Shell Completions¶
Axium provides a fast, hierarchical shell completion system for instant command discovery across core commands, Spokes, and Gears.
Overview¶
The completion system offers:
- Fast lookups - Target <50ms response time via cached command registry
- Hierarchical matching - Multi-word commands (
daemon start,env set prod) - Dynamic updates - Automatically refreshes when Spokes/Gears load
- Shell agnostic - Works with zsh, bash, and fish
- No external dependencies - Pure Python implementation
Architecture¶
Shell Tab Press
↓
Shell Completion Function
↓
axium completions list "prefix"
↓
Load Cache (~/.config/axium/completions.json)
↓
Filter Matches
↓
Return to Shell (<50ms total)
Command Registry¶
All commands are registered in a central registry:
# Core commands registered on startup
registry.introspect_typer_app(app, source="core")
# Spoke commands registered when loaded
registry.introspect_typer_app(spoke_app, source="aws-spoke")
# Gear commands registered when loaded
registry.introspect_typer_app(gear_app, source="ansible-gear")
Completion Cache¶
The registry is serialized to ~/.config/axium/completions.json:
{
"commands": [
"bootstrap",
"config edit",
"config path",
"config show",
"daemon logs",
"daemon reload",
"daemon start",
"daemon status",
"daemon stop",
"env get",
"env list",
"env set",
"env show",
"gear list",
"gear perms-edit",
"gear perms-show"
],
"generated_at": "2025-10-13T17:30:00Z",
"command_count": 42
}
Installation¶
Auto-Detection¶
axium completions install
Detects your shell from $SHELL and outputs installation instructions.
Manual Shell Selection¶
# ZSH
axium completions install --shell zsh
# Bash
axium completions install --shell bash
# Fish
axium completions install --shell fish
Shell Integration¶
ZSH¶
Add to ~/.zshrc:
# Axium shell completion for zsh
_axium_completion() {
local prefix current
current="${words[CURRENT]}"
# Build prefix from all axium arguments up to current position
if [[ $CURRENT -eq 2 ]]; then
# Completing first argument after 'axium'
prefix="$current"
else
# Completing subsequent arguments
# Join all previous words (2 to CURRENT-1) with spaces
prefix="${(j: :)words[2,CURRENT-1]}"
# Add trailing space if current word is empty (user pressed space before tab)
[[ -z "$current" ]] && prefix="$prefix " || prefix="$prefix $current"
fi
local -a completions
completions=($(axium completions list --shell zsh "$prefix" 2>/dev/null))
compadd -Q -- "${completions[@]}"
}
compdef _axium_completion axium
# Then run: source ~/.zshrc
Bash¶
Add to ~/.bashrc:
# Axium shell completion for bash
_axium_completion() {
local cur prev words cword
_init_completion || return
COMPREPLY=($(axium completions list --shell bash "$cur" 2>/dev/null))
}
complete -F _axium_completion axium
# Then run: source ~/.bashrc
Fish¶
Create ~/.config/fish/completions/axium.fish:
# Axium shell completion for fish
complete -c axium -f -a '(axium completions list --shell fish (commandline -ct) 2>/dev/null)'
# Completions available immediately
Usage¶
Basic Completion¶
axium <TAB>
# Shows: bootstrap config daemon env gear hud ...
axium d<TAB>
# Completes to: axium daemon
axium daemon <TAB>
# Shows: logs reload start status stop
Hierarchical Completion¶
axium env <TAB>
# Shows: get list set show
axium env s<TAB>
# Shows: set show
axium daemon sta<TAB>
# Completes to: axium daemon start
Multi-Word Commands¶
Cache Management¶
Automatic Regeneration¶
The completion cache regenerates automatically when:
- Spokes are loaded, reloaded, or unloaded
- Gears are loaded or unloaded
- Daemon configuration is reloaded
- Command registry changes
Manual Refresh¶
# Force regeneration
axium completions refresh
# Output:
✓ Regenerated completion cache (42 commands)
Cache Location¶
Viewing Cache¶
# List all completions
axium completions list ""
# Filter completions
axium completions list "env"
# Output:
env get
env list
env set
env show
# Multi-word filter
axium completions list "daemon s"
# Output:
daemon start
daemon status
Implementation Details¶
Completion Algorithm¶
def get_completions(prefix: str) -> list[str]:
"""
Get matching completions for prefix.
Args:
prefix: Command prefix to match (e.g., "env", "daemon s")
Returns:
List of matching command strings
"""
cache = load_completion_cache()
if not prefix:
# Return all commands
return cache
# Filter commands that start with prefix
prefix_lower = prefix.lower()
matches = [
cmd for cmd in cache
if cmd.lower().startswith(prefix_lower)
]
return sorted(matches)
Performance¶
- Cache load: ~5-10ms
- Filtering: ~5-10ms for 100+ commands
- Total time: ~20-30ms typical, <50ms target
Registry Structure¶
Commands stored with metadata:
{
"daemon start": {
"source": "core",
"help": "Start the Axium daemon process",
"path": ["daemon", "start"]
},
"spoke list": {
"source": "core",
"help": "List all installed Spokes",
"path": ["spoke", "list"]
},
"aws-whoami": {
"source": "aws-spoke",
"help": "Show current AWS identity",
"path": ["aws-whoami"]
}
}
Troubleshooting¶
Completions Not Working¶
Check installation:
# Verify completion function is defined
typeset -f _axium_completion # zsh
declare -f _axium_completion # bash
# Reload shell config
source ~/.zshrc # or ~/.bashrc
Check cache exists:
Slow Completions¶
Check response time:
If slow: - Check cache file size (should be <100KB) - Verify no network calls in completion path - Check for slow disk I/O
Missing Commands¶
Regenerate cache:
Check command registered:
Check registry:
from axium.core import registry
commands = registry.list_all_commands()
print([cmd for cmd in commands if "my-command" in cmd])
Duplicate Completions¶
Check for duplicate registrations:
Solution: - Ensure spokes/gears don't register same command - Check for naming conflicts
Advanced Usage¶
Custom Completion in Spokes¶
Spokes can register commands that appear in completions:
def register(app, events):
@app.command("my-spoke-cmd")
def my_cmd():
"""This appears in completions."""
pass
# Completion cache auto-regenerates when spoke loads
Completion Filtering¶
# Show only env commands
axium completions list "env" | wc -l
# 4
# Show only daemon commands
axium completions list "daemon" | wc -l
# 5
# Show all commands
axium completions list "" | wc -l
# 42
Debugging Completions¶
# Enable debug logging
AXIUM_DEBUG=1 axium completions list "env" 2>&1 | grep completion
# Check cache generation
AXIUM_DEBUG=1 axium completions refresh
Comparison with Typer Built-in Completions¶
| Feature | Axium Completions | Typer Built-in |
|---|---|---|
| Speed | <50ms (cached) | Slow (shell startup) |
| Multi-word | ✓ | ✗ |
| Dynamic updates | ✓ Auto | Manual |
| Spoke/Gear discovery | ✓ | ✗ |
| Shell support | zsh, bash, fish | zsh, bash |
| Installation | Simple | Complex |
API Reference¶
CLI Commands¶
# Install completions (print instructions)
axium completions install [--shell SHELL]
# List matching completions
axium completions list [PREFIX]
# Regenerate cache
axium completions refresh
Python API¶
from axium.core.completions import (
generate_completion_cache,
load_completion_cache,
get_completions
)
# Generate cache
success = generate_completion_cache()
# Load cache
commands = load_completion_cache() # list[str]
# Get matches
matches = get_completions("env") # ["env get", "env list", ...]
See Also¶
- CLI Reference - Complete command documentation
- Spokes - Plugin system that extends completions
- Gears - Privileged extensions in completions
- Command Registry - Central command tracking