mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-17 14:16:21 +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
110 lines
2.7 KiB
PowerShell
110 lines
2.7 KiB
PowerShell
# CCS Interactive Prompt Utilities (PowerShell 5.1+ compatible)
|
|
# NO external dependencies
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
# Interactive confirmation prompt
|
|
function Confirm-Action {
|
|
param(
|
|
[string]$Message,
|
|
[ValidateSet('Yes', 'No')]
|
|
[string]$Default = 'No'
|
|
)
|
|
|
|
# Check for --yes flag (automation)
|
|
if ($env:CCS_YES -eq '1' -or $global:RemainingArgs -contains '--yes' -or $global:RemainingArgs -contains '-y') {
|
|
return $Default -eq 'Yes'
|
|
}
|
|
|
|
# Check for --no-input flag (CI)
|
|
if ($env:CCS_NO_INPUT -eq '1' -or $global:RemainingArgs -contains '--no-input') {
|
|
Write-Host "[X] Interactive input required but --no-input specified" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
|
|
# Non-TTY: use default
|
|
if ([Console]::IsInputRedirected) {
|
|
return $Default -eq 'Yes'
|
|
}
|
|
|
|
# Interactive prompt
|
|
$PromptText = if ($Default -eq 'Yes') {
|
|
"$Message [Y/n]: "
|
|
} else {
|
|
"$Message [y/N]: "
|
|
}
|
|
|
|
while ($true) {
|
|
Write-Host $PromptText -NoNewline -ForegroundColor Cyan
|
|
$Response = Read-Host
|
|
|
|
$Normalized = $Response.Trim().ToLower()
|
|
|
|
# Empty answer: use default
|
|
if ($Normalized -eq '' -or $Normalized -eq ' ') {
|
|
return $Default -eq 'Yes'
|
|
}
|
|
|
|
# Valid answers
|
|
if ($Normalized -eq 'y' -or $Normalized -eq 'yes') {
|
|
return $true
|
|
}
|
|
|
|
if ($Normalized -eq 'n' -or $Normalized -eq 'no') {
|
|
return $false
|
|
}
|
|
|
|
# Invalid input: retry
|
|
Write-Host "[!] Please answer y or n" -ForegroundColor Yellow
|
|
}
|
|
}
|
|
|
|
# Interactive text input
|
|
function Read-Input {
|
|
param(
|
|
[string]$Message,
|
|
[string]$Default = '',
|
|
[scriptblock]$Validate = $null
|
|
)
|
|
|
|
# Non-TTY: use default or error
|
|
if ([Console]::IsInputRedirected) {
|
|
if ($Default) {
|
|
return $Default
|
|
}
|
|
throw "Interactive input required but stdin is redirected"
|
|
}
|
|
|
|
# Interactive prompt
|
|
$PromptText = if ($Default) {
|
|
"$Message [$Default]: "
|
|
} else {
|
|
"$Message: "
|
|
}
|
|
|
|
while ($true) {
|
|
Write-Host $PromptText -NoNewline -ForegroundColor Cyan
|
|
$Response = Read-Host
|
|
|
|
$Value = if ($Response.Trim()) { $Response.Trim() } else { $Default }
|
|
|
|
# Validate input if validator provided
|
|
if ($Validate) {
|
|
$Error = & $Validate $Value
|
|
if ($Error) {
|
|
Write-Host "[!] $Error" -ForegroundColor Yellow
|
|
continue
|
|
}
|
|
}
|
|
|
|
return $Value
|
|
}
|
|
}
|
|
|
|
# Check if running in non-interactive mode
|
|
function Test-NonInteractive {
|
|
return [Console]::IsInputRedirected -or
|
|
$env:CCS_YES -eq '1' -or
|
|
$env:CCS_NO_INPUT -eq '1'
|
|
}
|