/** * SkillKit — testing toolkit for skill authors and CI gates. * * Wraps the runtime `SkillsManager` + parser / validator with a * test-friendly surface: list, get, validate, snapshot, diff, and a * read-only activation-rank simulator. Same parse/validate codepath as * production — no shadow implementation to drift against. * * Constructor mirrors `SkillsConfig` minus the runtime fields * (`emit`, `lockfile`, `requires` caps) — those don't apply to a * synchronous test toolkit. The kit is intended to be re-instantiated * per test (or per CI run); state lives entirely on the underlying * `SkillsManager`. * * Public surface published under `@qodo/sdk/skills/testing`. Re-exports * also flow through the package's main entrypoint so `import { SkillKit } * from '@qodo/sdk'` resolves; the dedicated subpath stays stable for * authors writing tests without a runtime dependency. */ import { SkillsManager, type SkillGetOptions } from '../manager.js'; import type { ParsedSkill, SkillEmbedder, SkillSource } from '../types.js'; /** Construction config. Same shape as `SkillsConfig` minus the runtime-only fields. */ export interface SkillKitOptions { readonly sources?: readonly SkillSource[]; readonly trustedSources?: readonly string[]; readonly embedder?: SkillEmbedder; readonly sdkVersion?: string; } /** Output of `kit.validate()`. One entry per validation finding. */ export interface SkillKitValidationIssue { /** Skill FQN, or `null` for catalog-wide events (e.g. unreachable source). */ readonly fqn: string | null; /** Absolute path of the offending file, or `null` when not file-bound. */ readonly file: string | null; readonly severity: 'error' | 'warning' | 'info'; readonly message: string; } /** Output of `kit.snapshot(fqn)`. Stable shape suitable for `toMatchSnapshot`. */ export interface SkillKitSnapshot { readonly fqn: string; readonly vendor: string; readonly name: string; readonly version: string; readonly description?: string; readonly when_to_use?: string; readonly trustTier: ParsedSkill['trustTier']; readonly requires: readonly string[]; readonly allowedTools: readonly { readonly tool: string; readonly args?: string; }[]; readonly bodySha256: string; readonly files: readonly { readonly path: string; readonly sha256: string; }[]; } /** Output of `kit.testActivation(message)`. */ export interface SkillKitActivationCandidate { readonly fqn: string; readonly score: number; readonly source: 'embedding' | 'keyword'; } /** Diff result between two catalog versions of the same skill. */ export interface SkillKitDiff { readonly fqn: string; readonly status: 'unchanged' | 'description_changed' | 'body_changed' | 'references_changed' | 'removed' | 'added'; readonly details?: string; } export declare class SkillKit { private readonly manager; private readonly options; constructor(options?: SkillKitOptions); /** Underlying manager — escape hatch for tests that want the full surface. */ get internalManager(): SkillsManager; /** List every catalog entry. Latest-version-only by default. */ list(opts?: SkillGetOptions): Promise; /** Resolve a specifier to a fully parsed skill, or `null` if not in the catalog. */ get(specifier: string): Promise; /** * Run discovery and return every validation finding. Used in CI gates * that fail the build when a skill ships with a fatal frontmatter * issue. The same `sdk.skill.error` events the runtime would emit * are captured and converted to a structured array. */ validate(): Promise; /** * Compute a stable snapshot for `toMatchSnapshot`. Captures the * description, body hash, supporting-file index with per-file hashes, * and the most stability-relevant frontmatter fields. Designed for * `expect(snapshot).toMatchSnapshot()` (vitest / jest). */ snapshot(specifier: string): Promise; /** * Score the configured catalog against `message` so authors can write * activation-regression tests ("the user types this; the * `code-review` skill must rank in the top 3"). Two modes: * * - When an embedder is configured, ranks via cosine similarity * between the message embedding and each skill's description. * - Otherwise, ranks via overlapping keyword count (case-insensitive, * whitespace-tokenized) for cheap CI use. * * Returns the top-`limit` (default 10) candidates sorted by score * descending. No LLM call regardless of mode. */ testActivation(message: string, opts?: { readonly limit?: number; }): Promise; /** * Semantic diff between two skill snapshots. The same skill at two * different versions, or before-and-after of an edit. Useful for * "what would land if I bumped this skill?" CI surfaces. */ diff(specifier: string, otherKit: SkillKit): Promise; /** * Compute the lockfile content-hash of a skill directly. Surfaces the * shared `computeSkillHash` helper for authors writing pre-commit * checks that "the locked hash hasn't drifted". */ hash(specifier: string): Promise; /** * Return the consumer-supplied options so `validate()` can build a * second manager with the same sources but a custom event sink. The * `emit` field is intentionally not surfaced — `validate()` wires its * own sink to capture findings. */ private passthroughOptions; } //# sourceMappingURL=SkillKit.d.ts.map