/** * @fileoverview Helper functions for SkillInstallationService * @module @skillsmith/core/services/skill-installation.helpers * @see SMI-3483: Wave 0 — Extract SkillInstallationService into core * * Pure helper functions used by the service. Split from the main service * file to meet the 500-line standard. */ import type { SkillDependencyRepository } from '../repositories/SkillDependencyRepository.js'; import type { Database } from '../db/database-interface.js'; import type { RiskScoreHistoryRepository } from '../repositories/RiskScoreHistoryRepository.js'; import type { ScanReport } from '../security/index.js'; import type { DepIntelResult, OptimizationInfo } from './skill-installation.types.js'; export { fetchFromGitHub } from './skill-installation.io.js'; import { type ClientId } from '../install/paths.js'; /** Result of applying optimization to a skill's content. */ export interface OptimizationResult { finalSkillContent: string; subSkillFiles: Array<{ filename: string; content: string; }>; subagentContent: string | undefined; claudeMdSnippet: string | undefined; optimizationInfo: OptimizationInfo; } export declare function hashContent(content: string): string; /** * SMI-5894 (Wave 1 Step 5): `client`/`skillsDir` default to the canonical * (Claude Code) client so every existing caller that doesn't pass them * (tests, and anywhere the service is constructed without `client`) keeps * seeing exactly the previous "Claude Code" / `~/.claude/skills/` wording — * only a caller that actually resolved a non-canonical client sees the tips * name that client and its real install path. */ export declare function generateTips(skillName: string, optimizationInfo: OptimizationInfo, client?: ClientId, skillsDir?: string): string[]; /** * Read the MCP server names registered in the consuming project's * `.mcp.json` (SMI-5676). Used to cross-check `extractMcpReferences` * candidates against what's *actually* configured, so a stale/renamed * reference (e.g. `claude-flow` after this project's own rename to `ruflo`) * gets tagged `unregistered` in `serverResolutions` instead of silently * asserted as a real dependency — without ever dropping a candidate that * simply isn't installed *yet*. * * Fails open: returns `undefined` (not `[]`) when `.mcp.json` is missing, * unreadable, or unparseable — `extractMcpReferences` treats `undefined` as * "no information available" (`serverResolutions` = `'unknown'`), whereas * `[]` would mean "zero servers registered", incorrectly tagging every real * candidate `unregistered`. * * @param projectRoot - Directory to look for `.mcp.json` in (defaults to * `process.cwd()`, matching the convention used elsewhere in the codebase * for locating a consuming project's config, e.g. * `packages/mcp-server/src/context/project-detector.ts`). */ export declare function getRegisteredMcpServers(projectRoot?: string): string[] | undefined; export declare function extractDepIntel(skillMdContent: string): DepIntelResult; /** * Extract + persist dependency intelligence for a skill. * * @returns The number of dependency rows written (inserted or upserted) this * call — i.e. `merged.length`. Because `SkillDependencyRepository.setDependencies` * upserts on (skill_id, dep_type, dep_target, dep_source), calling this * repeatedly with the same skillId/content is idempotent: the count * reflects the size of the currently-extracted dependency set on every * call, not a cumulative "newly inserted since last call" delta. Callers * that need a per-run backfill count (SMI-5645) can rely on this return * value directly. */ export declare function persistDependencies(repo: SkillDependencyRepository, skillId: string, content: string, declared: DepIntelResult['dep_declared']): number; /** * SMI-5894 (Wave 1 Step 3): compute the `~/.skillsmith/manifest.json` * `installedSkills` key for a given skill name + client. * * Canonical-client (`claude-code`) entries keep the legacy bare-name key — * every manifest reader written before multi-client installs existed * (`pin.ts`, `diff.ts`, MCP's `install.conflict.ts`, MCP's `uninstall_skill` * `listInstalledSkills()`, none of which are in this wave's scope) indexes * `installedSkills[name]` directly and must keep working unmodified for the * single-client-install case, which remains the overwhelming majority. * Only non-canonical clients get the composite `name::client` key, since * those are the ONLY entries that could previously silently collide with * (overwrite) a same-named install recorded under a different client — * exactly the bug this function exists to close. See the plan doc * (docs/internal/implementation/cursor-integration-readiness-cli-mcp-parity.md, * Wave 1 Step 3) for the full rationale and the deliberately additive, * backward-compatible shape of this fix. */ export declare function manifestKeyFor(name: string, client: ClientId): string; export { performUninstall } from './skill-installation.uninstall.js'; /** * Apply skill optimization via TransformationService. * Returns original content if transformation fails or produces no changes. * * @param client - SMI-6276: target client for the generated companion-agent * frontmatter shape (default: canonical / `claude-code`, preserving prior * behavior for every existing caller). See * `SubagentGenerator.client-profiles.ts`. */ export declare function applyOptimization(db: Database, skillId: string, skillName: string, skillMdContent: string, client?: ClientId): Promise; export declare function sanitizeInstallError(error: unknown): string; /** Compute quality score (0-1) from scan report and skill metadata. */ export declare function computeAndAttachQualityScore(params: { scanReport: ScanReport | undefined; description: string | null; tagCount: number; hasRepoUrl: boolean; hasAuthor: boolean; trustTier: string; hasExamples: boolean; }): number; /** Record a risk score snapshot. Best-effort: swallows errors. */ export declare function recordRiskHistory(params: { historyRepo: RiskScoreHistoryRepository | undefined; skillId: string; scanReport: ScanReport; contentHash: string | null; source: 'install' | 'indexer' | 'rescan'; }): void; //# sourceMappingURL=skill-installation.helpers.d.ts.map