mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-13 18:15:23 +00:00
feat(cli): refresh help and shell completion UX
- add a shared command catalog for root help and completion routing - replace shell-local completion logic with a hidden __complete backend - add topic help and parity tests for router, help, and completion coverage
This commit is contained in:
1 parent
3eb55d0e33
commit
24ba2abe10
15 files changed
+1227
-2118
No files matched your search
+56
-132
@@ -2,14 +2,16 @@
|
||||
|
||||
Tab completion for CCS commands, subcommands, profiles, and flags.
|
||||
|
||||
The completion scripts are thin adapters over the hidden `ccs __complete` backend so
|
||||
all supported shells stay aligned with the same command graph.
|
||||
|
||||
**Supported Shells:** Bash, Zsh, Fish, PowerShell
|
||||
|
||||
## Features
|
||||
|
||||
- Complete profile names (both settings-based and account-based)
|
||||
- Complete `ccs auth` subcommands (create, list, show, remove, default)
|
||||
- Complete flags (`--help`, `--version`, `--json`, `--verbose`, `--yes`)
|
||||
- Complete profile names for auth subcommands
|
||||
- Complete root commands, help topics, provider shortcuts, and command flags
|
||||
- Complete `ccs auth` and `ccs api` lifecycle subcommands
|
||||
- Context-aware: suggests relevant options based on current command
|
||||
|
||||
## Quick Install (Recommended)
|
||||
@@ -32,6 +34,12 @@ ccs --shell-completion --fish # Force fish
|
||||
ccs --shell-completion --powershell # Force PowerShell
|
||||
```
|
||||
|
||||
**Help and verification:**
|
||||
```bash
|
||||
ccs help completion
|
||||
ccs --shell-completion --force
|
||||
```
|
||||
|
||||
## Manual Installation
|
||||
|
||||
Completion files are installed to `~/.ccs/completions/` during `npm install`.
|
||||
@@ -116,188 +124,104 @@ sudo cp scripts/completion/ccs.fish /usr/share/fish/vendor_completions.d/
|
||||
|
||||
```bash
|
||||
$ ccs <TAB>
|
||||
auth doctor glm kimi work personal --help --version
|
||||
auth api cliproxy config doctor docker help
|
||||
|
||||
$ ccs auth <TAB>
|
||||
create list show remove default --help
|
||||
$ ccs help <TAB>
|
||||
profiles providers completion targets
|
||||
```
|
||||
|
||||
### Profile Completion
|
||||
### Context Completion
|
||||
|
||||
```bash
|
||||
$ ccs auth show <TAB>
|
||||
work personal team --json
|
||||
|
||||
$ ccs auth remove <TAB>
|
||||
work personal team --yes -y
|
||||
$ ccs api <TAB>
|
||||
create discover copy export import remove
|
||||
```
|
||||
|
||||
### Flag Completion
|
||||
### Backend Contract
|
||||
|
||||
```bash
|
||||
$ ccs auth list <TAB>
|
||||
--verbose --json
|
||||
|
||||
$ ccs auth show work <TAB>
|
||||
--json
|
||||
$ ccs __complete --shell bash --current do
|
||||
doctor
|
||||
docker
|
||||
```
|
||||
|
||||
## Completion Behavior
|
||||
|
||||
### Top-level (after `ccs`)
|
||||
- Built-in commands: `auth`, `doctor`
|
||||
- Flags: `--help`, `--version`, `-h`, `-v`
|
||||
- Settings-based profiles: from `~/.ccs/config.json`
|
||||
- Account-based profiles: from `~/.ccs/profiles.json`
|
||||
|
||||
### After `ccs auth`
|
||||
- Subcommands: `create`, `list`, `show`, `remove`, `default`
|
||||
- Flags: `--help`, `-h`
|
||||
|
||||
### After `ccs auth <subcommand>`
|
||||
- **create**: No completion (user enters new profile name)
|
||||
- Flags: `--force`
|
||||
- **list**: No profile completion
|
||||
- Flags: `--verbose`, `--json`
|
||||
- **show**: Account profiles only
|
||||
- Flags: `--json`
|
||||
- **remove**: Account profiles only
|
||||
- Flags: `--yes`, `-y`
|
||||
- **default**: Account profiles only
|
||||
|
||||
### After `ccs <profile>`
|
||||
- No completion (Claude CLI arguments are free-form)
|
||||
Shell adapters now call the shared CCS completion backend instead of maintaining their own
|
||||
copy of the command graph. That means:
|
||||
- top-level commands, help topics, and provider shortcuts come from CCS itself
|
||||
- dynamic profiles and CLIProxy variants resolve through the real config loaders
|
||||
- bash, zsh, fish, and PowerShell stay aligned with the same completion logic
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Bash: Completion not working
|
||||
### Bash
|
||||
|
||||
1. Check if bash-completion is installed:
|
||||
```bash
|
||||
# macOS
|
||||
brew install bash-completion
|
||||
|
||||
# Ubuntu/Debian
|
||||
sudo apt install bash-completion
|
||||
```
|
||||
|
||||
2. Verify jq is installed (required for profile completion):
|
||||
```bash
|
||||
command -v jq
|
||||
```
|
||||
|
||||
3. Check if completion is loaded:
|
||||
1. Check if completion is loaded:
|
||||
```bash
|
||||
complete -p ccs
|
||||
```
|
||||
|
||||
Should output:
|
||||
```
|
||||
complete -F _ccs_completion ccs
|
||||
2. Verify the backend directly:
|
||||
```bash
|
||||
ccs __complete --shell bash --current "" -- help
|
||||
```
|
||||
|
||||
### Zsh: Completion not working
|
||||
### Zsh
|
||||
|
||||
1. Verify completion system is enabled in `~/.zshrc`:
|
||||
1. Verify completion system is enabled:
|
||||
```zsh
|
||||
autoload -Uz compinit && compinit
|
||||
```
|
||||
|
||||
2. Check if completion is loaded:
|
||||
```zsh
|
||||
which _ccs
|
||||
```
|
||||
|
||||
3. Rebuild completion cache:
|
||||
2. Rebuild the cache if needed:
|
||||
```zsh
|
||||
rm ~/.zcompdump && compinit
|
||||
```
|
||||
|
||||
### PowerShell: Completion not working
|
||||
|
||||
1. Check PowerShell version (5.1+ required):
|
||||
```powershell
|
||||
$PSVersionTable.PSVersion
|
||||
3. Verify the backend directly:
|
||||
```zsh
|
||||
ccs __complete --shell zsh --current "" -- help
|
||||
```
|
||||
|
||||
2. Verify profile is loaded:
|
||||
### PowerShell
|
||||
|
||||
1. Check that the profile exists:
|
||||
```powershell
|
||||
Test-Path $PROFILE
|
||||
```
|
||||
|
||||
3. Check if completion is registered:
|
||||
2. Verify the backend directly:
|
||||
```powershell
|
||||
(Get-ArgumentCompleter).CommandName | Select-String ccs
|
||||
ccs __complete --shell powershell --current "" -- help
|
||||
```
|
||||
|
||||
### Fish: Completion not working
|
||||
### Fish
|
||||
|
||||
1. Check Fish version (3.0+ required):
|
||||
```fish
|
||||
fish --version
|
||||
```
|
||||
|
||||
2. Verify completion file is in the right location:
|
||||
1. Verify completion file location:
|
||||
```fish
|
||||
ls ~/.config/fish/completions/ccs.fish
|
||||
```
|
||||
|
||||
3. Verify jq is installed (required for profile completion):
|
||||
```fish
|
||||
which jq
|
||||
```
|
||||
|
||||
4. Test completion manually:
|
||||
2. Test completion manually:
|
||||
```fish
|
||||
complete -C'ccs '
|
||||
```
|
||||
|
||||
5. If needed, rebuild completions:
|
||||
3. Verify the backend directly:
|
||||
```fish
|
||||
fish_update_completions
|
||||
ccs __complete --shell fish --current "" -- help
|
||||
```
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Bash Implementation
|
||||
- Uses `complete -F` for programmable completion
|
||||
- Compatible with bash 3.2+ (macOS default)
|
||||
- Reads profiles dynamically using `jq`
|
||||
- Context-aware based on `COMP_CWORD` and `COMP_WORDS`
|
||||
|
||||
### Zsh Implementation
|
||||
- Uses `_arguments` and `_describe` for rich completion
|
||||
- Compatible with zsh 5.0+
|
||||
- Supports completion descriptions
|
||||
- Context-aware using `$state` and `$words`
|
||||
|
||||
### PowerShell Implementation
|
||||
- Uses `Register-ArgumentCompleter`
|
||||
- Compatible with PowerShell 5.1+
|
||||
- Reads profiles dynamically using `ConvertFrom-Json`
|
||||
- Provides `CompletionResult` objects
|
||||
|
||||
### Fish Implementation
|
||||
- Uses declarative `complete` command
|
||||
- Compatible with Fish 3.0+
|
||||
- Automatic loading from `~/.config/fish/completions/`
|
||||
- Helper functions for dynamic profile loading
|
||||
- Context-aware using `__fish_seen_subcommand_from`
|
||||
- No manual sourcing required
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **jq**: Required for reading profiles from JSON files
|
||||
- Install: `brew install jq` (macOS) or `apt install jq` (Ubuntu)
|
||||
- Already required by CCS core functionality
|
||||
- Bash uses `complete -F`
|
||||
- Zsh uses a custom `_ccs` completion function
|
||||
- Fish uses `complete -a` with backend command substitution
|
||||
- PowerShell uses `Register-ArgumentCompleter`
|
||||
- All four shells now delegate suggestion logic to `ccs __complete`
|
||||
|
||||
## Contributing
|
||||
|
||||
When adding new commands or flags:
|
||||
1. Update all four completion scripts (bash, zsh, fish, PowerShell)
|
||||
2. Test on each shell
|
||||
3. Update this README with new completion examples
|
||||
4. Maintain cross-shell parity
|
||||
When adding or changing command surfaces:
|
||||
1. Update the shared TypeScript command/completion catalog
|
||||
2. Run `bun run validate`
|
||||
3. Smoke-check at least one installed shell adapter plus the backend directly
|
||||
|
||||
## See Also
|
||||
|
||||
|
||||
+28
-196
@@ -1,210 +1,42 @@
|
||||
# Bash completion for CCS (Claude Code Switch)
|
||||
# Compatible with bash 3.2+
|
||||
#
|
||||
# Installation:
|
||||
# Add to ~/.bashrc or ~/.bash_profile:
|
||||
# source /path/to/ccs/scripts/completion/ccs.bash
|
||||
#
|
||||
# Or install system-wide (requires sudo):
|
||||
# sudo cp scripts/completion/ccs.bash /etc/bash_completion.d/ccs
|
||||
|
||||
_ccs_completion() {
|
||||
local cur prev words cword
|
||||
local cur
|
||||
COMPREPLY=()
|
||||
|
||||
# Get current word and previous word
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
|
||||
# Top-level completion (first argument)
|
||||
if [[ ${COMP_CWORD} -eq 1 ]]; then
|
||||
local commands="auth api cliproxy config doctor env persist sync update"
|
||||
local flags="--help --version --shell-completion -h -v -sc"
|
||||
local cliproxy_profiles="gemini codex agy qwen"
|
||||
local profiles=""
|
||||
|
||||
# Add profiles from config.json (settings-based profiles)
|
||||
if [[ -f ~/.ccs/config.json ]]; then
|
||||
profiles="$profiles $(jq -r '.profiles | keys[]' ~/.ccs/config.json 2>/dev/null || true)"
|
||||
fi
|
||||
|
||||
# Add profiles from profiles.json (account-based profiles)
|
||||
if [[ -f ~/.ccs/profiles.json ]]; then
|
||||
profiles="$profiles $(jq -r '.profiles | keys[]' ~/.ccs/profiles.json 2>/dev/null || true)"
|
||||
fi
|
||||
|
||||
# Add cliproxy variants from config.json
|
||||
if [[ -f ~/.ccs/config.json ]]; then
|
||||
profiles="$profiles $(jq -r '.cliproxy | keys[]' ~/.ccs/config.json 2>/dev/null || true)"
|
||||
fi
|
||||
|
||||
# Combine all options
|
||||
local opts="$commands $flags $cliproxy_profiles $profiles"
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||
return 0
|
||||
local tokens_before_current=()
|
||||
if [[ ${COMP_CWORD} -gt 1 ]]; then
|
||||
tokens_before_current=("${COMP_WORDS[@]:1:COMP_CWORD-1}")
|
||||
fi
|
||||
|
||||
# CLIProxy provider flags (gemini, codex, agy, qwen)
|
||||
if [[ ${COMP_WORDS[1]} =~ ^(gemini|codex|agy|qwen)$ ]]; then
|
||||
local provider_flags="--auth --config --logout --headless --help -h"
|
||||
COMPREPLY=( $(compgen -W "${provider_flags}" -- ${cur}) )
|
||||
return 0
|
||||
fi
|
||||
|
||||
# auth subcommands
|
||||
if [[ ${prev} == "auth" ]]; then
|
||||
local auth_commands="create list show remove default --help -h"
|
||||
COMPREPLY=( $(compgen -W "${auth_commands}" -- ${cur}) )
|
||||
return 0
|
||||
fi
|
||||
|
||||
# api subcommands
|
||||
if [[ ${prev} == "api" ]]; then
|
||||
local api_commands="create list remove --help -h"
|
||||
COMPREPLY=( $(compgen -W "${api_commands}" -- ${cur}) )
|
||||
return 0
|
||||
fi
|
||||
|
||||
# cliproxy subcommands
|
||||
if [[ ${prev} == "cliproxy" ]]; then
|
||||
local cliproxy_commands="create list remove --install --latest --help -h"
|
||||
COMPREPLY=( $(compgen -W "${cliproxy_commands}" -- ${cur}) )
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Completion for cliproxy subcommands
|
||||
if [[ ${COMP_WORDS[1]} == "cliproxy" ]]; then
|
||||
case "${prev}" in
|
||||
remove|delete|rm)
|
||||
# Complete with cliproxy variant names
|
||||
if [[ -f ~/.ccs/config.json ]]; then
|
||||
local variants=$(jq -r '.cliproxy | keys[]' ~/.ccs/config.json 2>/dev/null || true)
|
||||
COMPREPLY=( $(compgen -W "${variants}" -- ${cur}) )
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
create)
|
||||
# Complete with create flags
|
||||
COMPREPLY=( $(compgen -W "--provider --model --force --yes -y" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
--provider)
|
||||
# Complete with provider names
|
||||
COMPREPLY=( $(compgen -W "gemini codex agy qwen" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
list|ls)
|
||||
# No flags for list
|
||||
return 0
|
||||
;;
|
||||
--install)
|
||||
# User enters version number
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Completion for api subcommands
|
||||
if [[ ${COMP_WORDS[1]} == "api" ]]; then
|
||||
case "${prev}" in
|
||||
remove|delete|rm)
|
||||
# Complete with settings profile names
|
||||
if [[ -f ~/.ccs/config.json ]]; then
|
||||
local profiles=$(jq -r '.profiles | keys[]' ~/.ccs/config.json 2>/dev/null || true)
|
||||
COMPREPLY=( $(compgen -W "${profiles}" -- ${cur}) )
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
create)
|
||||
# Complete with create flags
|
||||
COMPREPLY=( $(compgen -W "--base-url --api-key --model --force --yes -y" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
list)
|
||||
# No flags for list
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Completion for auth subcommands that need profile names
|
||||
if [[ ${COMP_WORDS[1]} == "auth" ]]; then
|
||||
case "${prev}" in
|
||||
show|remove|default)
|
||||
# Complete with account profile names only
|
||||
if [[ -f ~/.ccs/profiles.json ]]; then
|
||||
local profiles=$(jq -r '.profiles | keys[]' ~/.ccs/profiles.json 2>/dev/null || true)
|
||||
COMPREPLY=( $(compgen -W "${profiles}" -- ${cur}) )
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
create)
|
||||
# Complete with create flags
|
||||
COMPREPLY=( $(compgen -W "--force" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
list)
|
||||
# Complete with list flags
|
||||
COMPREPLY=( $(compgen -W "--verbose --json" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# env subcommands
|
||||
if [[ ${COMP_WORDS[1]} == "env" ]]; then
|
||||
case "${prev}" in
|
||||
env)
|
||||
# Complete with profile names and flags (inline profiles since $cliproxy_profiles is out of scope)
|
||||
local env_opts="--format --shell --ide --help -h gemini codex agy qwen iflow kiro ghcp claude default"
|
||||
if [[ -f ~/.ccs/config.json ]]; then
|
||||
env_opts="$env_opts $(jq -r '.profiles | keys[]' ~/.ccs/config.json 2>/dev/null || true)"
|
||||
fi
|
||||
if [[ -f ~/.ccs/profiles.json ]]; then
|
||||
env_opts="$env_opts $(jq -r '.profiles | keys[]' ~/.ccs/profiles.json 2>/dev/null || true)"
|
||||
fi
|
||||
COMPREPLY=( $(compgen -W "${env_opts}" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
--format)
|
||||
COMPREPLY=( $(compgen -W "openai anthropic raw claude-extension" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
--shell)
|
||||
COMPREPLY=( $(compgen -W "auto bash zsh fish powershell" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
--ide)
|
||||
COMPREPLY=( $(compgen -W "vscode cursor windsurf" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=( $(compgen -W "--format --shell --ide --help -h" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Flags for doctor command
|
||||
if [[ ${COMP_WORDS[1]} == "doctor" ]]; then
|
||||
COMPREPLY=( $(compgen -W "--help -h" -- ${cur}) )
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Flags for update command
|
||||
if [[ ${COMP_WORDS[1]} == "update" ]]; then
|
||||
COMPREPLY=( $(compgen -W "--force --beta --dev --help -h" -- ${cur}) )
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Flags for shell-completion command
|
||||
if [[ ${prev} == "--shell-completion" || ${prev} == "-sc" ]]; then
|
||||
COMPREPLY=( $(compgen -W "--bash --zsh --fish --powershell" -- ${cur}) )
|
||||
return 0
|
||||
fi
|
||||
while IFS= read -r line; do
|
||||
[[ -n "${line}" ]] && COMPREPLY+=("${line}")
|
||||
done < <(__ccs_completion_run "${cur}" "${tokens_before_current[@]}")
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Register completion function
|
||||
__ccs_completion_run() {
|
||||
local current="$1"
|
||||
shift || true
|
||||
|
||||
local script_dir repo_root repo_cli
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo_root="$(cd "${script_dir}/../.." && pwd)"
|
||||
repo_cli="${repo_root}/dist/ccs.js"
|
||||
if [[ ! -f "${repo_cli}" ]]; then
|
||||
repo_cli="${repo_root}/bin/ccs.js"
|
||||
fi
|
||||
if [[ -f "${repo_cli}" ]]; then
|
||||
node "${repo_cli}" __complete --shell bash --current "${current}" -- "$@" 2>/dev/null
|
||||
return 0
|
||||
fi
|
||||
|
||||
if command -v ccs >/dev/null 2>&1; then
|
||||
ccs __complete --shell bash --current "${current}" -- "$@" 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
complete -F _ccs_completion ccs
|
||||
+21
-250
@@ -1,256 +1,27 @@
|
||||
# Fish completion for CCS (Claude Code Switch)
|
||||
# Compatible with fish 3.0+
|
||||
#
|
||||
# Features:
|
||||
# - Categorized completions with [cmd], [proxy], [model], and [account] prefixes
|
||||
# - Dynamic profile loading from config.json and profiles.json
|
||||
# - Context-aware subcommand completion
|
||||
#
|
||||
# Installation:
|
||||
# Copy to ~/.config/fish/completions/:
|
||||
# mkdir -p ~/.config/fish/completions
|
||||
# cp scripts/completion/ccs.fish ~/.config/fish/completions/
|
||||
#
|
||||
# Fish will automatically load completions from this directory.
|
||||
# No need to source or reload - completions are loaded on demand.
|
||||
|
||||
# Helper function to get settings profiles
|
||||
function __fish_ccs_get_settings_profiles
|
||||
set -l config_path ~/.ccs/config.json
|
||||
function __fish_ccs_complete
|
||||
set -l tokens_before_current (commandline -opc)
|
||||
if test (count $tokens_before_current) -gt 0
|
||||
set -e tokens_before_current[1]
|
||||
end
|
||||
|
||||
if test -f $config_path
|
||||
jq -r '.profiles | keys[]' $config_path 2>/dev/null
|
||||
set -l current (commandline -ct)
|
||||
|
||||
set -l script_file (status filename)
|
||||
set -l repo_root (realpath (dirname $script_file)/../.. 2>/dev/null)
|
||||
set -l repo_cli "$repo_root/dist/ccs.js"
|
||||
if not test -f "$repo_cli"
|
||||
set repo_cli "$repo_root/bin/ccs.js"
|
||||
end
|
||||
if test -f "$repo_cli"
|
||||
node "$repo_cli" __complete --shell fish --current "$current" -- $tokens_before_current 2>/dev/null
|
||||
return
|
||||
end
|
||||
|
||||
if command -sq ccs
|
||||
ccs __complete --shell fish --current "$current" -- $tokens_before_current 2>/dev/null
|
||||
end
|
||||
end
|
||||
|
||||
# Helper function to get custom/unknown settings profiles
|
||||
function __fish_ccs_get_custom_settings_profiles
|
||||
set -l config_path ~/.ccs/config.json
|
||||
set -l known_profiles default glm kimi
|
||||
|
||||
if test -f $config_path
|
||||
set -l all_profiles (jq -r '.profiles | keys[]' $config_path 2>/dev/null)
|
||||
|
||||
for profile in $all_profiles
|
||||
if not contains $profile $known_profiles
|
||||
echo $profile
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Helper function to get cliproxy variants
|
||||
function __fish_ccs_get_cliproxy_variants
|
||||
set -l config_path ~/.ccs/config.json
|
||||
|
||||
if test -f $config_path
|
||||
jq -r '.cliproxy | keys[]' $config_path 2>/dev/null
|
||||
end
|
||||
end
|
||||
|
||||
# Helper function to get profiles with all types
|
||||
function __fish_ccs_get_profiles
|
||||
__fish_ccs_get_settings_profiles
|
||||
__fish_ccs_get_account_profiles
|
||||
end
|
||||
|
||||
# Helper function to get account profiles only
|
||||
function __fish_ccs_get_account_profiles
|
||||
set -l profiles_path ~/.ccs/profiles.json
|
||||
|
||||
if test -f $profiles_path
|
||||
jq -r '.profiles | keys[]' $profiles_path 2>/dev/null
|
||||
end
|
||||
end
|
||||
|
||||
# Helper function to check if we're in auth context
|
||||
function __fish_ccs_using_auth
|
||||
__fish_seen_subcommand_from auth
|
||||
end
|
||||
|
||||
# Helper function to check specific auth subcommand
|
||||
function __fish_ccs_using_auth_subcommand
|
||||
set -l subcommand $argv[1]
|
||||
__fish_ccs_using_auth; and __fish_seen_subcommand_from $subcommand
|
||||
end
|
||||
|
||||
# Helper function to check if we're in api context
|
||||
function __fish_ccs_using_api
|
||||
__fish_seen_subcommand_from api
|
||||
end
|
||||
|
||||
# Helper function to check specific api subcommand
|
||||
function __fish_ccs_using_api_subcommand
|
||||
set -l subcommand $argv[1]
|
||||
__fish_ccs_using_api; and __fish_seen_subcommand_from $subcommand
|
||||
end
|
||||
|
||||
# Helper function to check if we're in cliproxy context
|
||||
function __fish_ccs_using_cliproxy
|
||||
__fish_seen_subcommand_from cliproxy
|
||||
end
|
||||
|
||||
# Helper function to check specific cliproxy subcommand
|
||||
function __fish_ccs_using_cliproxy_subcommand
|
||||
set -l subcommand $argv[1]
|
||||
__fish_ccs_using_cliproxy; and __fish_seen_subcommand_from $subcommand
|
||||
end
|
||||
|
||||
# Helper function to check if we're in profile context
|
||||
function __fish_ccs_using_profile
|
||||
__fish_seen_subcommand_from profile
|
||||
end
|
||||
|
||||
# Helper function to check specific profile subcommand
|
||||
function __fish_ccs_using_profile_subcommand
|
||||
set -l subcommand $argv[1]
|
||||
__fish_ccs_using_profile; and __fish_seen_subcommand_from $subcommand
|
||||
end
|
||||
|
||||
# Helper function to check if we're using a CLIProxy provider
|
||||
function __fish_ccs_using_provider
|
||||
__fish_seen_subcommand_from gemini codex agy qwen
|
||||
end
|
||||
|
||||
# Disable file completion for ccs
|
||||
complete -c ccs -f
|
||||
|
||||
# Top-level flags
|
||||
complete -c ccs -s h -l help -d 'Show help message'
|
||||
complete -c ccs -s v -l version -d 'Show version information'
|
||||
complete -c ccs -s sc -l shell-completion -d 'Install shell completion'
|
||||
|
||||
# Commands - grouped with [cmd] prefix for visual distinction
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a 'auth' -d '[cmd] Manage multiple Claude accounts'
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a 'api' -d '[cmd] Manage API profiles (create/remove)'
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a 'cliproxy' -d '[cmd] Manage CLIProxy variants and binary'
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a 'doctor' -d '[cmd] Run health check and diagnostics'
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a 'env' -d '[cmd] Export env vars for third-party tools'
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a 'sync' -d '[cmd] Sync delegation commands and skills'
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a 'update' -d '[cmd] Update CCS to latest version'
|
||||
|
||||
# CLIProxy profiles - grouped with [proxy] prefix for OAuth providers
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a 'gemini' -d '[proxy] Google Gemini (OAuth)'
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a 'codex' -d '[proxy] OpenAI Codex (OAuth)'
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a 'agy' -d '[proxy] Antigravity (OAuth)'
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a 'qwen' -d '[proxy] Qwen Code (OAuth)'
|
||||
|
||||
# Model profiles - grouped with [model] prefix for visual distinction
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a 'default' -d '[model] Default Claude Sonnet 4.5'
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a 'glm' -d '[model] GLM-4.6 (cost-optimized)'
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a 'kimi' -d '[model] Kimi for Coding (long-context)'
|
||||
|
||||
# Custom model profiles - dynamic with [model] prefix
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a '(__fish_ccs_get_custom_settings_profiles)' -d '[model] Settings-based profile'
|
||||
|
||||
# CLIProxy variants - dynamic with [variant] prefix
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a '(__fish_ccs_get_cliproxy_variants)' -d '[variant] CLIProxy variant'
|
||||
|
||||
# Account profiles - dynamic with [account] prefix
|
||||
complete -c ccs -n 'not __fish_seen_subcommand_from auth api cliproxy doctor env sync update gemini codex agy qwen' -a '(__fish_ccs_get_account_profiles)' -d '[account] Account-based profile'
|
||||
|
||||
# shell-completion subflags
|
||||
complete -c ccs -n '__fish_seen_argument -l shell-completion; or __fish_seen_argument -s sc' -l bash -d 'Install for bash'
|
||||
complete -c ccs -n '__fish_seen_argument -l shell-completion; or __fish_seen_argument -s sc' -l zsh -d 'Install for zsh'
|
||||
complete -c ccs -n '__fish_seen_argument -l shell-completion; or __fish_seen_argument -s sc' -l fish -d 'Install for fish'
|
||||
complete -c ccs -n '__fish_seen_argument -l shell-completion; or __fish_seen_argument -s sc' -l powershell -d 'Install for PowerShell'
|
||||
|
||||
# CLIProxy provider flags (gemini, codex, agy, qwen)
|
||||
complete -c ccs -n '__fish_ccs_using_provider' -l auth -d 'Authenticate only'
|
||||
complete -c ccs -n '__fish_ccs_using_provider' -l config -d 'Change model configuration'
|
||||
complete -c ccs -n '__fish_ccs_using_provider' -l logout -d 'Clear authentication'
|
||||
complete -c ccs -n '__fish_ccs_using_provider' -l headless -d 'Headless auth (for SSH)'
|
||||
complete -c ccs -n '__fish_ccs_using_provider' -s h -l help -d 'Show help'
|
||||
|
||||
# update command flags
|
||||
complete -c ccs -n '__fish_seen_subcommand_from update' -l force -d 'Force reinstall current version'
|
||||
complete -c ccs -n '__fish_seen_subcommand_from update' -l beta -d 'Install from dev channel'
|
||||
complete -c ccs -n '__fish_seen_subcommand_from update' -l dev -d 'Install from dev channel'
|
||||
complete -c ccs -n '__fish_seen_subcommand_from update' -s h -l help -d 'Show help'
|
||||
|
||||
# doctor command flags
|
||||
complete -c ccs -n '__fish_seen_subcommand_from doctor' -s h -l help -d 'Show help for doctor command'
|
||||
|
||||
# env command completions
|
||||
complete -c ccs -n '__fish_seen_subcommand_from env; and not __fish_seen_argument -l format -l shell' -a 'gemini codex agy qwen iflow kiro ghcp claude' -d '[proxy] CLIProxy profile'
|
||||
complete -c ccs -n '__fish_seen_subcommand_from env' -l format -d 'Output format'
|
||||
complete -c ccs -n '__fish_seen_subcommand_from env; and __fish_seen_argument -l format' -a 'openai anthropic raw' -d 'Format'
|
||||
complete -c ccs -n '__fish_seen_subcommand_from env' -l shell -d 'Shell syntax'
|
||||
complete -c ccs -n '__fish_seen_subcommand_from env; and __fish_seen_argument -l shell' -a 'auto bash zsh fish powershell' -d 'Shell'
|
||||
complete -c ccs -n '__fish_seen_subcommand_from env' -s h -l help -d 'Show help for env command'
|
||||
|
||||
# ============================================================================
|
||||
# auth subcommands
|
||||
# ============================================================================
|
||||
complete -c ccs -n '__fish_ccs_using_auth; and not __fish_seen_subcommand_from create list show remove default' -a 'create' -d 'Create new profile and login'
|
||||
complete -c ccs -n '__fish_ccs_using_auth; and not __fish_seen_subcommand_from create list show remove default' -a 'list' -d 'List all saved profiles'
|
||||
complete -c ccs -n '__fish_ccs_using_auth; and not __fish_seen_subcommand_from create list show remove default' -a 'show' -d 'Show profile details'
|
||||
complete -c ccs -n '__fish_ccs_using_auth; and not __fish_seen_subcommand_from create list show remove default' -a 'remove' -d 'Remove saved profile'
|
||||
complete -c ccs -n '__fish_ccs_using_auth; and not __fish_seen_subcommand_from create list show remove default' -a 'default' -d 'Set default profile'
|
||||
|
||||
complete -c ccs -n '__fish_ccs_using_auth' -s h -l help -d 'Show help for auth commands'
|
||||
complete -c ccs -n '__fish_ccs_using_auth_subcommand create' -l force -d 'Allow overwriting existing profile'
|
||||
complete -c ccs -n '__fish_ccs_using_auth_subcommand list' -l verbose -d 'Show additional details'
|
||||
complete -c ccs -n '__fish_ccs_using_auth_subcommand list' -l json -d 'Output in JSON format'
|
||||
complete -c ccs -n '__fish_ccs_using_auth_subcommand show' -a '(__fish_ccs_get_account_profiles)' -d 'Account profile'
|
||||
complete -c ccs -n '__fish_ccs_using_auth_subcommand show' -l json -d 'Output in JSON format'
|
||||
complete -c ccs -n '__fish_ccs_using_auth_subcommand remove' -a '(__fish_ccs_get_account_profiles)' -d 'Account profile'
|
||||
complete -c ccs -n '__fish_ccs_using_auth_subcommand remove' -l yes -d 'Skip confirmation prompts'
|
||||
complete -c ccs -n '__fish_ccs_using_auth_subcommand remove' -s y -d 'Skip confirmation prompts'
|
||||
complete -c ccs -n '__fish_ccs_using_auth_subcommand default' -a '(__fish_ccs_get_account_profiles)' -d 'Account profile'
|
||||
|
||||
# ============================================================================
|
||||
# api subcommands
|
||||
# ============================================================================
|
||||
complete -c ccs -n '__fish_ccs_using_api; and not __fish_seen_subcommand_from create list remove' -a 'create' -d 'Create new API profile'
|
||||
complete -c ccs -n '__fish_ccs_using_api; and not __fish_seen_subcommand_from create list remove' -a 'list' -d 'List all API profiles'
|
||||
complete -c ccs -n '__fish_ccs_using_api; and not __fish_seen_subcommand_from create list remove' -a 'remove' -d 'Remove an API profile'
|
||||
|
||||
complete -c ccs -n '__fish_ccs_using_api' -s h -l help -d 'Show help for api commands'
|
||||
complete -c ccs -n '__fish_ccs_using_api_subcommand create' -l base-url -d 'API base URL'
|
||||
complete -c ccs -n '__fish_ccs_using_api_subcommand create' -l api-key -d 'API key'
|
||||
complete -c ccs -n '__fish_ccs_using_api_subcommand create' -l model -d 'Default model'
|
||||
complete -c ccs -n '__fish_ccs_using_api_subcommand create' -l force -d 'Overwrite existing profile'
|
||||
complete -c ccs -n '__fish_ccs_using_api_subcommand create' -l yes -d 'Skip prompts'
|
||||
complete -c ccs -n '__fish_ccs_using_api_subcommand create' -s y -d 'Skip prompts'
|
||||
complete -c ccs -n '__fish_ccs_using_api_subcommand remove' -a '(__fish_ccs_get_settings_profiles)' -d 'Settings profile'
|
||||
complete -c ccs -n '__fish_ccs_using_api_subcommand remove' -l yes -d 'Skip confirmation'
|
||||
complete -c ccs -n '__fish_ccs_using_api_subcommand remove' -s y -d 'Skip confirmation'
|
||||
|
||||
# ============================================================================
|
||||
# cliproxy subcommands
|
||||
# ============================================================================
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy; and not __fish_seen_subcommand_from create list remove' -a 'create' -d 'Create new CLIProxy variant'
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy; and not __fish_seen_subcommand_from create list remove' -a 'list' -d 'List all CLIProxy variants'
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy; and not __fish_seen_subcommand_from create list remove' -a 'remove' -d 'Remove a CLIProxy variant'
|
||||
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy' -s h -l help -d 'Show help for cliproxy commands'
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy' -l install -d 'Install specific version'
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy' -l latest -d 'Install latest version'
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy_subcommand create' -l provider -d 'Provider name'
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy_subcommand create; and __fish_seen_argument -l provider' -a 'gemini codex agy qwen' -d 'Provider'
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy_subcommand create' -l model -d 'Model name'
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy_subcommand create' -l force -d 'Overwrite existing variant'
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy_subcommand create' -l yes -d 'Skip prompts'
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy_subcommand create' -s y -d 'Skip prompts'
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy_subcommand remove' -a '(__fish_ccs_get_cliproxy_variants)' -d 'CLIProxy variant'
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy_subcommand remove' -l yes -d 'Skip confirmation'
|
||||
complete -c ccs -n '__fish_ccs_using_cliproxy_subcommand remove' -s y -d 'Skip confirmation'
|
||||
|
||||
# ============================================================================
|
||||
# profile subcommands (legacy - redirects to api)
|
||||
# ============================================================================
|
||||
complete -c ccs -n '__fish_ccs_using_profile; and not __fish_seen_subcommand_from create list remove' -a 'create' -d 'Create new API profile'
|
||||
complete -c ccs -n '__fish_ccs_using_profile; and not __fish_seen_subcommand_from create list remove' -a 'list' -d 'List all profiles'
|
||||
complete -c ccs -n '__fish_ccs_using_profile; and not __fish_seen_subcommand_from create list remove' -a 'remove' -d 'Remove a profile'
|
||||
|
||||
complete -c ccs -n '__fish_ccs_using_profile' -s h -l help -d 'Show help for profile commands'
|
||||
complete -c ccs -n '__fish_ccs_using_profile_subcommand create' -l base-url -d 'API base URL'
|
||||
complete -c ccs -n '__fish_ccs_using_profile_subcommand create' -l api-key -d 'API key'
|
||||
complete -c ccs -n '__fish_ccs_using_profile_subcommand create' -l model -d 'Default model'
|
||||
complete -c ccs -n '__fish_ccs_using_profile_subcommand create' -l force -d 'Overwrite existing profile'
|
||||
complete -c ccs -n '__fish_ccs_using_profile_subcommand create' -l yes -d 'Skip prompts'
|
||||
complete -c ccs -n '__fish_ccs_using_profile_subcommand create' -s y -d 'Skip prompts'
|
||||
complete -c ccs -n '__fish_ccs_using_profile_subcommand remove' -a '(__fish_ccs_get_settings_profiles)' -d 'Settings profile'
|
||||
complete -c ccs -n '__fish_ccs_using_profile_subcommand remove' -l yes -d 'Skip confirmation'
|
||||
complete -c ccs -n '__fish_ccs_using_profile_subcommand remove' -s y -d 'Skip confirmation'
|
||||
complete -c ccs -f -a "(__fish_ccs_complete)"
|
||||
+42
-432
@@ -1,446 +1,56 @@
|
||||
# PowerShell completion for CCS (Claude Code Switch)
|
||||
# Compatible with PowerShell 5.1+
|
||||
#
|
||||
# Installation:
|
||||
# Add to your PowerShell profile ($PROFILE):
|
||||
# . /path/to/ccs/scripts/completion/ccs.ps1
|
||||
#
|
||||
# Or install for current user:
|
||||
# Copy-Item scripts/completion/ccs.ps1 ~\Documents\PowerShell\Scripts\
|
||||
# Add to profile: . ~\Documents\PowerShell\Scripts\ccs.ps1
|
||||
|
||||
function Invoke-CcsCompletionBackend {
|
||||
param(
|
||||
[string]$CurrentWord,
|
||||
[string[]]$TokensBeforeCurrent
|
||||
)
|
||||
|
||||
$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
|
||||
$repoCli = Join-Path $repoRoot 'dist\ccs.js'
|
||||
if (-not (Test-Path $repoCli)) {
|
||||
$repoCli = Join-Path $repoRoot 'bin\ccs.js'
|
||||
}
|
||||
if (Test-Path $repoCli) {
|
||||
& node $repoCli __complete --shell powershell --current $CurrentWord -- @TokensBeforeCurrent 2>$null
|
||||
return
|
||||
}
|
||||
|
||||
if (Get-Command ccs -ErrorAction SilentlyContinue) {
|
||||
& ccs __complete --shell powershell --current $CurrentWord -- @TokensBeforeCurrent 2>$null
|
||||
}
|
||||
}
|
||||
|
||||
Register-ArgumentCompleter -CommandName ccs -ScriptBlock {
|
||||
param($commandName, $wordToComplete, $commandAst, $fakeBoundParameters)
|
||||
|
||||
$commands = @('auth', 'api', 'cliproxy', 'doctor', 'env', 'sync', 'update', '--help', '--version', '--shell-completion', '-h', '-v', '-sc')
|
||||
$cliproxyProfiles = @('gemini', 'codex', 'agy', 'qwen', 'iflow', 'kiro', 'ghcp', 'claude')
|
||||
$authCommands = @('create', 'list', 'show', 'remove', 'default', '--help', '-h')
|
||||
$apiCommands = @('create', 'list', 'remove', '--help', '-h')
|
||||
$cliproxyCommands = @('create', 'list', 'remove', '--install', '--latest', '--help', '-h')
|
||||
$apiCreateFlags = @('--base-url', '--api-key', '--model', '--force', '--yes', '-y')
|
||||
$cliproxyCreateFlags = @('--provider', '--model', '--force', '--yes', '-y')
|
||||
$providerFlags = @('--auth', '--config', '--logout', '--headless', '--help', '-h')
|
||||
$updateFlags = @('--force', '--beta', '--dev', '--help', '-h')
|
||||
$envFlags = @('--format', '--shell', '--help', '-h')
|
||||
$envFormats = @('openai', 'anthropic', 'raw')
|
||||
$envShells = @('auto', 'bash', 'zsh', 'fish', 'powershell')
|
||||
$shellCompletionFlags = @('--bash', '--zsh', '--fish', '--powershell')
|
||||
$listFlags = @('--verbose', '--json')
|
||||
$removeFlags = @('--yes', '-y')
|
||||
$showFlags = @('--json')
|
||||
$providers = @('gemini', 'codex', 'agy', 'qwen')
|
||||
|
||||
# Get current position in command
|
||||
$words = $commandAst.ToString() -split '\s+' | Where-Object { $_ -ne '' }
|
||||
$position = $words.Count
|
||||
|
||||
# Helper function to get profiles
|
||||
function Get-CcsProfiles {
|
||||
param([string]$Type = 'all')
|
||||
|
||||
$profiles = @()
|
||||
|
||||
# Settings-based profiles
|
||||
if ($Type -in @('all', 'settings')) {
|
||||
$configPath = "$env:USERPROFILE\.ccs\config.json"
|
||||
if (Test-Path $configPath) {
|
||||
try {
|
||||
$config = Get-Content $configPath -Raw | ConvertFrom-Json
|
||||
$profiles += $config.profiles.PSObject.Properties.Name
|
||||
} catch {}
|
||||
$commandElements = @($commandAst.CommandElements | ForEach-Object { $_.Extent.Text })
|
||||
$tokensBeforeCurrent = @()
|
||||
if ($commandElements.Count -gt 1) {
|
||||
$tokensBeforeCurrent = $commandElements[1..($commandElements.Count - 1)]
|
||||
if ($tokensBeforeCurrent.Count -gt 0 -and $tokensBeforeCurrent[-1] -eq $wordToComplete) {
|
||||
$tokensBeforeCurrent = if ($tokensBeforeCurrent.Count -gt 1) {
|
||||
$tokensBeforeCurrent[0..($tokensBeforeCurrent.Count - 2)]
|
||||
} else {
|
||||
@()
|
||||
}
|
||||
}
|
||||
|
||||
# Account-based profiles
|
||||
if ($Type -in @('all', 'account')) {
|
||||
$profilesPath = "$env:USERPROFILE\.ccs\profiles.json"
|
||||
if (Test-Path $profilesPath) {
|
||||
try {
|
||||
$data = Get-Content $profilesPath -Raw | ConvertFrom-Json
|
||||
$profiles += $data.profiles.PSObject.Properties.Name
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
|
||||
# CLIProxy variants
|
||||
if ($Type -in @('all', 'cliproxy')) {
|
||||
$configPath = "$env:USERPROFILE\.ccs\config.json"
|
||||
if (Test-Path $configPath) {
|
||||
try {
|
||||
$config = Get-Content $configPath -Raw | ConvertFrom-Json
|
||||
if ($config.cliproxy) {
|
||||
$profiles += $config.cliproxy.PSObject.Properties.Name
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
|
||||
return $profiles | Sort-Object -Unique
|
||||
}
|
||||
|
||||
# Top-level completion
|
||||
if ($position -eq 2) {
|
||||
$allOptions = $commands + $cliproxyProfiles + (Get-CcsProfiles)
|
||||
$allOptions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
foreach ($line in Invoke-CcsCompletionBackend -CurrentWord $wordToComplete -TokensBeforeCurrent $tokensBeforeCurrent) {
|
||||
if ([string]::IsNullOrWhiteSpace($line)) {
|
||||
continue
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
# shell-completion flag completion
|
||||
if ($words[1] -eq '--shell-completion' -or $words[1] -eq '-sc') {
|
||||
if ($position -eq 3) {
|
||||
$shellCompletionFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
$parts = $line -split "`t", 2
|
||||
$value = $parts[0]
|
||||
$description = if ($parts.Count -gt 1) { $parts[1] } else { $parts[0] }
|
||||
|
||||
# CLIProxy provider flags (gemini, codex, agy, qwen)
|
||||
if ($words[1] -in $cliproxyProfiles) {
|
||||
$providerFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
# update command completion
|
||||
if ($words[1] -eq 'update') {
|
||||
$updateFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
# env command completion
|
||||
if ($words[1] -eq 'env') {
|
||||
if ($position -eq 3) {
|
||||
$options = $cliproxyProfiles + (Get-CcsProfiles -Type settings) + $envFlags
|
||||
$options | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
} elseif ($position -ge 4) {
|
||||
switch ($words[$position - 2]) {
|
||||
'--format' {
|
||||
$envFormats | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
'--shell' {
|
||||
$envShells | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
default {
|
||||
$envFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
# auth subcommand completion
|
||||
if ($words[1] -eq 'auth') {
|
||||
if ($position -eq 3) {
|
||||
$authCommands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
} elseif ($position -eq 4) {
|
||||
switch ($words[2]) {
|
||||
'show' {
|
||||
$options = (Get-CcsProfiles -Type account) + $showFlags
|
||||
$options | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
'remove' {
|
||||
$options = (Get-CcsProfiles -Type account) + $removeFlags
|
||||
$options | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
'default' {
|
||||
Get-CcsProfiles -Type account | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
'list' {
|
||||
$listFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
'create' {
|
||||
@('--force') | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($position -eq 5) {
|
||||
switch ($words[2]) {
|
||||
'show' {
|
||||
$showFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
'remove' {
|
||||
$removeFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
# api subcommand completion
|
||||
if ($words[1] -eq 'api') {
|
||||
if ($position -eq 3) {
|
||||
$apiCommands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
} elseif ($position -eq 4) {
|
||||
switch ($words[2]) {
|
||||
'remove' {
|
||||
$options = (Get-CcsProfiles -Type settings) + $removeFlags
|
||||
$options | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
'create' {
|
||||
$apiCreateFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($position -eq 5) {
|
||||
switch ($words[2]) {
|
||||
'remove' {
|
||||
$removeFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
# cliproxy subcommand completion
|
||||
if ($words[1] -eq 'cliproxy') {
|
||||
if ($position -eq 3) {
|
||||
$cliproxyCommands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
} elseif ($position -eq 4) {
|
||||
switch ($words[2]) {
|
||||
'remove' {
|
||||
$options = (Get-CcsProfiles -Type cliproxy) + $removeFlags
|
||||
$options | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
'create' {
|
||||
$cliproxyCreateFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($position -eq 5) {
|
||||
switch ($words[2]) {
|
||||
'remove' {
|
||||
$removeFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
'create' {
|
||||
# After --provider, complete with provider names
|
||||
if ($words[3] -eq '--provider') {
|
||||
$providers | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
# profile subcommand completion (legacy)
|
||||
if ($words[1] -eq 'profile') {
|
||||
if ($position -eq 3) {
|
||||
@('create', 'list', 'remove', '--help', '-h') | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
} elseif ($position -eq 4) {
|
||||
switch ($words[2]) {
|
||||
'remove' {
|
||||
$options = (Get-CcsProfiles -Type settings) + $removeFlags
|
||||
$options | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
'create' {
|
||||
$apiCreateFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($position -eq 5) {
|
||||
switch ($words[2]) {
|
||||
'remove' {
|
||||
$removeFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$_,
|
||||
$_,
|
||||
'ParameterValue',
|
||||
$_
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
[System.Management.Automation.CompletionResult]::new(
|
||||
$value,
|
||||
$value,
|
||||
'ParameterValue',
|
||||
$description
|
||||
)
|
||||
}
|
||||
}
|
||||
+26
-304
@@ -1,319 +1,41 @@
|
||||
#compdef ccs
|
||||
|
||||
# Zsh completion for CCS (Claude Code Switch)
|
||||
# Compatible with zsh 5.0+
|
||||
#
|
||||
# Installation:
|
||||
# Add to ~/.zshrc:
|
||||
# fpath=(~/.zsh/completion $fpath)
|
||||
# autoload -Uz compinit && compinit
|
||||
# source /path/to/ccs/scripts/completion/ccs.zsh
|
||||
#
|
||||
# Or install system-wide:
|
||||
# sudo cp scripts/completion/ccs.zsh /usr/local/share/zsh/site-functions/_ccs
|
||||
|
||||
# Set up completion styles for better formatting and colors
|
||||
zstyle ':completion:*:*:ccs:*:commands' list-colors '=(#b)(auth|api|cliproxy|doctor|env|sync|update)([[:space:]]#--[[:space:]]#*)==0\;34=2\;37'
|
||||
zstyle ':completion:*:*:ccs:*:proxy-profiles' list-colors '=(#b)(gemini|codex|agy|qwen)([[:space:]]#--[[:space:]]#*)==0\;35=2\;37'
|
||||
zstyle ':completion:*:*:ccs:*:model-profiles' list-colors '=(#b)(default|glm|kimi|[^[:space:]]##)([[:space:]]#--[[:space:]]#*)==0\;32=2\;37'
|
||||
zstyle ':completion:*:*:ccs:*:account-profiles' list-colors '=(#b)([^[:space:]]##)([[:space:]]#--[[:space:]]#*)==0\;33=2\;37'
|
||||
zstyle ':completion:*:*:ccs:*' group-name ''
|
||||
zstyle ':completion:*:*:ccs:*:descriptions' format $'\n%B%F{yellow}── %d ──%f%b'
|
||||
zstyle ':completion:*:*:ccs:*' list-separator ' -- '
|
||||
zstyle ':completion:*:*:ccs:*' list-rows-first true
|
||||
zstyle ':completion:*:*:ccs:*' menu select
|
||||
|
||||
_ccs() {
|
||||
local -a commands proxy_profiles settings_profiles_described account_profiles_described cliproxy_variants_described
|
||||
local curcontext="$curcontext" state line
|
||||
typeset -A opt_args
|
||||
local current
|
||||
current="${words[CURRENT]}"
|
||||
|
||||
# Define top-level commands
|
||||
commands=(
|
||||
'auth:Manage multiple Claude accounts'
|
||||
'api:Manage API profiles (create/remove)'
|
||||
'cliproxy:Manage CLIProxy variants and binary'
|
||||
'doctor:Run health check and diagnostics'
|
||||
'env:Export env vars for third-party tools'
|
||||
'sync:Sync delegation commands and skills'
|
||||
'update:Update CCS to latest version'
|
||||
)
|
||||
|
||||
# Define CLIProxy hardcoded profiles (OAuth providers)
|
||||
proxy_profiles=(
|
||||
'gemini:Google Gemini (OAuth)'
|
||||
'codex:OpenAI Codex (OAuth)'
|
||||
'agy:Antigravity (OAuth)'
|
||||
'qwen:Qwen Code (OAuth)'
|
||||
'iflow:iFlow (OAuth)'
|
||||
'kiro:Kiro (OAuth)'
|
||||
'ghcp:GitHub Copilot (OAuth)'
|
||||
'claude:Claude Direct (OAuth)'
|
||||
)
|
||||
|
||||
# Define known settings profiles with descriptions
|
||||
local -A profile_descriptions
|
||||
profile_descriptions=(
|
||||
'default' 'Default Claude Sonnet 4.5'
|
||||
'glm' 'GLM-4.6 (cost-optimized)'
|
||||
'kimi' 'Kimi for Coding (long-context)'
|
||||
)
|
||||
|
||||
# Load settings-based profiles from config.json
|
||||
if [[ -f ~/.ccs/config.json ]]; then
|
||||
local -a raw_settings_profiles
|
||||
raw_settings_profiles=(${(f)"$(jq -r '.profiles | keys[]' ~/.ccs/config.json 2>/dev/null)"})
|
||||
|
||||
for profile in $raw_settings_profiles; do
|
||||
local desc="${profile_descriptions[$profile]:-Settings-based profile}"
|
||||
settings_profiles_described+=("${profile}:${desc}")
|
||||
done
|
||||
local -a tokens_before_current
|
||||
if (( CURRENT > 2 )); then
|
||||
tokens_before_current=("${words[@]:2:$((CURRENT-2))}")
|
||||
else
|
||||
tokens_before_current=()
|
||||
fi
|
||||
|
||||
# Load account-based profiles from profiles.json
|
||||
if [[ -f ~/.ccs/profiles.json ]]; then
|
||||
local -a raw_account_profiles
|
||||
raw_account_profiles=(${(f)"$(jq -r '.profiles | keys[]' ~/.ccs/profiles.json 2>/dev/null)"})
|
||||
|
||||
for profile in $raw_account_profiles; do
|
||||
account_profiles_described+=("${profile}:Account-based profile")
|
||||
done
|
||||
fi
|
||||
|
||||
# Load cliproxy variants from config.json
|
||||
if [[ -f ~/.ccs/config.json ]]; then
|
||||
local -a raw_cliproxy_variants
|
||||
raw_cliproxy_variants=(${(f)"$(jq -r '.cliproxy | keys[]' ~/.ccs/config.json 2>/dev/null)"})
|
||||
|
||||
for variant in $raw_cliproxy_variants; do
|
||||
cliproxy_variants_described+=("${variant}:CLIProxy variant")
|
||||
done
|
||||
fi
|
||||
|
||||
_arguments -C \
|
||||
'(- *)'{-h,--help}'[Show help message]' \
|
||||
'(- *)'{-v,--version}'[Show version information]' \
|
||||
'(- *)'{-sc,--shell-completion}'[Install shell completion]' \
|
||||
'1: :->command' \
|
||||
'*:: :->args'
|
||||
|
||||
case $state in
|
||||
command)
|
||||
_describe -t commands 'commands' commands
|
||||
_describe -t proxy-profiles 'CLIProxy profiles' proxy_profiles
|
||||
_describe -t model-profiles 'model profiles' settings_profiles_described
|
||||
_describe -t account-profiles 'account profiles' account_profiles_described
|
||||
_describe -t cliproxy-variants 'CLIProxy variants' cliproxy_variants_described
|
||||
;;
|
||||
|
||||
args)
|
||||
case $words[1] in
|
||||
auth)
|
||||
_ccs_auth
|
||||
;;
|
||||
api)
|
||||
_ccs_api
|
||||
;;
|
||||
cliproxy)
|
||||
_ccs_cliproxy
|
||||
;;
|
||||
update)
|
||||
_arguments \
|
||||
'--force[Force reinstall current version]' \
|
||||
'--beta[Install from dev channel]' \
|
||||
'--dev[Install from dev channel]' \
|
||||
'(- *)'{-h,--help}'[Show help]'
|
||||
;;
|
||||
doctor)
|
||||
_arguments \
|
||||
'(- *)'{-h,--help}'[Show help for doctor command]'
|
||||
;;
|
||||
env)
|
||||
_arguments \
|
||||
'--format[Output format]:format:(openai anthropic raw)' \
|
||||
'--shell[Shell syntax]:shell:(auto bash zsh fish powershell)' \
|
||||
'(- *)'{-h,--help}'[Show help]' \
|
||||
'1:profile:($proxy_profiles ${(k)settings_profiles_described})'
|
||||
;;
|
||||
gemini|codex|agy|qwen)
|
||||
_arguments \
|
||||
'--auth[Authenticate only]' \
|
||||
'--config[Change model configuration]' \
|
||||
'--logout[Clear authentication]' \
|
||||
'--headless[Headless auth (for SSH)]' \
|
||||
'(- *)'{-h,--help}'[Show help]'
|
||||
;;
|
||||
--shell-completion|-sc)
|
||||
_arguments \
|
||||
'--bash[Install for bash]' \
|
||||
'--zsh[Install for zsh]' \
|
||||
'--fish[Install for fish]' \
|
||||
'--powershell[Install for PowerShell]'
|
||||
;;
|
||||
*)
|
||||
_message 'Claude CLI arguments'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
local -a suggestions
|
||||
suggestions=("${(@f)$(__ccs_completion_run "${current}" "${tokens_before_current[@]}")}")
|
||||
compadd -- "${suggestions[@]}"
|
||||
}
|
||||
|
||||
_ccs_api() {
|
||||
local curcontext="$curcontext" state line
|
||||
typeset -A opt_args
|
||||
__ccs_completion_run() {
|
||||
local current="$1"
|
||||
shift || true
|
||||
|
||||
local -a api_commands settings_profiles
|
||||
|
||||
api_commands=(
|
||||
'create:Create new API profile (interactive)'
|
||||
'list:List all API profiles'
|
||||
'remove:Remove an API profile'
|
||||
)
|
||||
|
||||
if [[ -f ~/.ccs/config.json ]]; then
|
||||
settings_profiles=(${(f)"$(jq -r '.profiles | keys[]' ~/.ccs/config.json 2>/dev/null)"})
|
||||
local script_path script_dir repo_root repo_cli
|
||||
script_path="${(%):-%N}"
|
||||
script_dir="${script_path:A:h}"
|
||||
repo_root="${script_dir:h:h}"
|
||||
repo_cli="${repo_root}/dist/ccs.js"
|
||||
if [[ ! -f "${repo_cli}" ]]; then
|
||||
repo_cli="${repo_root}/bin/ccs.js"
|
||||
fi
|
||||
if [[ -f "${repo_cli}" ]]; then
|
||||
node "${repo_cli}" __complete --shell zsh --current "${current}" -- "$@" 2>/dev/null
|
||||
return 0
|
||||
fi
|
||||
|
||||
_arguments -C \
|
||||
'(- *)'{-h,--help}'[Show help for api commands]' \
|
||||
'1: :->subcommand' \
|
||||
'*:: :->subargs'
|
||||
|
||||
case $state in
|
||||
subcommand)
|
||||
_describe -t api-commands 'api commands' api_commands
|
||||
;;
|
||||
|
||||
subargs)
|
||||
case $words[1] in
|
||||
create)
|
||||
_arguments \
|
||||
'1:profile name:' \
|
||||
'--base-url[API base URL]:url:' \
|
||||
'--api-key[API key]:key:' \
|
||||
'--model[Default model]:model:' \
|
||||
'--force[Overwrite existing profile]' \
|
||||
{--yes,-y}'[Skip prompts]'
|
||||
;;
|
||||
list)
|
||||
;;
|
||||
remove|delete|rm)
|
||||
_arguments \
|
||||
'1:profile:($settings_profiles)' \
|
||||
{--yes,-y}'[Skip confirmation]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_ccs_cliproxy() {
|
||||
local curcontext="$curcontext" state line
|
||||
typeset -A opt_args
|
||||
|
||||
local -a cliproxy_commands cliproxy_variants providers
|
||||
|
||||
cliproxy_commands=(
|
||||
'create:Create new CLIProxy variant profile'
|
||||
'list:List all CLIProxy variant profiles'
|
||||
'remove:Remove a CLIProxy variant profile'
|
||||
)
|
||||
|
||||
providers=(gemini codex agy qwen)
|
||||
|
||||
if [[ -f ~/.ccs/config.json ]]; then
|
||||
cliproxy_variants=(${(f)"$(jq -r '.cliproxy | keys[]' ~/.ccs/config.json 2>/dev/null)"})
|
||||
if (( $+commands[ccs] )); then
|
||||
ccs __complete --shell zsh --current "${current}" -- "$@" 2>/dev/null
|
||||
fi
|
||||
|
||||
_arguments -C \
|
||||
'(- *)'{-h,--help}'[Show help for cliproxy commands]' \
|
||||
'--install[Install specific version]:version:' \
|
||||
'--latest[Install latest version]' \
|
||||
'1: :->subcommand' \
|
||||
'*:: :->subargs'
|
||||
|
||||
case $state in
|
||||
subcommand)
|
||||
_describe -t cliproxy-commands 'cliproxy commands' cliproxy_commands
|
||||
;;
|
||||
|
||||
subargs)
|
||||
case $words[1] in
|
||||
create)
|
||||
_arguments \
|
||||
'1:variant name:' \
|
||||
'--provider[Provider name]:provider:($providers)' \
|
||||
'--model[Model name]:model:' \
|
||||
'--force[Overwrite existing variant]' \
|
||||
{--yes,-y}'[Skip prompts]'
|
||||
;;
|
||||
list|ls)
|
||||
;;
|
||||
remove|delete|rm)
|
||||
_arguments \
|
||||
'1:variant:($cliproxy_variants)' \
|
||||
{--yes,-y}'[Skip confirmation]'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_ccs_auth() {
|
||||
local curcontext="$curcontext" state line
|
||||
typeset -A opt_args
|
||||
|
||||
local -a auth_commands account_profiles
|
||||
|
||||
auth_commands=(
|
||||
'create:Create new profile and login'
|
||||
'list:List all saved profiles'
|
||||
'show:Show profile details'
|
||||
'remove:Remove saved profile'
|
||||
'default:Set default profile'
|
||||
)
|
||||
|
||||
if [[ -f ~/.ccs/profiles.json ]]; then
|
||||
account_profiles=(${(f)"$(jq -r '.profiles | keys[]' ~/.ccs/profiles.json 2>/dev/null)"})
|
||||
fi
|
||||
|
||||
_arguments -C \
|
||||
'(- *)'{-h,--help}'[Show help for auth commands]' \
|
||||
'1: :->subcommand' \
|
||||
'*:: :->subargs'
|
||||
|
||||
case $state in
|
||||
subcommand)
|
||||
_describe -t auth-commands 'auth commands' auth_commands
|
||||
;;
|
||||
|
||||
subargs)
|
||||
case $words[1] in
|
||||
create)
|
||||
_message 'new profile name'
|
||||
_arguments '--force[Allow overwriting existing profile]'
|
||||
;;
|
||||
list)
|
||||
_arguments \
|
||||
'--verbose[Show additional details]' \
|
||||
'--json[Output in JSON format]'
|
||||
;;
|
||||
show)
|
||||
_arguments \
|
||||
'1:profile:($account_profiles)' \
|
||||
'--json[Output in JSON format]'
|
||||
;;
|
||||
remove)
|
||||
_arguments \
|
||||
'1:profile:($account_profiles)' \
|
||||
{--yes,-y}'[Skip confirmation prompts]'
|
||||
;;
|
||||
default)
|
||||
_arguments '1:profile:($account_profiles)'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_ccs "$@"
|
||||
Reference in new issue
Block a user