UNPKG

@ace-sdk/cli

Version:

ACE CLI - Command-line tool for intelligent pattern learning and playbook management

113 lines 5.65 kB
/** * Playbook status command */ import { globalOptions } from '../cli.js'; import { createContext } from '../types/config.js'; import { ACEServerClient } from '../services/server-client.js'; import { Logger } from '../services/logger.js'; import chalk from 'chalk'; import { isSubscriptionError, QuotaExceededError, PaymentRequiredError, AccountBlockedError } from '@ace-sdk/core'; import { displayUsageStatus, formatUsageJson } from '../utils/usage-display.js'; /** * Show playbook statistics */ export async function statusCommand() { const logger = new Logger(globalOptions); let spinner = logger.spinner('Fetching playbook status...'); try { // Create context using 4-tier precedence (flags > env > .claude/settings.json > error) const context = await createContext({ org: globalOptions.org, project: globalOptions.project }); const client = new ACEServerClient(context, logger); const status = await client.getAnalytics(); spinner?.succeed('Status retrieved'); // Get subscription usage from response headers (v2.8.0+) const usage = client.getLastUsage(); if (logger.isJson()) { // Include both playbook stats and subscription usage in JSON output const output = { playbook: status, subscription: usage ? formatUsageJson(usage) : null }; logger.output(output); } else { // Show subscription usage first (if available) if (usage) { displayUsageStatus(usage); } logger.info(chalk.bold('📊 Playbook Status\n')); // Handle both total_patterns (new) and total_bullets (legacy) const totalCount = status.total_patterns ?? status.total_bullets ?? 0; logger.info(` ${chalk.cyan('Total Patterns:')} ${totalCount}`); logger.info(` ${chalk.cyan('Project ID:')} ${context.projectId}`); if (status.by_section) { logger.info(chalk.bold('\n📑 By Section:\n')); Object.entries(status.by_section).forEach(([section, count]) => { const label = section.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()); logger.info(` ${chalk.dim('•')} ${label}: ${count}`); }); } if (status.top_helpful && status.top_helpful.length > 0) { logger.info(chalk.bold('\n⭐ Top Helpful Patterns:\n')); status.top_helpful.slice(0, 5).forEach((bullet, index) => { logger.info(` ${chalk.green(index + 1)}. ${chalk.bold(`[+${bullet.helpful}]`)} ${bullet.content.substring(0, 60)}...`); }); } if (status.top_harmful && status.top_harmful.length > 0) { logger.info(chalk.bold('\n⚠️ Top Harmful Patterns:\n')); status.top_harmful.slice(0, 3).forEach((bullet, index) => { logger.info(` ${chalk.red(index + 1)}. ${chalk.bold(`[-${bullet.harmful}]`)} ${bullet.content.substring(0, 60)}...`); }); } logger.info(''); } } catch (error) { spinner?.fail('Failed to fetch status'); // Handle subscription-related errors with helpful messages (v2.8.0+) if (isSubscriptionError(error)) { if (logger.isJson()) { logger.error(JSON.stringify({ error: error.name, message: error.message, upgrade_url: 'upgradeUrl' in error ? error.upgradeUrl : 'https://ace-ai.app/pricing' })); } else { if (error instanceof QuotaExceededError) { logger.error(chalk.yellow(`\n⚠️ Quota exceeded: ${error.message}`)); logger.error(chalk.dim(` ${error.resource}: ${error.current.toLocaleString()} / ${error.limit.toLocaleString()} (${error.percentage}%)`)); logger.error(chalk.cyan(` Upgrade: ${error.upgradeUrl}\n`)); } else if (error instanceof PaymentRequiredError) { logger.error(chalk.yellow(`\n⚠️ Account is in read-only mode`)); logger.error(chalk.dim(` ${error.message}`)); if (error.isUrgent) { logger.error(chalk.red(` ⚠️ URGENT: Account will be blocked in ${error.daysUntilBlock} days!`)); } else { logger.error(chalk.dim(` Days until block: ${error.daysUntilBlock}`)); } logger.error(chalk.cyan(` Update payment: ${error.upgradeUrl}\n`)); } else if (error instanceof AccountBlockedError) { logger.error(chalk.red(`\n🚫 Account is blocked`)); logger.error(chalk.dim(` ${error.message}`)); logger.error(chalk.cyan(` Resolve at: ${error.upgradeUrl}\n`)); } else { logger.error(chalk.red(`\n❌ ${error.message}\n`)); } } process.exit(1); } if (logger.isJson()) { logger.error(JSON.stringify({ error: error instanceof Error ? error.message : String(error) })); } else { logger.error(chalk.red(`\n❌ Error: ${error instanceof Error ? error.message : String(error)}\n`)); } process.exit(1); } } //# sourceMappingURL=status.js.map