# Task ID: 100 **Title:** Implement mcpctl cache list Command **Status:** done **Dependencies:** 98 ✓ **Priority:** low **Description:** Add CLI command to list cached proxymodel artifacts with size and age information. **Details:** Create `src/cli/src/commands/cache-list.ts`: ```typescript import { Command } from 'commander'; import { readdir, stat } from 'fs/promises'; import { join } from 'path'; import Table from 'cli-table3'; const CACHE_DIR = join(process.env.HOME ?? '', '.mcpctl', 'cache', 'proxymodel'); export function registerCacheList(program: Command): void { program .command('cache list') .description('List cached proxymodel artifacts') .option('--project ', 'Filter by project') .action(async (opts) => { try { const files = await readdir(CACHE_DIR); const table = new Table({ head: ['KEY', 'SIZE', 'AGE'], }); let totalSize = 0; for (const file of files) { const filePath = join(CACHE_DIR, file); const stats = await stat(filePath); const age = formatAge(Date.now() - stats.mtimeMs); const size = formatSize(stats.size); totalSize += stats.size; if (opts.project && !file.includes(opts.project)) continue; table.push([file, size, age]); } console.log(table.toString()); console.log(`Total: ${formatSize(totalSize)}`); } catch { console.log('No cache entries found'); } }); } function formatSize(bytes: number): string { if (bytes < 1024) return `${bytes}B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`; return `${(bytes / 1024 / 1024).toFixed(1)}MB`; } function formatAge(ms: number): string { const mins = Math.floor(ms / 60000); if (mins < 60) return `${mins}m`; const hours = Math.floor(mins / 60); if (hours < 24) return `${hours}h`; return `${Math.floor(hours / 24)}d`; } ``` **Test Strategy:** CLI test: list shows cache entries with correct format, --project filter works, empty cache shows appropriate message, size/age formatting is correct.