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
100 lines
2.1 KiB
Bash
100 lines
2.1 KiB
Bash
#!/usr/bin/env bash
|
|
# CCS Interactive Prompt Utilities (bash 3.2+ compatible)
|
|
# NO external dependencies
|
|
|
|
set -euo pipefail
|
|
|
|
# Interactive confirmation prompt
|
|
# Usage: confirm_action "message" "yes"|"no"
|
|
# Returns: 0 (true) or 1 (false)
|
|
confirm_action() {
|
|
local message="$1"
|
|
local default="${2:-no}" # Default to NO for safety
|
|
|
|
# Check for --yes flag (automation) - always returns true (0)
|
|
if [[ "${CCS_YES:-}" == "1" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
# Check for --no-input flag (CI)
|
|
if [[ "${CCS_NO_INPUT:-}" == "1" ]]; then
|
|
echo "[X] Interactive input required but --no-input specified" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Non-TTY: use default
|
|
if [[ ! -t 0 ]]; then
|
|
[[ "$default" == "yes" ]] && return 0 || return 1
|
|
fi
|
|
|
|
# Interactive prompt
|
|
local prompt
|
|
if [[ "$default" == "yes" ]]; then
|
|
prompt="$message [Y/n]: "
|
|
else
|
|
prompt="$message [y/N]: "
|
|
fi
|
|
|
|
while true; do
|
|
read -r -p "$prompt" response >&2
|
|
response=$(echo "$response" | tr '[:upper:]' '[:lower:]')
|
|
|
|
case "$response" in
|
|
""|" ")
|
|
# Empty answer: use default
|
|
[[ "$default" == "yes" ]] && return 0 || return 1
|
|
;;
|
|
y|yes)
|
|
return 0
|
|
;;
|
|
n|no)
|
|
return 1
|
|
;;
|
|
*)
|
|
echo "[!] Please answer y or n" >&2
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
# Interactive text input
|
|
# Usage: prompt_input "message" "default_value"
|
|
# Outputs: user input to stdout
|
|
prompt_input() {
|
|
local message="$1"
|
|
local default="${2:-}"
|
|
|
|
# Non-TTY: use default or error
|
|
if [[ ! -t 0 ]]; then
|
|
if [[ -n "$default" ]]; then
|
|
echo "$default"
|
|
return 0
|
|
else
|
|
echo "[X] Interactive input required but stdin is not a TTY" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Interactive prompt
|
|
local prompt
|
|
if [[ -n "$default" ]]; then
|
|
prompt="$message [$default]: "
|
|
else
|
|
prompt="$message: "
|
|
fi
|
|
|
|
read -r -p "$prompt" response >&2
|
|
|
|
# Return user input or default
|
|
if [[ -z "$response" ]]; then
|
|
echo "$default"
|
|
else
|
|
echo "$response"
|
|
fi
|
|
}
|
|
|
|
# Check if running in non-interactive mode
|
|
is_non_interactive() {
|
|
[[ ! -t 0 ]] || [[ "${CCS_YES:-}" == "1" ]] || [[ "${CCS_NO_INPUT:-}" == "1" ]]
|
|
}
|