arc completion generates a tab-completion script for your shell and prints it to stdout. It never writes anywhere on disk — turning the output into a file, or appending it to your shell's startup file, is a step you do yourself.
Captured against arc 2.0.0-beta.48 (commit 5a5316bde, main, 2026-09-10). Run arc --version before copying anything below; the generated script can change between builds.
Usage
arc completion [shell]shell:bash,zsh, orfish. Omit it andarcdetects your shell from$SHELL; if$SHELLis unset, or set to something that isn't one of those three, it falls back tobash:
$ env -i PATH="$PATH" SHELL=/bin/zsh arc completion | head -1
#compdef arc
$ env -i PATH="$PATH" SHELL=/usr/bin/tcsh arc completion | head -1
###-begin-arc-completions-###Generating a script
The three scripts are different lengths — bash has to do the matching and escaping itself, zsh hands most of that to _describe, and fish is a single complete call:
$ arc completion bash | wc -l
86
$ arc completion zsh | wc -l
67
$ arc completion fish | wc -l
14A shell name outside the three choices is rejected the same way any other invalid choice value is — a yargs validation error, exit 5:
$ arc completion nosuchshell
ERROR: Invalid values:
Argument: shell, Given: "nosuchshell", Choices: "bash", "zsh", "fish"(trimmed here — the rest of the block is the same text arc completion --help prints)
Installing it
Each script's own header states how it expects to be installed. arc completion <shell> only prints; it never writes to any of the paths below for you.
bash
arc completion bash >> ~/.bashrcUse ~/.bash_profile instead on macOS, per the comment inside the script. Open a new shell, or source the file, to pick it up.
zsh
arc completion zsh >> ~/.zshrcIf your ~/.zshrc has never run compinit, the script bootstraps it the first time it loads, so you don't add that step separately. It also re-registers itself on every prompt, so a later compinit elsewhere in your setup that rebuilds the completion table doesn't silently drop arc's entry.
fish
mkdir -p ~/.config/fish/completions
arc completion fish > ~/.config/fish/completions/arc.fishThe mkdir -p matters — > does not create the parent directory, and fish only picks up completion files that are already inside ~/.config/fish/completions/.
What it completes
Press Tab after any of these and the installed script asks the running arc binary what fits, so the answer always matches the binary you actually have, not a snapshot baked in when the script was generated:
- Command names —
arc d<TAB>offersdid,deploy,drain,dsl - Subcommand names —
arc did <TAB>offersinit,check,issue,verify,info,list,issuer --instance/-ivalues — the same namesarc service listwould show, soarc service status -i <TAB>only ever offers an instance you actually have--recipe/--templatevalues —arc blocklet create --recipe <TAB>offers the same choicesarc blocklet create --helplists:basic,blank,blog,agent,minimal-app,agent-workspace,support-community
Anything else — an AFS path in arc afs ls <TAB>, for example — is not one of the slots above, so the script falls through to your shell's ordinary filename completion instead.
How values reach your command line
Instance names and recipe names are not fixed at generation time. Each keystroke queries the arc binary you have installed right now, so a script you generated last week still offers an instance you created five minutes ago.
Insertion is also safe regardless of what characters a value contains. bash quotes every candidate with printf %q before inserting it, so an instance literally named my prod box completes to the three-word-safe my\ prod\ box instead of splitting into separate words, and a name containing shell metacharacters is never handed to the shell unescaped. zsh's _describe carries the same property built in.
Exit codes
| What you ran | Exit code |
|---|---|
arc completion bash / zsh / fish | 0 |
arc completion (no argument, shell detected) | 0 |
arc completion <anything else> | 5 |