diff --git a/packages/cli/src/commands/enable.ts b/packages/cli/src/commands/enable.ts index 96ea71d4..5f43ac2e 100644 --- a/packages/cli/src/commands/enable.ts +++ b/packages/cli/src/commands/enable.ts @@ -1,4 +1,4 @@ -import chalk from 'chalk'; +import { colors, warn, success, error } from '../onboarding/index.js'; import { Command, Option } from 'clipanion'; import { setSkillEnabled, findSkill } from '@skillkit/core'; import { getSearchDirs } from '../helpers.js'; @@ -18,36 +18,36 @@ export class EnableCommand extends Command { async execute(): Promise { const searchDirs = getSearchDirs(); - let success = 0; + let successCount = 0; let failed = 0; for (const skillName of this.skills) { const skill = findSkill(skillName, searchDirs); if (!skill) { - console.log(chalk.red(`Skill not found: ${skillName}`)); + error(`Skill not found: ${skillName}`); failed++; continue; } if (skill.enabled) { - console.log(chalk.dim(`Already enabled: ${skillName}`)); + console.log(colors.muted(`Already enabled: ${skillName}`)); continue; } const result = setSkillEnabled(skill.path, true); if (result) { - console.log(chalk.green(`Enabled: ${skillName}`)); - success++; + success(`Enabled: ${skillName}`); + successCount++; } else { - console.log(chalk.red(`Failed to enable: ${skillName}`)); + error(`Failed to enable: ${skillName}`); failed++; } } - if (success > 0) { - console.log(chalk.dim('\nRun `skillkit sync` to update your agent config')); + if (successCount > 0) { + console.log(colors.muted('\nRun `skillkit sync` to update your agent config')); } return failed > 0 ? 1 : 0; @@ -69,36 +69,36 @@ export class DisableCommand extends Command { async execute(): Promise { const searchDirs = getSearchDirs(); - let success = 0; + let successCount = 0; let failed = 0; for (const skillName of this.skills) { const skill = findSkill(skillName, searchDirs); if (!skill) { - console.log(chalk.red(`Skill not found: ${skillName}`)); + error(`Skill not found: ${skillName}`); failed++; continue; } if (!skill.enabled) { - console.log(chalk.dim(`Already disabled: ${skillName}`)); + console.log(colors.muted(`Already disabled: ${skillName}`)); continue; } const result = setSkillEnabled(skill.path, false); if (result) { - console.log(chalk.yellow(`Disabled: ${skillName}`)); - success++; + warn(`Disabled: ${skillName}`); + successCount++; } else { - console.log(chalk.red(`Failed to disable: ${skillName}`)); + error(`Failed to disable: ${skillName}`); failed++; } } - if (success > 0) { - console.log(chalk.dim('\nRun `skillkit sync` to update your agent config')); + if (successCount > 0) { + console.log(colors.muted('\nRun `skillkit sync` to update your agent config')); } return failed > 0 ? 1 : 0; diff --git a/packages/cli/src/commands/generate.ts b/packages/cli/src/commands/generate.ts index c0f72bb7..a3337dde 100644 --- a/packages/cli/src/commands/generate.ts +++ b/packages/cli/src/commands/generate.ts @@ -33,7 +33,7 @@ export class GenerateCommand extends Command { ['Interactive wizard', '$0 generate'], ['Use specific provider', '$0 generate --provider openai'], ['Compose from existing skills', '$0 generate --compose "testing patterns for vitest"'], - ['Target specific agents', '$0 generate --agents claude-code,cursor'], + ['Target specific agents', '$0 generate --agent claude-code,cursor'], ['Skip memory context', '$0 generate --no-memory'], ], }); @@ -50,7 +50,7 @@ export class GenerateCommand extends Command { description: 'Natural language search to find skills to compose', }); - agents = Option.String('--agents,-a', { + agents = Option.String('--agent,--agents,-a', { description: 'Target agents (comma-separated)', }); @@ -536,6 +536,9 @@ ${trustScore.warnings.length > 0 ? `\nWarnings:\n${trustScore.warnings.map((w) = let targetAgents: string[]; if (this.agents) { + if (process.argv.includes('--agents')) { + console.warn('Warning: --agents is deprecated, use --agent instead (--agents will be removed in v2.0)'); + } targetAgents = this.agents.split(',').map((a) => a.trim()); } else { const agentOptions = [ diff --git a/packages/cli/src/commands/list.ts b/packages/cli/src/commands/list.ts index 50a1005b..8d38d534 100644 --- a/packages/cli/src/commands/list.ts +++ b/packages/cli/src/commands/list.ts @@ -1,8 +1,7 @@ -import chalk from 'chalk'; import { Command, Option } from 'clipanion'; import { findAllSkills, evaluateSkillDirectory } from '@skillkit/core'; import { getSearchDirs } from '../helpers.js'; -import { formatQualityBadge, colors } from '../onboarding/index.js'; +import { formatQualityBadge, colors, warn } from '../onboarding/index.js'; export class ListCommand extends Command { static override paths = [['list'], ['ls'], ['l']]; @@ -65,18 +64,18 @@ export class ListCommand extends Command { } if (skills.length === 0) { - console.log(chalk.yellow('No skills installed')); - console.log(chalk.dim('Install skills with: skillkit install ')); + warn('No skills installed'); + console.log(colors.muted('Install skills with: skillkit install ')); return 0; } - console.log(chalk.cyan(`Installed skills (${skills.length}):\n`)); + console.log(colors.cyan(`Installed skills (${skills.length}):\n`)); const projectSkills = skillsWithQuality.filter(s => s.location === 'project'); const globalSkills = skillsWithQuality.filter(s => s.location === 'global'); if (projectSkills.length > 0) { - console.log(chalk.blue('Project skills:')); + console.log(colors.info('Project skills:')); for (const skill of projectSkills) { printSkill(skill, this.quality); } @@ -84,7 +83,7 @@ export class ListCommand extends Command { } if (globalSkills.length > 0) { - console.log(chalk.dim('Global skills:')); + console.log(colors.muted('Global skills:')); for (const skill of globalSkills) { printSkill(skill, this.quality); } @@ -95,7 +94,7 @@ export class ListCommand extends Command { const disabledCount = skills.length - enabledCount; console.log( - chalk.dim( + colors.muted( `${projectSkills.length} project, ${globalSkills.length} global` + (disabledCount > 0 ? `, ${disabledCount} disabled` : '') ) @@ -117,9 +116,9 @@ function printSkill( skill: { name: string; description: string; enabled: boolean; location: string; quality: number | null }, showQuality = false ) { - const status = skill.enabled ? chalk.green('✓') : chalk.red('○'); - const name = skill.enabled ? skill.name : chalk.dim(skill.name); - const desc = chalk.dim(truncate(skill.description, 50)); + const status = skill.enabled ? colors.success('✓') : colors.error('○'); + const name = skill.enabled ? skill.name : colors.muted(skill.name); + const desc = colors.muted(truncate(skill.description, 50)); const qualityBadge = showQuality && skill.quality !== null ? ` ${formatQualityBadge(skill.quality)}` : ''; console.log(` ${status} ${name}${qualityBadge}`); diff --git a/packages/cli/src/commands/manifest.ts b/packages/cli/src/commands/manifest.ts index 89083fbf..5d9ba071 100644 --- a/packages/cli/src/commands/manifest.ts +++ b/packages/cli/src/commands/manifest.ts @@ -147,7 +147,7 @@ export class ManifestAddCommand extends Command { description: 'Specific skills to include (comma-separated)', }); - agents = Option.String('--agents,-a', { + agents = Option.String('--agent,--agents,-a', { description: 'Target agents (comma-separated)', }); @@ -159,6 +159,9 @@ export class ManifestAddCommand extends Command { } if (this.agents) { + if (process.argv.includes('--agents')) { + console.warn('Warning: --agents is deprecated, use --agent instead (--agents will be removed in v2.0)'); + } options.agents = this.agents.split(',').map(s => s.trim()); } diff --git a/packages/cli/src/commands/remove.ts b/packages/cli/src/commands/remove.ts index db18cc89..1363e040 100644 --- a/packages/cli/src/commands/remove.ts +++ b/packages/cli/src/commands/remove.ts @@ -1,6 +1,6 @@ import { existsSync, rmSync, readFileSync, writeFileSync } from 'node:fs'; import { join } from 'node:path'; -import chalk from 'chalk'; +import { colors, warn, success, error } from '../onboarding/index.js'; import { Command, Option } from 'clipanion'; import { findSkill, AgentsMdParser, AgentsMdGenerator } from '@skillkit/core'; import { getSearchDirs } from '../helpers.js'; @@ -32,22 +32,22 @@ export class RemoveCommand extends Command { const skill = findSkill(skillName, searchDirs); if (!skill) { - console.log(chalk.yellow(`Skill not found: ${skillName}`)); + warn(`Skill not found: ${skillName}`); continue; } if (!existsSync(skill.path)) { - console.log(chalk.yellow(`Path not found: ${skill.path}`)); + warn(`Path not found: ${skill.path}`); continue; } try { rmSync(skill.path, { recursive: true, force: true }); - console.log(chalk.green(`Removed: ${skillName}`)); + success(`Removed: ${skillName}`); removed++; - } catch (error) { - console.log(chalk.red(`Failed to remove: ${skillName}`)); - console.error(chalk.dim(error instanceof Error ? error.message : String(error))); + } catch (err) { + error(`Failed to remove: ${skillName}`); + console.error(colors.muted(err instanceof Error ? err.message : String(err))); failed++; } } @@ -65,11 +65,11 @@ export class RemoveCommand extends Command { writeFileSync(agentsMdPath, updated, 'utf-8'); } } - } catch (error) { - console.log(chalk.yellow('Warning: Failed to update AGENTS.md')); - console.error(chalk.dim(error instanceof Error ? error.message : String(error))); + } catch (err) { + warn('Warning: Failed to update AGENTS.md'); + console.error(colors.muted(err instanceof Error ? err.message : String(err))); } - console.log(chalk.dim('\nRun `skillkit sync` to update your agent config')); + console.log(colors.muted('\nRun `skillkit sync` to update your agent config')); } return failed > 0 ? 1 : 0; diff --git a/packages/cli/src/commands/scan.ts b/packages/cli/src/commands/scan.ts index d79b73dc..a3b61187 100644 --- a/packages/cli/src/commands/scan.ts +++ b/packages/cli/src/commands/scan.ts @@ -2,6 +2,7 @@ import { Command, Option } from 'clipanion'; import { resolve } from 'node:path'; import { existsSync } from 'node:fs'; import { SkillScanner, formatResult, Severity } from '@skillkit/core'; +import { error } from '../onboarding/index.js'; const SEVERITY_MAP: Record = { critical: Severity.CRITICAL, @@ -50,13 +51,13 @@ export class ScanCommand extends Command { const targetPath = resolve(this.skillPath); if (!existsSync(targetPath)) { - this.context.stderr.write(`Path not found: ${targetPath}\n`); + error(`Path not found: ${targetPath}`); return 1; } const validFormats = ['summary', 'json', 'table', 'sarif']; if (!validFormats.includes(this.format)) { - this.context.stderr.write(`Invalid format: "${this.format}". Must be one of: ${validFormats.join(', ')}\n`); + error(`Invalid format: "${this.format}". Must be one of: ${validFormats.join(', ')}`); return 1; } @@ -66,7 +67,7 @@ export class ScanCommand extends Command { if (this.failOn) { failOnSeverity = SEVERITY_MAP[this.failOn.toLowerCase()]; if (!failOnSeverity) { - this.context.stderr.write(`Invalid --fail-on value: "${this.failOn}". Must be one of: ${Object.keys(SEVERITY_MAP).join(', ')}\n`); + error(`Invalid --fail-on value: "${this.failOn}". Must be one of: ${Object.keys(SEVERITY_MAP).join(', ')}`); return 1; } } diff --git a/packages/cli/src/commands/translate.ts b/packages/cli/src/commands/translate.ts index f26ee9c6..730d942c 100644 --- a/packages/cli/src/commands/translate.ts +++ b/packages/cli/src/commands/translate.ts @@ -1,7 +1,7 @@ import { Command, Option } from 'clipanion'; import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs'; import { join, basename, dirname } from 'node:path'; -import chalk from 'chalk'; +import { colors, warn, success, error } from '../onboarding/index.js'; import { type AgentType, translateSkill, @@ -102,15 +102,15 @@ export class TranslateCommand extends Command { // Validate target agent if (!this.to) { - console.error(chalk.red('Error: --to/-t target agent is required')); - console.log(chalk.gray('Use --list to see all supported agents')); + error('--to/-t target agent is required'); + console.log(colors.muted('Use --list to see all supported agents')); return 1; } const targetAgent = this.to as AgentType; if (!getSupportedTranslationAgents().includes(targetAgent)) { - console.error(chalk.red(`Error: Unknown target agent "${this.to}"`)); - console.log(chalk.gray('Use --list to see all supported agents')); + error(`Unknown target agent "${this.to}"`); + console.log(colors.muted('Use --list to see all supported agents')); return 1; } @@ -121,7 +121,7 @@ export class TranslateCommand extends Command { // Translate single skill if (!this.source) { - console.error(chalk.red('Error: Please specify a skill name or path, or use --all')); + error('Please specify a skill name or path, or use --all'); return 1; } @@ -132,7 +132,7 @@ export class TranslateCommand extends Command { * List all supported agents and their formats */ private listAgents(): number { - console.log(chalk.bold('\nSupported Agents for Translation:\n')); + console.log(colors.bold('\nSupported Agents for Translation:\n')); const agents = getSupportedTranslationAgents(); const adapters = getAllAdapters(); @@ -154,17 +154,17 @@ export class TranslateCommand extends Command { }; for (const [format, formatAgents] of Object.entries(byFormat)) { - console.log(chalk.cyan(` ${formatNames[format] || format}:`)); + console.log(colors.cyan(` ${formatNames[format] || format}:`)); for (const agent of formatAgents) { const adapter = adapters.find(a => a.type === agent); const name = adapter?.name || agent; - console.log(` ${chalk.green(agent.padEnd(16))} ${chalk.gray(name)}`); + console.log(` ${colors.success(agent.padEnd(16))} ${colors.muted(name)}`); } console.log(); } - console.log(chalk.gray('All formats can translate to any other format.')); - console.log(chalk.gray('Use --compat to see compatibility details.\n')); + console.log(colors.muted('All formats can translate to any other format.')); + console.log(colors.muted('Use --compat to see compatibility details.\n')); return 0; } @@ -174,7 +174,7 @@ export class TranslateCommand extends Command { */ private showCompatibility(): number { if (!this.from || !this.to) { - console.error(chalk.red('Error: Both --from and --to are required for compatibility check')); + error('Both --from and --to are required for compatibility check'); return 1; } @@ -183,26 +183,26 @@ export class TranslateCommand extends Command { const info = translatorRegistry.getCompatibilityInfo(fromAgent, toAgent); - console.log(chalk.bold(`\nTranslation: ${fromAgent} → ${toAgent}\n`)); + console.log(colors.bold(`\nTranslation: ${fromAgent} → ${toAgent}\n`)); if (info.supported) { - console.log(chalk.green(' ✓ Translation supported')); + console.log(colors.success(' ✓ Translation supported')); } else { - console.log(chalk.red(' ✗ Translation not supported')); + console.log(colors.error(' ✗ Translation not supported')); return 1; } if (info.warnings.length > 0) { - console.log(chalk.yellow('\n Warnings:')); + warn('\n Warnings:'); for (const warning of info.warnings) { - console.log(chalk.yellow(` • ${warning}`)); + console.log(colors.warning(` • ${warning}`)); } } if (info.lossyFields.length > 0) { - console.log(chalk.gray('\n Fields with reduced functionality:')); + console.log(colors.muted('\n Fields with reduced functionality:')); for (const field of info.lossyFields) { - console.log(chalk.gray(` • ${field}`)); + console.log(colors.muted(` • ${field}`)); } } @@ -218,19 +218,19 @@ export class TranslateCommand extends Command { const skills = findAllSkills(searchDirs); if (skills.length === 0) { - console.log(chalk.yellow('No skills found to translate')); + warn('No skills found to translate'); return 0; } - console.log(chalk.bold(`\nTranslating ${skills.length} skill(s) to ${targetAgent}...\n`)); + console.log(colors.bold(`\nTranslating ${skills.length} skill(s) to ${targetAgent}...\n`)); - let success = 0; + let successCount = 0; let failed = 0; for (const skill of skills) { const skillMdPath = join(skill.path, 'SKILL.md'); if (!existsSync(skillMdPath)) { - console.log(chalk.yellow(` ⚠ ${skill.name}: No SKILL.md found`)); + warn(` ⚠ ${skill.name}: No SKILL.md found`); failed++; continue; } @@ -241,10 +241,10 @@ export class TranslateCommand extends Command { if (result.success) { if (this.dryRun) { - console.log(chalk.green(` ✓ ${skill.name} → ${result.filename} (dry run)`)); + success(` ✓ ${skill.name} → ${result.filename} (dry run)`); if (result.warnings.length > 0) { for (const warning of result.warnings) { - console.log(chalk.gray(` ${warning}`)); + console.log(colors.muted(` ${warning}`)); } } } else { @@ -259,33 +259,33 @@ export class TranslateCommand extends Command { const outputPath = join(outputDir, result.filename); if (existsSync(outputPath) && !this.force) { - console.log(chalk.yellow(` ⚠ ${skill.name}: ${outputPath} exists (use --force)`)); + warn(` ⚠ ${skill.name}: ${outputPath} exists (use --force)`); failed++; continue; } writeFileSync(outputPath, result.content, 'utf-8'); - console.log(chalk.green(` ✓ ${skill.name} → ${outputPath}`)); + success(` ✓ ${skill.name} → ${outputPath}`); } if (result.incompatible.length > 0) { for (const item of result.incompatible) { - console.log(chalk.gray(` ⚠ ${item}`)); + console.log(colors.muted(` ⚠ ${item}`)); } } - success++; + successCount++; } else { - console.log(chalk.red(` ✗ ${skill.name}: Translation failed`)); + console.log(colors.error(` ✗ ${skill.name}: Translation failed`)); for (const item of result.incompatible) { - console.log(chalk.red(` ${item}`)); + console.log(colors.error(` ${item}`)); } failed++; } } console.log(); - console.log(chalk.bold(`Translated: ${success}, Failed: ${failed}`)); + console.log(colors.bold(`Translated: ${successCount}, Failed: ${failed}`)); return failed > 0 ? 1 : 0; } @@ -322,10 +322,10 @@ export class TranslateCommand extends Command { } if (!found) { - console.error(chalk.red(`Error: Skill "${source}" not found`)); - console.log(chalk.gray('Searched in:')); + error(`Skill "${source}" not found`); + console.log(colors.muted('Searched in:')); for (const dir of searchDirs) { - console.log(chalk.gray(` ${dir}`)); + console.log(colors.muted(` ${dir}`)); } return 1; } @@ -339,35 +339,35 @@ export class TranslateCommand extends Command { }); if (!result.success) { - console.error(chalk.red('Translation failed:')); + error('Translation failed:'); for (const item of result.incompatible) { - console.error(chalk.red(` ${item}`)); + console.log(colors.muted(` ${item}`)); } return 1; } // Show warnings if (result.warnings.length > 0) { - console.log(chalk.yellow('\nWarnings:')); + warn('\nWarnings:'); for (const warning of result.warnings) { - console.log(chalk.yellow(` • ${warning}`)); + console.log(colors.warning(` • ${warning}`)); } } // Show incompatible features if (result.incompatible.length > 0) { - console.log(chalk.gray('\nIncompatible features:')); + console.log(colors.muted('\nIncompatible features:')); for (const item of result.incompatible) { - console.log(chalk.gray(` • ${item}`)); + console.log(colors.muted(` • ${item}`)); } } // Dry run - just show preview if (this.dryRun) { - console.log(chalk.bold(`\nTranslated content (${result.filename}):\n`)); - console.log(chalk.gray('─'.repeat(60))); + console.log(colors.bold(`\nTranslated content (${result.filename}):\n`)); + console.log(colors.muted('─'.repeat(60))); console.log(result.content); - console.log(chalk.gray('─'.repeat(60))); + console.log(colors.muted('─'.repeat(60))); return 0; } @@ -388,8 +388,8 @@ export class TranslateCommand extends Command { // Check for existing file if (existsSync(outputPath) && !this.force) { - console.error(chalk.red(`Error: ${outputPath} already exists`)); - console.log(chalk.gray('Use --force to overwrite')); + error(`${outputPath} already exists`); + console.log(colors.muted('Use --force to overwrite')); return 1; } @@ -401,9 +401,9 @@ export class TranslateCommand extends Command { writeFileSync(outputPath, result.content, 'utf-8'); - console.log(chalk.green(`\n✓ Translated to ${outputPath}`)); - console.log(chalk.gray(` Format: ${result.targetFormat}`)); - console.log(chalk.gray(` Agent: ${result.targetAgent}`)); + success(`\n✓ Translated to ${outputPath}`); + console.log(colors.muted(` Format: ${result.targetFormat}`)); + console.log(colors.muted(` Agent: ${result.targetAgent}`)); return 0; } diff --git a/packages/cli/src/commands/update.ts b/packages/cli/src/commands/update.ts index 50c18e71..da096114 100644 --- a/packages/cli/src/commands/update.ts +++ b/packages/cli/src/commands/update.ts @@ -1,10 +1,9 @@ import { existsSync, rmSync, cpSync } from 'node:fs'; import { join } from 'node:path'; -import chalk from 'chalk'; -import ora from 'ora'; import { Command, Option } from 'clipanion'; import { findAllSkills, findSkill, detectProvider, isLocalPath } from '@skillkit/core'; import { getSearchDirs, loadSkillMetadata, saveSkillMetadata } from '../helpers.js'; +import { colors, spinner, warn, step } from '../onboarding/index.js'; export class UpdateCommand extends Command { static override paths = [['update'], ['u']]; @@ -25,7 +24,7 @@ export class UpdateCommand extends Command { }); async execute(): Promise { - const spinner = ora(); + const s = spinner(); const searchDirs = getSearchDirs(); let skillsToUpdate; @@ -37,18 +36,18 @@ export class UpdateCommand extends Command { const notFound = this.skills.filter(name => !findSkill(name, searchDirs)); if (notFound.length > 0) { - console.log(chalk.yellow(`Skills not found: ${notFound.join(', ')}`)); + warn(`Skills not found: ${notFound.join(', ')}`); } } else { skillsToUpdate = findAllSkills(searchDirs); } if (skillsToUpdate.length === 0) { - console.log(chalk.yellow('No skills to update')); + warn('No skills to update'); return 0; } - console.log(chalk.cyan(`Updating ${skillsToUpdate.length} skill(s)...\n`)); + step(`Updating ${skillsToUpdate.length} skill(s)...`); let updated = 0; let skipped = 0; @@ -58,12 +57,12 @@ export class UpdateCommand extends Command { const metadata = loadSkillMetadata(skill.path); if (!metadata) { - console.log(chalk.dim(`Skipping ${skill.name} (no metadata, reinstall needed)`)); + console.log(colors.muted(`Skipping ${skill.name} (no metadata, reinstall needed)`)); skipped++; continue; } - spinner.start(`Updating ${skill.name}...`); + s.start(`Updating ${skill.name}...`); try { if (isLocalPath(metadata.source)) { @@ -72,14 +71,14 @@ export class UpdateCommand extends Command { : metadata.source; if (!existsSync(localPath)) { - spinner.warn(chalk.yellow(`${skill.name}: local source missing`)); + s.stop(colors.warning(`${skill.name}: local source missing`)); skipped++; continue; } const skillMdPath = join(localPath, 'SKILL.md'); if (!existsSync(skillMdPath)) { - spinner.warn(chalk.yellow(`${skill.name}: no SKILL.md at source`)); + s.stop(colors.warning(`${skill.name}: no SKILL.md at source`)); skipped++; continue; } @@ -90,13 +89,13 @@ export class UpdateCommand extends Command { metadata.updatedAt = new Date().toISOString(); saveSkillMetadata(skill.path, metadata); - spinner.succeed(chalk.green(`Updated ${skill.name}`)); + s.stop(`Updated ${skill.name}`); updated++; } else { const provider = detectProvider(metadata.source); if (!provider) { - spinner.warn(chalk.yellow(`${skill.name}: unknown provider`)); + s.stop(colors.warning(`${skill.name}: unknown provider`)); skipped++; continue; } @@ -104,7 +103,7 @@ export class UpdateCommand extends Command { const result = await provider.clone(metadata.source, '', { depth: 1 }); if (!result.success || !result.path) { - spinner.fail(chalk.red(`${skill.name}: ${result.error || 'clone failed'}`)); + s.stop(colors.error(`${skill.name}: ${result.error || 'clone failed'}`)); failed++; continue; } @@ -115,7 +114,7 @@ export class UpdateCommand extends Command { const skillMdPath = join(sourcePath, 'SKILL.md'); if (!existsSync(skillMdPath)) { - spinner.warn(chalk.yellow(`${skill.name}: no SKILL.md in source`)); + s.stop(colors.warning(`${skill.name}: no SKILL.md in source`)); rmSync(result.path, { recursive: true, force: true }); skipped++; continue; @@ -129,22 +128,18 @@ export class UpdateCommand extends Command { metadata.updatedAt = new Date().toISOString(); saveSkillMetadata(skill.path, metadata); - spinner.succeed(chalk.green(`Updated ${skill.name}`)); + s.stop(`Updated ${skill.name}`); updated++; } - } catch (error) { - spinner.fail(chalk.red(`Failed to update ${skill.name}`)); - console.error(chalk.dim(error instanceof Error ? error.message : String(error))); + } catch (err) { + s.stop(colors.error(`Failed to update ${skill.name}`)); + console.log(colors.muted(err instanceof Error ? err.message : String(err))); failed++; } } console.log(); - console.log( - chalk.cyan( - `Updated: ${updated}, Skipped: ${skipped}, Failed: ${failed}` - ) - ); + step(`Updated: ${updated}, Skipped: ${skipped}, Failed: ${failed}`); return failed > 0 ? 1 : 0; }