mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-15 22:21:20 +00:00
Implements 6-phase CLI UX improvement plan with comprehensive error handling, interactive features, and cross-platform consistency. ### Added - Shell auto-completion (bash, zsh, PowerShell, Fish) - Error codes (E101-E901) with documentation URLs - Fuzzy matching "Did you mean?" suggestions (Levenshtein distance) - Progress indicators (doctor [n/9] counter, GLMT proxy spinner) - Interactive confirmation prompts with --yes/-y automation flag - JSON output format (--json) for auth commands - Impact display (session count, paths) before destructive operations - Comprehensive test suite (15 tests, 100% pass rate) - Complete error documentation in docs/errors/ - Cross-platform `--shell-completion` command ### Changed - Error boxes: Unicode (╔═╗) → ASCII (===) for compatibility - JSON output uses CCS version instead of schema version - Help text includes EXAMPLES section across platforms - Test suite properly counts test cases (not assertions) ### Fixed - --yes flag bug (returned false instead of true) - Help text consistency (added Uninstall section to bash) - Test pass rate calculation (excludes skipped tests) - Help section comparison (locale-specific sort) ### Testing - 13/13 tests passing (2 legitimately skipped) - Cross-platform verified (Node.js, bash, PowerShell) - All error codes documented and tested
121 lines
3.3 KiB
PowerShell
121 lines
3.3 KiB
PowerShell
# CCS Progress Indicator (PowerShell 5.1+ compatible)
|
|
# Simple spinner for long-running operations
|
|
# NO external dependencies - ASCII-only for cross-platform compatibility
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
# Show simple spinner (synchronous)
|
|
function Show-Spinner {
|
|
param(
|
|
[string]$Message,
|
|
[scriptblock]$Task
|
|
)
|
|
|
|
# TTY detection: only animate if not redirected and not in CI
|
|
$IsTTY = -not [Console]::IsOutputRedirected -and -not $env:CI -and -not $env:NO_COLOR
|
|
|
|
$StartTime = Get-Date
|
|
|
|
if (-not $IsTTY) {
|
|
# Non-TTY: just print message and run task
|
|
Write-Host "[i] $Message..." -ForegroundColor Gray
|
|
$result = & $Task
|
|
Write-Host "[OK] $Message" -ForegroundColor Green
|
|
return $result
|
|
}
|
|
|
|
# ASCII-only frames for cross-platform compatibility
|
|
$Frames = @('|', '/', '-', '\')
|
|
$FrameIndex = 0
|
|
|
|
# Start task in background job
|
|
$Job = Start-Job -ScriptBlock $Task
|
|
|
|
try {
|
|
# Animate spinner while job is running
|
|
while ($Job.State -eq 'Running') {
|
|
$Frame = $Frames[$FrameIndex]
|
|
$Elapsed = [math]::Round(((Get-Date) - $StartTime).TotalSeconds, 1)
|
|
Write-Host "`r[$Frame] $Message... ($($Elapsed)s)" -NoNewline -ForegroundColor Cyan
|
|
$FrameIndex = ($FrameIndex + 1) % $Frames.Length
|
|
Start-Sleep -Milliseconds 100
|
|
}
|
|
|
|
# Clear spinner line
|
|
Write-Host "`r$(' ' * 80)`r" -NoNewline
|
|
|
|
# Check job result
|
|
$JobResult = Receive-Job -Job $Job -ErrorAction Stop
|
|
$Elapsed = [math]::Round(((Get-Date) - $StartTime).TotalSeconds, 1)
|
|
Write-Host "[OK] $Message ($($Elapsed)s)" -ForegroundColor Green
|
|
|
|
return $JobResult
|
|
}
|
|
catch {
|
|
# Clear spinner line
|
|
Write-Host "`r$(' ' * 80)`r" -NoNewline
|
|
Write-Host "[X] $Message" -ForegroundColor Red
|
|
throw
|
|
}
|
|
finally {
|
|
# Cleanup job
|
|
if ($Job) {
|
|
Remove-Job -Job $Job -Force -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
}
|
|
|
|
# Show progress counter for multi-step operations
|
|
function Show-ProgressStep {
|
|
param(
|
|
[int]$Current,
|
|
[int]$Total,
|
|
[string]$Message
|
|
)
|
|
|
|
# TTY detection
|
|
$IsTTY = -not [Console]::IsOutputRedirected -and -not $env:CI
|
|
|
|
if (-not $IsTTY) {
|
|
Write-Host "[$Current/$Total] $Message" -ForegroundColor Gray
|
|
return
|
|
}
|
|
|
|
# Show progress with carriage return (can be overwritten)
|
|
Write-Host "`r[$Current/$Total] $Message..." -NoNewline -ForegroundColor Cyan
|
|
}
|
|
|
|
# Clear progress line
|
|
function Clear-Progress {
|
|
$IsTTY = -not [Console]::IsOutputRedirected -and -not $env:CI
|
|
|
|
if ($IsTTY) {
|
|
Write-Host "`r$(' ' * 80)`r" -NoNewline
|
|
}
|
|
}
|
|
|
|
# Simple status message (for operations that don't need spinners)
|
|
function Write-Status {
|
|
param(
|
|
[string]$Message,
|
|
[ValidateSet('Info', 'Success', 'Warning', 'Error')]
|
|
[string]$Type = 'Info'
|
|
)
|
|
|
|
$Prefix = switch ($Type) {
|
|
'Info' { '[i]'; break }
|
|
'Success' { '[OK]'; break }
|
|
'Warning' { '[!]'; break }
|
|
'Error' { '[X]'; break }
|
|
}
|
|
|
|
$Color = switch ($Type) {
|
|
'Info' { 'Gray'; break }
|
|
'Success' { 'Green'; break }
|
|
'Warning' { 'Yellow'; break }
|
|
'Error' { 'Red'; break }
|
|
}
|
|
|
|
Write-Host "$Prefix $Message" -ForegroundColor $Color
|
|
}
|