import { Command } from "commander"; import chalk from "chalk"; import ora from "ora"; import { readManifest, addToManifest } from "../lib/manifest.js"; import { installSkill } from "./install.js"; export const restoreCommand = new Command("restore") .description("Install all skills from .skills.json manifest") .option("--dry-run", "Show what would be installed without installing") .action(async (options) => { const manifest = readManifest(); const slugs = Object.keys(manifest.skills); if (slugs.length === 0) { console.log(chalk.yellow("No .skills.json found or no skills listed.")); return; } if (options.dryRun) { console.log(chalk.bold(`Skills in .skills.json (${slugs.length}):\n`)); for (const slug of slugs) { const entry = manifest.skills[slug]; console.log( ` ${chalk.cyan(slug)} v${entry.version} (${entry.platform || "claude-code"})`, ); } return; } const spinner = ora( `Restoring ${slugs.length} skill(s) from .skills.json...`, ).start(); let installed = 0; let failed = 0; for (const slug of slugs) { const entry = manifest.skills[slug]; spinner.text = `[${installed + failed + 1}/${slugs.length}] Installing ${slug} v${entry.version}...`; try { const result = await installSkill(slug, { version: entry.version, target: entry.platform || "claude-code", }); addToManifest(slug, result.version, entry.platform || "claude-code"); installed++; } catch (err) { spinner.warn( chalk.yellow( ` ${slug}: ${err instanceof Error ? err.message : "failed"}`, ), ); spinner.start(); failed++; } } if (failed > 0) { spinner.warn( `Restored ${installed}/${slugs.length} skills (${failed} failed)`, ); process.exitCode = 1; } else { spinner.succeed(`All ${installed} skill(s) restored from .skills.json`); } });