#compdef claude # Dynamic completion functions # Directories Claude Code keeps its state in (agents, plugins, sessions). # CLAUDE_CONFIG_DIR replaces the default location when it is set. _claude_state_dirs() { if [[ -n "$CLAUDE_CONFIG_DIR" ]]; then print -r -- "$CLAUDE_CONFIG_DIR" else print -l -- "$HOME/.claude" "$HOME/.config/claude" fi } # JSON files that may hold MCP server definitions. _claude_config_files() { if [[ -n "$CLAUDE_CONFIG_DIR" ]]; then print -l -- "$CLAUDE_CONFIG_DIR/.claude.json" "$CLAUDE_CONFIG_DIR/mcp.json" else print -l -- "$HOME/.claude.json" "$HOME/.claude/mcp.json" "$HOME/.config/claude/mcp.json" fi } _claude_mcp_servers() { local config_file local -a server_list # Parse config files using grep/sed (no external dependencies) for config_file in ${(f)"$(_claude_config_files)"}; do [[ -f "$config_file" ]] || continue # Find entries with "command", "type", or "url" (MCP server signature) server_list+=(${(f)"$(grep -B 1 -E '"(command|type|url)"[[:space:]]*:' "$config_file" 2>/dev/null | \ grep -E '"[^"]+": \{' | sed 's/.*"\([^"]*\)".*/\1/' | grep -v '/')"}) done server_list=(${(u)server_list}) # Fallback to claude mcp list if [[ ${#server_list[@]} -eq 0 ]]; then server_list=(${(f)"$(claude mcp list 2>/dev/null | sed -n 's/^\([^:]*\):.*/\1/p' | grep -v '^Checking')"}) fi compadd -a server_list } _claude_installed_plugins() { local -a plugins local state_dir manifest # Installed plugins are "name@marketplace" keys in # plugins/installed_plugins.json - the directories beside it are caches. for state_dir in ${(f)"$(_claude_state_dirs)"}; do manifest="$state_dir/plugins/installed_plugins.json" [[ -f "$manifest" ]] || continue plugins+=(${(f)"$(grep -oE '"[^"]+@[^"]+"[[:space:]]*:' "$manifest" 2>/dev/null | \ sed 's/[[:space:]]*:$//; s/"//g')"}) done plugins=(${(u)plugins}) compadd -a plugins } _claude_sessions() { setopt localoptions extendedglob local -a sessions project_dirs local state_dir project_dir cwd session_file uuid summary # Sessions live under /projects/. # A symlinked working directory is recorded under its resolved path, so # try that as well as the one the shell reports. for cwd in "$PWD" "${PWD:A}"; do project_dirs+=(${${cwd//\//-}//./-}) done project_dirs=(${(u)project_dirs}) for state_dir in ${(f)"$(_claude_state_dirs)"}; do for project_dir in $project_dirs; do [[ -d "$state_dir/projects/$project_dir" ]] || continue # Newest first, capped so completion stays instant on long-lived projects for session_file in ${state_dir}/projects/${project_dir}/*.jsonl(Nom[1,20]); do uuid=${session_file:t:r} [[ $uuid == [0-9a-f](#c8)-[0-9a-f](#c4)-[0-9a-f](#c4)-[0-9a-f](#c4)-[0-9a-f](#c12) ]] || continue # Describe each session by the name it was given (/rename or --name), # else by the first thing you typed in it. A name is appended near the # end of the transcript and the first message sits at the start, so # only those ends are read - these files grow into the megabytes. summary=$(tail -c 100000 "$session_file" 2>/dev/null | \ grep -o '"customTitle":"[^"]*"' 2>/dev/null | tail -1 | \ sed 's/^"customTitle":"//; s/"$//') if [[ -z $summary ]]; then summary=$(head -c 200000 "$session_file" 2>/dev/null | \ grep -m 1 -o '"role":"user","content":"[^"]\{1,60\}' 2>/dev/null | \ sed 's/.*"content":"//; s/\\n/ /g; s/\\*$//') fi sessions+=("${uuid}:${summary:-no description}") done done done _describe -t sessions 'session' sessions } _claude_agent_names() { local -a agents agent_dirs local state_dir agent_dir agent_file name # User-level and project-level agent definitions for state_dir in ${(f)"$(_claude_state_dirs)"}; do agent_dirs+=("$state_dir/agents") done agent_dirs+=(.claude/agents) for agent_dir in $agent_dirs; do [[ -d "$agent_dir" ]] || continue for agent_file in ${agent_dir}/*.md(N); do # Prefer the name declared in the front matter, fall back to the filename name=$(sed -n '1,10{s/^name:[[:space:]]*\([^[:space:]]*\).*/\1/p;}' "$agent_file" 2>/dev/null | head -1) agents+=(${name:-${agent_file:t:r}}) done done agents=(${(u)agents}) compadd -a agents } _claude_background_sessions() { local -a sessions state_files local -A names states local state_dir state_file line id rest # Background sessions (`claude --bg`) live in /jobs//, where # is the short id that attach, logs, stop, respawn and rm take. for state_dir in ${(f)"$(_claude_state_dirs)"}; do # Newest first state_files=(${state_dir}/jobs/*/state.json(Nom)) (( ${#state_files} )) || continue # One grep for all of them; the first "name" and "state" it reports for a # file are that file's top-level ones names=() states=() for line in ${(f)"$(grep -HoE '"(name|state)"[[:space:]]*:[[:space:]]*"[^"]*"' $state_files 2>/dev/null)"}; do id=${${line%%/state.json:*}:t} rest=${line#*/state.json:} case $rest in \"name\"*) [[ -z $names[$id] ]] && names[$id]=${${rest#*:*\"}%\"} ;; \"state\"*) [[ -z $states[$id] ]] && states[$id]=${${rest#*:*\"}%\"} ;; esac done for state_file in $state_files; do id=${state_file:h:t} sessions+=("${id}:${names[$id]:-no name}${states[$id]:+ (${states[$id]})}") done done _describe -t sessions 'background session' sessions } _claude_model_names() { local -a models config_files local state_dir config_file # Aliases always resolve to the latest model of that family models=(default fable opus sonnet haiku) # Full model names the user has already configured for state_dir in ${(f)"$(_claude_state_dirs)"}; do config_files+=("$state_dir/settings.json" "$state_dir/settings.local.json") done config_files+=(${(f)"$(_claude_config_files)"}) for config_file in $config_files; do [[ -f "$config_file" ]] || continue models+=(${(f)"$(grep -oE '"(model|fallbackModel)"[[:space:]]*:[[:space:]]*"[^"]+"' "$config_file" 2>/dev/null | \ sed 's/.*:[[:space:]]*"\([^"]*\)"/\1/')"}) done # Remove duplicates models=(${(u)models}) compadd -a models } _claude() { local curcontext="$curcontext" state line typeset -A opt_args local -a main_commands main_commands=( 'mcp:Configure and manage MCP servers' 'plugin:Manage Claude Code plugins' 'agents:Manage background agents' 'attach:Open a background session in this terminal' 'logs:Print the recent terminal output of a background session' 'stop:Stop a background session (its conversation is kept)' 'respawn:Restart a background session so it runs the current Claude Code version' 'rm:Delete a background session, and its worktree when that is safe' 'auth:Manage authentication' 'auto-mode:Inspect or reset auto mode classifier configuration' 'gateway:Run the enterprise auth/telemetry gateway' 'import:Import config from another AI coding agent into Claude Code' 'project:Manage Claude Code project state' 'purge:Delete all Claude Code state for a project (transcripts, tasks, file history, config entry)' 'ultrareview:Run a cloud-hosted multi-agent code review and print the findings' 'setup-token:Set up long-term authentication token (requires Claude subscription)' 'doctor:Health check for Claude Code auto-updater' 'update:Check for and install updates' 'install:Install Claude Code native build' ) local -a main_options main_options=( '(-d --debug)'{-d,--debug}'[Enable debug mode with optional category filtering (e.g., "api,hooks" or "!statsig,!file")]:filter:' '--verbose[Override verbose mode setting from config file]' '(-p --print)'{-p,--print}'[Print response and exit (for use with pipes). Note: use only in trusted directories]' '--output-format[Output format (with --print): "text" (default), "json" (single result), or "stream-json" (real-time streaming)]:format:(text json stream-json)' '--json-schema[JSON schema for structured output validation]:schema:' '--include-partial-messages[Include partial message chunks as they arrive (with --print and --output-format=stream-json)]' '--input-format[Input format (with --print): "text" (default) or "stream-json" (real-time streaming input)]:format:(text stream-json)' '--mcp-debug[\[Deprecated. Use --debug instead\] Enable MCP debug mode (shows MCP server errors)]' '--dangerously-skip-permissions[Bypass all permission checks. Recommended only for sandboxes without internet access]' '--allow-dangerously-skip-permissions[Enable option to bypass permission checks without enabling by default]' '--restricted[Restricted mode: remove the tools that run commands or code and WebFetch, ignore user/project/local settings, and confine file tools to the working directories]' '--max-budget-usd[Maximum dollar amount to spend on API calls (--print only)]:amount:' '--replay-user-messages[Re-send user messages from stdin on stdout for confirmation]' '--allowed-tools[Comma or space-separated list of allowed tool names (e.g., "Bash(git:*) Edit")]:tools:' '--allowedTools[Comma or space-separated list of allowed tool names (camelCase format)]:tools:' '--tools[Specify list of available tools from built-in set. Print mode only]:tools:' '--disallowed-tools[Comma or space-separated list of disallowed tool names (e.g., "Bash(git:*) Edit")]:tools:' '--disallowedTools[Comma or space-separated list of disallowed tool names (camelCase format)]:tools:' '--mcp-config[Load MCP servers from JSON file or string (space-separated)]:configs:' '--system-prompt[System prompt to use for session]:prompt:' '--system-prompt-file[Read system prompt from a file]:file:_files' '--append-system-prompt[Append system prompt to default system prompt]:prompt:' '--append-system-prompt-file[Read system prompt from a file and append to the default system prompt]:file:_files' '--system-prompt-snapshot[Record the system prompt once per conversation and reuse it verbatim on every request and resume (on, the default) or render it fresh every request (off)]:mode:(on off)' '--permission-mode[Permission mode to use for session]:mode:(acceptEdits auto bypassPermissions manual dontAsk plan)' '--permission-prompts[Who answers permission prompts with --print: "host" (the SDK host or --permission-prompt-tool) or "none" (anything that would prompt is denied)]:target:(host none)' '--permission-prompt-tool[MCP tool to use for permission prompts (--print only)]:tool:' '(-c --continue)'{-c,--continue}'[Continue the most recent conversation]' '(-r --resume)'{-r,--resume}'[Resume a conversation - specify session ID or select interactively]:sessionId:_claude_sessions' '--fork-session[Create new session ID instead of reusing original session ID when resuming (with --resume or --continue)]' '--no-session-persistence[Disable session persistence - sessions will not be saved (--print only)]' '--model[Model for current session. Specify alias for latest model (e.g., '\''sonnet'\'' or '\''opus'\'')]:model:_claude_model_names' '--agent[Agent for the current session. Overrides the '\''agent'\'' setting]:agent:_claude_agent_names' '--betas[Beta headers to include in API requests (API key users only)]:betas:' '--fallback-model[Enable automatic fallback to specified model when default model is overloaded (--print only)]:model:_claude_model_names' '--settings[Path to settings JSON file or JSON string to load additional settings]:file-or-json:_files' '--add-dir[Additional directories to allow tool access]:directories:_directories' '--ide[Auto-connect to IDE on startup if exactly one valid IDE is available]' '--desktop[Open in the Claude Desktop app instead of the terminal (with --continue or --resume to pick the session)]' '--strict-mcp-config[Use only MCP servers from --mcp-config and ignore all other MCP settings]' '--session-id[Specific session ID to use for conversation (must be valid UUID)]:uuid:' '--agents[JSON object defining custom agents]:json:' '--setting-sources[Comma-separated list of setting sources to load (user, project, local)]:sources:' '--plugin-dir[Directory to load plugins from for this session only (repeatable)]:paths:_directories' '--disable-slash-commands[Disable all slash commands]' '(--bg --background)'{--bg,--background}'[Start the session as a background agent and return immediately]' '(-w --worktree)'{-w,--worktree}'[Create a new git worktree for this session (optionally specify a name)]::name:' '--tmux=-[Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; --tmux=classic for traditional tmux]::mode:(classic)' '(-n --name)'{-n,--name}'[Set a display name for this session]:name:' '--effort[Effort level for the current session]:level:(low medium high xhigh max)' '--autocompact[Auto-compact window size (auto, or 100k-1M tokens)]:size:(auto)' '--debug-file[Write debug logs to a specific file path (implicitly enables debug mode)]:path:_files' '--from-pr[Resume a session linked to a PR by number/URL, or open interactive picker]::value:' '--teleport[Resume a teleport session, optionally specify session ID]::session:' '--cloud[Create a cloud session with the given description, or attach to an existing one by session ID or claude.ai/code URL]::description-or-session:' '--environment[Create a new cloud session that runs on the given self-hosted environment (ccpool_...)]:environment_id:' '--remote-control[Start an interactive session with Remote Control enabled (optionally named)]::name:' '--remote-control-session-name-prefix[Prefix for auto-generated Remote Control session names]:prefix:' '--chrome[Enable Claude in Chrome integration]' '--no-chrome[Disable Claude in Chrome integration]' '--plugin-url[Fetch a plugin .zip from a URL for this session only (repeatable)]:url:' '--file[File resources to download at startup (format: file_id:relative_path)]:specs:' '--prompt-suggestions[Enable prompt suggestions (emits a predicted next prompt in print/SDK mode)]::value:(true false 1 0 yes no on off)' '--forward-subagent-text[Forward subagent text and thinking blocks as messages (with --print and stream-json)]' '--include-hook-events[Include all hook lifecycle events in the output stream (with stream-json)]' '--exclude-dynamic-system-prompt-sections[Move per-machine sections into the first user message to improve prompt-cache reuse]' '--brief[Enable SendUserMessage tool for agent-to-user communication]' '--safe-mode[Start with all customizations disabled (useful for troubleshooting a broken configuration)]' '--bare[Minimal mode: skip hooks, LSP, plugin sync, attribution, auto-memory, and CLAUDE.md auto-discovery]' '--ax-screen-reader[Render screen-reader friendly output (flat text, no decorative borders or animations)]' '(-v --version)'{-v,--version}'[Output version number]' '(-h --help)'{-h,--help}'[Display help for command]' ) _arguments -C \ $main_options \ '1: :->command' \ '*::arg:->args' case $state in command) _describe -t commands 'claude commands' main_commands ;; args) case $words[1] in mcp) _claude_mcp ;; plugin) _claude_plugin ;; install) _claude_install ;; agents) _claude_agents ;; attach|logs|stop|kill) _arguments \ '(-h --help)'{-h,--help}'[Display help for command]' \ '1:session:_claude_background_sessions' ;; respawn) _claude_respawn ;; rm) _claude_rm ;; auth) _claude_auth ;; auto-mode) _claude_auto_mode ;; gateway) _claude_gateway ;; import) _claude_import ;; project) _claude_project ;; purge) _claude_purge ;; ultrareview) _claude_ultrareview ;; setup-token|doctor|update) _message "no arguments" ;; esac ;; esac } _claude_mcp() { local -a mcp_commands mcp_commands=( 'serve:Start a Claude Code MCP server' 'add:Add an MCP server to Claude Code' 'remove:Remove an MCP server' 'list:List configured MCP servers' 'get:Get MCP server details' 'add-json:Add an MCP server (stdio or SSE) with JSON string' 'add-from-claude-desktop:Import MCP servers from Claude Desktop (Mac and WSL only)' 'reset-project-choices:Reset all approved/rejected project-scoped (.mcp.json) servers in this project' 'login:Authenticate with an MCP server (HTTP, SSE, or claude.ai connector)' 'logout:Clear stored OAuth credentials for an MCP server' 'help:Display help' ) local curcontext="$curcontext" state line typeset -A opt_args _arguments -C \ '(-h --help)'{-h,--help}'[Display help]' \ '1: :->command' \ '*::arg:->args' case $state in command) _describe -t commands 'mcp commands' mcp_commands ;; args) case $words[1] in serve) _arguments \ '(-d --debug)'{-d,--debug}'[Enable debug mode]' \ '--verbose[Override verbose mode setting from config file]' \ '(-h --help)'{-h,--help}'[Display help]' ;; add) _arguments \ '(-s --scope)'{-s,--scope}'[Config scope (local, user, project)]:scope:(local user project)' \ '(-t --transport)'{-t,--transport}'[Transport type (stdio, sse, http)]:transport:(stdio sse http)' \ '(-e --env)'{-e,--env}'[Set environment variable (e.g., -e KEY=value)]:env:' \ '(-H --header)'{-H,--header}'[Set WebSocket header]:header:' \ '--client-id[OAuth client ID for HTTP/SSE servers]:clientId:' \ '--client-secret[Prompt for OAuth client secret (or set MCP_CLIENT_SECRET env var)]' \ '--callback-port[Fixed port for OAuth callback (for servers requiring pre-registered redirect URIs)]:port:' \ '(-h --help)'{-h,--help}'[Display help]' \ '1:name:' \ '2:commandOrUrl:' \ '*:args:' ;; remove) _arguments \ '(-s --scope)'{-s,--scope}'[Config scope (local, user, project) - remove from existing scope if unspecified]:scope:(local user project)' \ '(-h --help)'{-h,--help}'[Display help]' \ '1:name:_claude_mcp_servers' ;; list) _arguments \ '(-h --help)'{-h,--help}'[Display help]' ;; get) _arguments \ '(-h --help)'{-h,--help}'[Display help]' \ '1:name:_claude_mcp_servers' ;; add-json) _arguments \ '(-s --scope)'{-s,--scope}'[Config scope (local, user, project)]:scope:(local user project)' \ '--client-secret[Prompt for OAuth client secret (or set MCP_CLIENT_SECRET env var)]' \ '(-h --help)'{-h,--help}'[Display help]' \ '1:name:' \ '2:json:' ;; add-from-claude-desktop) _arguments \ '(-s --scope)'{-s,--scope}'[Config scope (local, user, project)]:scope:(local user project)' \ '(-h --help)'{-h,--help}'[Display help]' ;; reset-project-choices) _arguments \ '(-h --help)'{-h,--help}'[Display help]' ;; login) _arguments \ '--no-browser[Print the authorization URL instead of opening a browser (for SSH/headless sessions)]' \ '(-h --help)'{-h,--help}'[Display help]' \ '1:name:_claude_mcp_servers' ;; logout) _arguments \ '(-h --help)'{-h,--help}'[Display help]' \ '1:name:_claude_mcp_servers' ;; esac ;; esac } _claude_plugin() { local -a plugin_commands plugin_commands=( 'validate:Validate a plugin or marketplace manifest' 'marketplace:Manage Claude Code marketplaces' 'list:List installed plugins' 'details:Show component inventory and projected token cost for a plugin' 'configure:Show a plugin'\''s options and which are unset, or save values from stdin' 'install:Install a plugin from available marketplaces' 'i:Install a plugin from available marketplaces (short for install)' 'init:Scaffold a new plugin (auto-loads next session)' 'new:Scaffold a new plugin (alias for init)' 'uninstall:Uninstall an installed plugin' 'remove:Uninstall an installed plugin (alias for uninstall)' 'enable:Enable a disabled plugin' 'disable:Disable an enabled plugin' 'update:Update a plugin to the latest version' 'eval:Run eval cases against a plugin and report scored results' 'prune:Remove auto-installed dependencies that are no longer needed' 'autoremove:Remove auto-installed dependencies that are no longer needed (alias for prune)' 'tag:Create a {name}--v{version} git tag for a plugin release' 'test:Run a mod'\''s tests' 'help:Display help' ) local curcontext="$curcontext" state line typeset -A opt_args _arguments -C \ '(-h --help)'{-h,--help}'[Display help]' \ '1: :->command' \ '*::arg:->args' case $state in command) _describe -t commands 'plugin commands' plugin_commands ;; args) case $words[1] in validate) _arguments \ '--strict[Treat warnings as errors (exit 1)]' \ '--json[Output the validation report as JSON (same exit codes)]' \ '(-h --help)'{-h,--help}'[Display help]' \ '1:path:_files' ;; marketplace) _claude_plugin_marketplace ;; install|i) _arguments \ '(-s --scope)'{-s,--scope}'[Installation scope]:scope:(user project local)' \ '--accept-command[Accept the marketplace-declared command whose sha256 a previous --json run reported as shownCommand.sha256]:sha256:' \ '*--config[Set a userConfig option declared in the plugin manifest (repeatable)]:key=value:' \ '--registry[For a package@npm install: resolve and download from this npm registry]:url:' \ '(-y --yes)'{-y,--yes}'[Accept the displayed marketplace-declared command without the confirmation prompt]' \ '--json[Print one machine-readable result line instead of the human message]' \ '(-h --help)'{-h,--help}'[Display help]' \ '1:plugin:' ;; uninstall|remove) _arguments \ '(-s --scope)'{-s,--scope}'[Installation scope]:scope:(user project local)' \ '--keep-data[Preserve the plugin persistent data directory]' \ '--prune[Also remove auto-installed dependencies that are no longer needed]' \ '(-y --yes)'{-y,--yes}'[Skip the --prune confirmation prompt]' \ '--json[Print one machine-readable result line instead of the human message (not with --prune)]' \ '(-h --help)'{-h,--help}'[Display help]' \ '1:plugin:_claude_installed_plugins' ;; enable) _arguments \ '(-s --scope)'{-s,--scope}'[Installation scope]:scope:(user project local)' \ '--json[Print one machine-readable result line instead of the human message]' \ '(-h --help)'{-h,--help}'[Display help]' \ '1:plugin:_claude_installed_plugins' ;; disable) _arguments \ '(-a --all)'{-a,--all}'[Disable all enabled plugins]' \ '(-s --scope)'{-s,--scope}'[Installation scope]:scope:(user project local)' \ '--json[Print one machine-readable result line instead of the human message]' \ '(-h --help)'{-h,--help}'[Display help]' \ '::plugin:_claude_installed_plugins' ;; update) _arguments \ '--accept-command[Accept the marketplace-declared command whose sha256 a previous --json run reported as shownCommand.sha256]:sha256:' \ '(-s --scope)'{-s,--scope}'[Installation scope]:scope:(user project local managed)' \ '(-y --yes)'{-y,--yes}'[Accept the displayed marketplace-declared command without the confirmation prompt]' \ '--json[Print one machine-readable result line instead of the human message]' \ '(-h --help)'{-h,--help}'[Display help]' \ '1:plugin:_claude_installed_plugins' ;; list) _arguments \ '--json[Output as JSON]' \ '--available[Include available plugins from marketplaces (requires --json)]' \ '--data-size[Measure each installed plugin saved data directory, or only the named plugin (requires --json)]::plugin:_claude_installed_plugins' \ '(-h --help)'{-h,--help}'[Display help]' ;; prune|autoremove) _arguments \ '(-s --scope)'{-s,--scope}'[Prune at scope]:scope:(user project local)' \ '--dry-run[List what would be removed without removing]' \ '(-y --yes)'{-y,--yes}'[Skip the confirmation prompt]' \ '(-h --help)'{-h,--help}'[Display help]' ;; configure) _arguments \ '--json[Output as JSON]' \ '--values-stdin[Read option values from stdin as a JSON object of single-line strings; options left out keep their values]' \ '(-h --help)'{-h,--help}'[Display help]' \ '1:plugin:_claude_installed_plugins' ;; details) _arguments \ '(-h --help)'{-h,--help}'[Display help]' \ '1:plugin:_claude_installed_plugins' ;; init|new) _arguments \ '--description[Manifest description]:text:' \ '--author[Author name (default: git config user.name)]:name:' \ '--author-email[Author email (default: git config user.email)]:email:' \ '--with[Components to scaffold as well]:components:' \ '(-f --force)'{-f,--force}'[Overwrite an existing .claude-plugin/ at the target]' \ '(-h --help)'{-h,--help}'[Display help]' \ '1:name:' ;; eval) if [[ $words[2] == init ]]; then _arguments \ '--bare[Write a blank template instead of running the interview]' \ '--eval-dir[Directory below the current directory to write cases into]:dir:_directories' \ '(-i --interactive)'{-i,--interactive}'[Run the authoring interview (requires an interactive terminal)]' \ '(-h --help)'{-h,--help}'[Display help]' \ '::name:' return fi _arguments \ '--case[Filter cases by name glob]:glob:' \ '*--tag[Filter cases by tag (repeatable)]:tag:' \ '--runs[Override per-case runs (default: case.runs, else 3)]:n:' \ '(-j --concurrency)'{-j,--concurrency}'[Run up to n agent runs at once (1-8; default 1)]:n:' \ '--model[Override model for all cases]:model:_claude_model_names' \ '--judge-model[Override LLM-grader model (default: haiku)]:model:_claude_model_names' \ '--max-cost-usd[Hard cost ceiling; abort and report partial results if hit (exit 2)]:usd:' \ '--output-dir[Directory for aggregate-result.json]:dir:_directories' \ '--eval-dir[Directory name (below the plugin) that holds the eval cases]:dir:' \ '--json[Print the full run result as JSON to stdout, or write it to this .json file]::path:_files' \ '--threshold[Exit 1 if any case score is below this threshold (default: 1.0)]:threshold:' \ '*--allow-tools[Operator grant for gated tools (Bash, Write, Edit, WebFetch, mcp__*)]:tools:' \ '(--no-scaffold)--scaffold[Run each case scaffold_script (runs author-supplied bash as you; off by default)]' \ '(--scaffold)--no-scaffold[Explicitly skip scaffold_script]' \ '--trust-plugin[Assert that you trust this plugin and its eval suite, skipping the first-run trust prompt (for CI)]' \ '--ablation[Run a no-plugin baseline arm and report the score delta]:mode:(none with-without)' \ '--mocks[Mock stand-ins for MCP servers, from /mocks/]:mode:(record off)' \ '--allow-real-servers[With --mocks record: also start the real MCP server processes that have no mock]' \ '--keep-temp[Preserve scaffold dirs for debugging]' \ '--verbose[Log per-message trace events to the debug log]' \ '--report[Write the self-contained HTML report to this path instead of the results dir]:path:_files' \ '(--no-publish)--publish-report[Also require publishing the report to claude.ai]' \ '(--publish-report)--no-publish[Keep the HTML report local only; skip publishing it to claude.ai]' \ '(-h --help)'{-h,--help}'[Display help]' \ '::target: _alternative "commands\:eval command\:(init)" "plugins\:installed plugin\:_claude_installed_plugins" "files\:path\:_files"' ;; tag) _arguments \ '--push[Push the tag to --remote after creating it]' \ '--dry-run[Print what would be tagged without creating it]' \ '(-f --force)'{-f,--force}'[Skip the dirty-working-tree and tag-already-exists checks]' \ '(-m --message)'{-m,--message}'[Tag annotation message (use %s for the version)]:msg:' \ '--remote[Remote to push to with --push]:name:' \ '(-h --help)'{-h,--help}'[Display help]' \ '::path:_files' ;; test) _arguments \ '(-h --help)'{-h,--help}'[Display help]' \ '::dir:_directories' ;; esac ;; esac } _claude_plugin_marketplace() { local -a marketplace_commands marketplace_commands=( 'add:Add a marketplace from URL, path, or GitHub repository' 'list:List configured marketplaces' 'remove:Remove a configured marketplace' 'rm:Remove a configured marketplace (alias for remove)' 'update:Update marketplace from source - update all if no name specified' 'help:Display help' ) local curcontext="$curcontext" state line typeset -A opt_args _arguments -C \ '(-h --help)'{-h,--help}'[Display help]' \ '1: :->command' \ '*::arg:->args' case $state in command) _describe -t commands 'marketplace commands' marketplace_commands ;; args) case $words[1] in add) _arguments \ '--sparse[Limit checkout to specific directories via git sparse-checkout (for monorepos)]:paths:' \ '--scope[Where to declare the marketplace]:scope:(user project local)' \ '--json[Print one machine-readable result line as the last line on stdout]' \ '--claudeai[Add the marketplace of this name that claude.ai hosts for you]' \ '(-h --help)'{-h,--help}'[Display help]' \ '1:source:' ;; list) _arguments \ '--json[Output as JSON]' \ '(-h --help)'{-h,--help}'[Display help]' ;; remove|rm) _arguments \ '--scope[Remove the marketplace declaration from a specific settings scope (omit to remove it from every scope)]:scope:(user project local)' \ '--json[Print one machine-readable result line as the last line on stdout]' \ '(-h --help)'{-h,--help}'[Display help]' \ '1:name:' ;; update) _arguments \ '--json[With a marketplace name: print one machine-readable result line as the last line on stdout]' \ '(-h --help)'{-h,--help}'[Display help]' \ '::name:' ;; esac ;; esac } _claude_install() { _arguments \ '--force[Force install even if already installed]' \ '(-h --help)'{-h,--help}'[Display help]' \ '::target:(stable latest)' } _claude_agents() { _arguments \ '*--add-dir[Additional directory to allow tool access to in dispatched sessions]:directory:_directories' \ '--agent[Default agent for sessions dispatched from agent view]:agent:_claude_agent_names' \ '--all[With --json: also include completed background sessions]' \ '--allow-dangerously-skip-permissions[Make bypass-permissions mode available to dispatched sessions]' \ '--cwd[Show only background sessions started under path]:path:_directories' \ '--dangerously-skip-permissions[Alias for --permission-mode bypassPermissions]' \ '--effort[Default effort level for dispatched sessions]:level:(low medium high xhigh max)' \ '--json[Print active sessions as a JSON array and exit]' \ '*--mcp-config[MCP server configuration to apply to dispatched sessions]:config:' \ '--model[Default model for sessions dispatched from agent view]:model:_claude_model_names' \ '--permission-mode[Default permission mode for dispatched sessions]:mode:(acceptEdits auto bypassPermissions manual dontAsk plan)' \ '*--plugin-dir[Load plugins from directory for the agent view and dispatched sessions]:path:_directories' \ '--setting-sources[Comma-separated list of setting sources to load (user, project, local)]:sources:' \ '--settings[Settings file or JSON string to apply]:file-or-json:_files' \ '--strict-mcp-config[Only use MCP servers from --mcp-config in dispatched sessions]' \ '--restricted[Start dispatched sessions in restricted mode]' \ '(-h --help)'{-h,--help}'[Display help for command]' } _claude_auth() { local -a auth_commands auth_commands=( 'login:Sign in to your Anthropic account' 'logout:Log out from your Anthropic account' 'status:Show authentication status' 'help:Display help' ) local curcontext="$curcontext" state line typeset -A opt_args _arguments -C \ '(-h --help)'{-h,--help}'[Display help for command]' \ '1: :->command' \ '*::arg:->args' case $state in command) _describe -t commands 'auth commands' auth_commands ;; args) case $words[1] in login) _arguments \ '--email[Pre-populate email address on the login page]:email:' \ '--sso[Force SSO login flow]' \ '(--claudeai)--console[Use Anthropic Console (API usage billing) instead of Claude subscription]' \ '(--console)--claudeai[Use Claude subscription (default)]' \ '(-h --help)'{-h,--help}'[Display help for command]' ;; status) _arguments \ '(--text)--json[Output as JSON (default)]' \ '(--json)--text[Output as human-readable text]' \ '(-h --help)'{-h,--help}'[Display help for command]' ;; logout) _arguments \ '(-h --help)'{-h,--help}'[Display help for command]' ;; esac ;; esac } _claude_auto_mode() { local -a auto_mode_commands auto_mode_commands=( 'config:Print the effective auto mode config as JSON' 'critique:Get AI feedback on your custom auto mode rules' 'defaults:Print the default auto mode rules as JSON' 'reset:Reset auto mode configuration to the shipped defaults' 'help:Display help' ) local curcontext="$curcontext" state line typeset -A opt_args _arguments -C \ '(-h --help)'{-h,--help}'[Display help for command]' \ '1: :->command' \ '*::arg:->args' case $state in command) _describe -t commands 'auto-mode commands' auto_mode_commands ;; args) case $words[1] in critique) _arguments \ '--model[Override which model is used]:model:_claude_model_names' \ '(-h --help)'{-h,--help}'[Display help for command]' ;; defaults) _arguments \ '--label[Show only rules whose label starts with this prefix (case-insensitive)]:prefix:' \ '(-h --help)'{-h,--help}'[Display help for command]' ;; reset) _arguments \ '(-y --yes)'{-y,--yes}'[Skip the confirmation prompt]' \ '(-h --help)'{-h,--help}'[Display help for command]' ;; config) _arguments \ '(-h --help)'{-h,--help}'[Display help for command]' ;; esac ;; esac } _claude_gateway() { _arguments \ '--config[Path to gateway YAML config]:path:_files' \ '(-h --help)'{-h,--help}'[Display help for command]' } _claude_project() { local -a project_commands project_commands=( 'purge:Delete all Claude Code state for a project (transcripts, tasks, file history, config entry)' 'help:Display help' ) local curcontext="$curcontext" state line typeset -A opt_args _arguments -C \ '(-h --help)'{-h,--help}'[Display help for command]' \ '1: :->command' \ '*::arg:->args' case $state in command) _describe -t commands 'project commands' project_commands ;; args) case $words[1] in purge) _arguments \ '--dry-run[List what would be deleted without deleting anything]' \ '(-y --yes)'{-y,--yes}'[Skip the confirmation prompt]' \ '(-i --interactive)'{-i,--interactive}'[Prompt for each item before deleting]' \ '(1)--all[Purge state for every project (mutually exclusive with a path)]' \ '(-h --help)'{-h,--help}'[Display help for command]' \ '(--all)::path:_directories' ;; esac ;; esac } _claude_purge() { _arguments \ '--dry-run[List what would be deleted without deleting anything]' \ '(-y --yes)'{-y,--yes}'[Skip the confirmation prompt]' \ '(-i --interactive)'{-i,--interactive}'[Prompt for each item before deleting]' \ '(1)--all[Purge state for every project (mutually exclusive with a path)]' \ '(-h --help)'{-h,--help}'[Display help for command]' \ '(--all)::path:_directories' } _claude_ultrareview() { _arguments \ '--json[Print the raw bugs.json payload instead of formatted findings]' \ '--timeout[Maximum minutes to wait for the review to finish (default: 45)]:minutes:' \ '(--no-post)--post[Post the finished review findings to the PR as you (PR targets only; one plain comment, not a review)]' \ '(--post)--no-post[Do not post the findings to the PR (the default)]' \ '(-h --help)'{-h,--help}'[Display help for command]' \ '1:target:' } _claude_respawn() { _arguments \ '(1)--all[Restart every running background session]' \ '(-h --help)'{-h,--help}'[Display help for command]' \ '(--all)::session:_claude_background_sessions' } _claude_rm() { _arguments \ '--discard-unpushed[Also discard the unpushed commits and uncommitted changes of the worktree (pass the commit@worktree-id a previous claude rm reported)]:commit@worktree-id:' \ '--force-remove-worktree[Delete the worktree directory even though the WorktreeRemove hook or git could not remove it (pass the worktree-id a previous claude rm reported)]:worktree-id:' \ '(-h --help)'{-h,--help}'[Display help for command]' \ '1:session:_claude_background_sessions' } _claude_import() { _arguments \ '--dry-run[Show what would be imported without writing anything]' \ '--yes[Skip the interactive picker (on headless surfaces, pass --yes= from the /import preview)]' \ '(-h --help)'{-h,--help}'[Display help for command]' \ '::source:(codex gemini cursor)' } (( $+_comps[claude] )) || compdef _claude claude