Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Configure cli-progress with custom formatters, multi-bar support, and ETA calculations for CLI progress indication.
.claude/skills/a5c-ai-cli-progress-bar-setup/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flash | 100% | 4 |
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 8% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 9% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 32% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 8% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 152% | 0% |
Configure cli-progress for advanced progress indication.
Invoke this skill when you need to:
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | language | string | Yes | Target language | | format | string | No | Bar format template | | presets | array | No | Progress bar presets |
typescriptimport cliProgress, { SingleBar, MultiBar, Presets } from 'cli-progress'; import chalk from 'chalk'; // Custom format with colors const defaultFormat = chalk.cyan('{bar}') + ' {percentage}% | ETA: {eta}s | {value}/{total} | {filename}'; // Create single progress bar export function createProgressBar(options?: { format?: string; barSize?: number; }): SingleBar { return new SingleBar({ format: options?.format || defaultFormat, barCompleteChar: '\u2588', barIncompleteChar: '\u2591', barsize: options?.barSize || 40, hideCursor: true, clearOnComplete: false, stopOnComplete: true, }, Presets.shades_classic); } // Multi-bar for parallel tasks export function createMultiBar(): MultiBar { return new MultiBar({ format: '{name} |' + chalk.cyan('{bar}') + '| {percentage}% | {value}/{total}', barCompleteChar: '\u2588', barIncompleteChar: '\u2591', hideCursor: true, clearOnComplete: false, stopOnComplete: false, }, Presets.shades_grey); } // Download progress with speed export function createDownloadBar(): SingleBar { return new SingleBar({ format: 'Downloading |' + chalk.cyan('{bar}') + '| {percentage}% | {speed} MB/s | {value}/{total} MB', barCompleteChar: '\u2588', barIncompleteChar: '\u2591', barsize: 30, formatValue: (value, options, type) => { if (type === 'value' || type === 'total') { return (value / 1024 / 1024).toFixed(2); } return String(value); }, }, Presets.shades_classic); } // Wrapper for async operations export async function withProgress<T>( total: number, fn: (update: (current: number, payload?: Record<string, any>) => void) => Promise<T>, options?: { format?: string } ): Promise<T> { const bar = createProgressBar(options); bar.start(total, 0); try { const result = await fn((current, payload) => { bar.update(current, payload); }); bar.stop(); return result; } catch (error) { bar.stop(); throw error; } } // Batch processing with progress export async function processBatch<T, R>( items: T[], processor: (item: T, index: number) => Promise<R>, options?: { label?: string } ): Promise<R[]> { const bar = createProgressBar({ format: `${options?.label || 'Processing'} |{bar}| {percentage}% | {value}/{total}`, }); bar.start(items.length, 0); const results: R[] = []; for (let i = 0; i < items.length; i++) { results.push(await processor(items[i], i)); bar.update(i + 1); } bar.stop(); return results; } // Parallel processing with multi-bar export async function processParallel<T, R>( tasks: Array<{ name: string; items: T[]; processor: (item: T) => Promise<R>; }> ): Promise<Map<string, R[]>> { const multiBar = createMultiBar(); const bars = new Map<string, SingleBar>(); const results = new Map<string, R[]>(); // Create bars for each task for (const task of tasks) { const bar = multiBar.create(task.items.length, 0, { name: task.name.padEnd(15) }); bars.set(task.name, bar); results.set(task.name, []); } // Process all tasks in parallel await Promise.all(tasks.map(async (task) => { const bar = bars.get(task.name)!; const taskResults = results.get(task.name)!; for (let i = 0; i < task.items.length; i++) { taskResults.push(await task.processor(task.items[i])); bar.update(i + 1); } })); multiBar.stop(); return results; }
json{ "dependencies": { "cli-progress": "^3.12.0", "chalk": "^5.0.0" }, "devDependencies": { "@types/cli-progress": "^3.11.0" } }
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 18,394 | 11,721 | -36% | 1 | 1 | 0% | 3,815 | 4,124 | +8% | 0 | 0 | — |
case-02 | fail→pass | 17,363 | 12,270 | -29% | 1 | 1 | 0% | 3,861 | 4,214 | +9% | 0 | 0 | — |
case-03 | fail→pass | 14,660 | 15,128 | +3% | 1 | 1 | 0% | 3,167 | 4,175 | +32% | 0 | 0 | — |
case-04 | fail→fail | 11,399 | 5,042 | -56% | 1 | 1 | 0% | 2,165 | 2,366 | +9% | 0 | 0 | — |
case-05 | pass→pass | 8,374 | 2,675 | -68% | 1 | 1 | 0% | 1,733 | 1,920 | +11% | 0 | 0 | — |
case-06 | fail→fail | 12,841 | 8,802 | -31% | 1 | 1 | 0% | 2,537 | 3,349 | +32% | 0 | 0 | — |
case-07 | pass→pass | 4,473 | 2,789 | -38% | 1 | 1 | 0% | 830 | 1,886 | +127% | 0 | 0 | — |
case-08 | fail→fail | 9,171 | 10,126 | +10% | 1 | 1 | 0% | 1,854 | 3,402 | +83% | 0 | 0 | — |
case-09 | pass→pass | 7,600 | 1,767 | -77% | 1 | 1 | 0% | 1,341 | 1,652 | +23% | 0 | 0 | — |
case-10 | fail→pass | 10,651 | 4,056 | -62% | 1 | 1 | 0% | 1,967 | 2,126 | +8% | 0 | 0 | — |
case-11 | fail→fail | 4,929 | 3,270 | -34% | 1 | 1 | 0% | 856 | 1,900 | +122% | 0 | 0 | — |
case-12 | fail→pass | 4,625 | 3,129 | -32% | 1 | 1 | 0% | 783 | 1,972 | +152% | 0 | 0 | — |
case-13 | fail→fail | 8,183 | 2,538 | -69% | 1 | 1 | 0% | 1,506 | 1,865 | +24% | 0 | 0 | — |
case-14 | fail→fail | 5,152 | 1,367 | -73% | 1 | 1 | 0% | 861 | 1,573 | +83% | 0 | 0 | — |
case-15 | fail→fail | 11,748 | 5,364 | -54% | 1 | 1 | 0% | 2,274 | 2,503 | +10% | 0 | 0 | — |
case-16 | fail→fail | 10,252 | 3,728 | -64% | 1 | 1 | 0% | 1,973 | 2,113 | +7% | 0 | 0 | — |
case-17 | fail→fail | 5,509 | 2,214 | -60% | 1 | 1 | 0% | 937 | 1,734 | +85% | 0 | 0 | — |
case-18 | fail→pass | 6,577 | 2,130 | -68% | 1 | 1 | 0% | 1,175 | 1,710 | +46% | 0 | 0 | — |
case-19 | fail→fail | 11,057 | 9,414 | -15% | 1 | 1 | 0% | 2,231 | 3,173 | +42% | 0 | 0 | — |
case-20 | fail→fail | 10,413 | 13,683 | +31% | 1 | 1 | 0% | 2,130 | 3,755 | +76% | 0 | 0 | — |
case-21 | fail→fail | 10,797 | 9,589 | -11% | 1 | 1 | 0% | 2,162 | 3,263 | +51% | 0 | 0 | — |
case-22 | fail→fail | 7,681 | 4,846 | -37% | 1 | 1 | 0% | 1,360 | 2,286 | +68% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +27 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.