import { existsSync, readFileSync } from "fs"; import { resolve } from "path"; import chalk from "chalk"; import { validateSkillContent } from "../lib/validate-skill.js"; /** * preview — shows how this skill will appear on the marketplace listing. * Operates entirely locally against the skill.md on disk. */ export async function previewCommand(filePath: string): Promise { const absPath = resolve(filePath); if (!existsSync(absPath)) { console.error(chalk.red(`Error: File not found: ${absPath}`)); process.exit(1); } const content = readFileSync(absPath, "utf-8"); const validation = validateSkillContent(content); if (!validation.valid) { for (const e of validation.errors) { console.log(chalk.red(`✗ ${e}`)); } console.log(chalk.red("\nValidation failed — cannot render preview.")); process.exit(1); } const fm = validation.frontmatter!; const body = validation.body ?? ""; const preview = body.slice(0, 500); const truncated = body.length > 500; const priceDisplay = fm.price === 0 ? chalk.green("Free") : chalk.yellow(`$${(fm.price / 100).toFixed(2)}`); console.log(chalk.bold("\n══════════════════════════════════════════════════")); console.log(chalk.bold(` Marketplace Preview: ${chalk.cyan(fm.name)}`)); console.log(chalk.bold("══════════════════════════════════════════════════\n")); console.log(` ${chalk.bold("Name:")} ${fm.name}`); console.log(` ${chalk.bold("Version:")} ${fm.version}`); console.log(` ${chalk.bold("Author:")} ${fm.author}`); console.log(` ${chalk.bold("Price:")} ${priceDisplay}`); console.log(` ${chalk.bold("License:")} ${fm.license ?? "(not specified)"}`); console.log(` ${chalk.bold("Model tier:")} ${fm.model_tier}`); if (fm.tags?.length) { console.log(` ${chalk.bold("Tags:")} ${fm.tags.map((t) => chalk.dim(`#${t}`)).join(" ")}`); } if (fm.required_secrets?.length) { console.log(` ${chalk.bold("Needs:")} ${fm.required_secrets.join(", ")}`); } if (fm.references?.length) { console.log(` ${chalk.bold("References:")} ${fm.references.length} skill(s)`); } console.log(); console.log(chalk.bold(" Description:")); console.log(` ${fm.description}`); console.log(); console.log(chalk.bold(" Content preview (first 500 chars):")); console.log(chalk.dim(" ─────────────────────────────────────────────────")); const indented = preview .split("\n") .map((l) => " " + l) .join("\n"); console.log(indented); if (truncated) { console.log(chalk.dim(" … (truncated) …")); } console.log(chalk.dim(" ─────────────────────────────────────────────────")); console.log(); for (const w of validation.warnings) { console.log(chalk.yellow(`⚠ ${w}`)); } }