Skip to content

feat(cli): add dynamic shell completion for bash, zsh, and fish - #9785

Merged
teknium1 merged 3 commits into
mainfrom
hermes/hermes-7401708c
Apr 14, 2026
Merged

feat(cli): add dynamic shell completion for bash, zsh, and fish#9785
teknium1 merged 3 commits into
mainfrom
hermes/hermes-7401708c

Conversation

@teknium1

Copy link
Copy Markdown
Collaborator

Summary

Salvage of PR #9476 by @leozeli. Closes #2582.

Replaces the hardcoded, stale shell completion stubs in profiles.py with a dynamic generator that walks the live argparse parser tree at runtime. Adds fish shell support in both the completion generator and install.sh.

Changes

From contributor (cherry-picked):

  • New hermes_cli/completion.py — dynamic parser walker generates bash/zsh/fish completions from the live argparse tree. No new dependencies.
  • hermes_cli/main.py — adds missing subcommands to _SUBCOMMANDS in _coalesce_session_name_args(), wires new completion generator, adds fish as a shell choice
  • scripts/install.sh — fish shell PATH setup (fish_add_path, ~/.config/fish/config.fish, skips ~/.profile for fish)
  • 17 tests covering parser walking, output generation, syntax validation, drift prevention

Follow-up fixes (ours):

  • Preserved profile name tab-completion that was lost in the switch from static to dynamic generators:
    • Bash: _hermes_profiles() helper + -p/--profile completion + profile action→name completion
    • Zsh: _hermes_profiles() function + -p/--profile argument spec + profile action case
    • Fish: __hermes_profiles function + -s p -l profile flag + profile action completions
  • Removed dead fallback path in cmd_completion() that imported old static generators from profiles.py
  • 11 additional regression-prevention tests for profile completion

Usage

# Bash — add to ~/.bashrc
eval "\$(hermes completion bash)"

# Zsh — add to ~/.zshrc
eval "\$(hermes completion zsh)"

# Fish — add to config
hermes completion fish | source

Test plan

  • 27 tests pass (26 + 1 skip for fish binary not installed)
  • bash -n syntax validation passes
  • install.sh syntax check passes
  • Existing test_coalesce_session_args.py (17 tests) pass

leozeli and others added 3 commits April 14, 2026 10:26
Replaces the hardcoded completion stubs in profiles.py with a dynamic
generator that walks the live argparse parser tree at runtime.

- New hermes_cli/completion.py: _walk() recursively extracts all
  subcommands and flags; generate_bash/zsh/fish() produce complete
  scripts with nested subcommand support
- cmd_completion now accepts the parser via closure so completions
  always reflect the actual registered commands (including plugin-
  registered ones like honcho)
- completion subcommand now accepts bash | zsh | fish (fish requested
  in issue comments)
- Fix _SUBCOMMANDS set: add honcho, claw, plugins, acp, webhook,
  memory, dump, debug, backup, import, completion, logs so that
  multi-word session names after -c/-r are not broken by these commands
- Add tests/hermes_cli/test_completion.py: 17 tests covering parser
  extraction, alias deduplication, bash/zsh/fish output content,
  bash syntax validation, fish syntax validation, and subcommand
  drift prevention

Tested on Linux (Arch). bash and fish completion verified live.
zsh script passes syntax check (zsh not installed on test machine).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fish users' $SHELL is /usr/bin/fish, which fell into the '*' case and
incorrectly wrote 'export PATH=...' to ~/.bashrc and ~/.zshrc — neither
of which fish reads.

- setup_path(): add fish) case that writes fish_add_path to
  ~/.config/fish/config.fish (fish-compatible PATH syntax)
- setup_path(): skip ~/.profile for fish (not sourced by fish)
- print_success(): show correct reload instruction for fish:
  source ~/.config/fish/config.fish

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The dynamic parser walker from the contributor's commit lost the profile
name tab-completion that existed in the old static generators. This adds
it back for all three shells:

- Bash: _hermes_profiles() helper, -p/--profile completion, profile
  action→name completion (use/delete/show/alias/rename/export)
- Zsh: _hermes_profiles() function, -p/--profile argument spec, profile
  action case with name completion
- Fish: __hermes_profiles function, -s p -l profile flag, profile action
  completions

Also removes the dead fallback path in cmd_completion() that imported
the old static generators from profiles.py (parser is always available
via the lambda wiring) and adds 11 regression-prevention tests for
profile completion.
@eabase

eabase commented Aug 17, 2026

Copy link
Copy Markdown

Big Mistake!

Warning

Never, ever add completion code to .bashrc!

It goes into ~/.local/share/bash-completion/completions/hermes or into .bash_completion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add shell completion support (hermes completion zsh|bash)

3 participants