Skip to content

Shell completions for Bash, Zsh #128#251

Open
Sravan1011 wants to merge 16 commits into
usemoss:mainfrom
Sravan1011:main
Open

Shell completions for Bash, Zsh #128#251
Sravan1011 wants to merge 16 commits into
usemoss:mainfrom
Sravan1011:main

Conversation

@Sravan1011

@Sravan1011 Sravan1011 commented May 18, 2026

Copy link
Copy Markdown
Contributor

This PR implements shell completions for the moss CLI, addressing #128. It introduces a new moss completions command group that generates native tab-completion scripts for Bash and Zsh, greatly improving command discoverability for power users.
It also introduces dynamic index name completion, which queries the Moss API live during tab-completion so users can auto-complete their actual index names.
Fixes #128

Features Added

  • moss completions bash|zsh: Outputs valid shell completion scripts.
  • moss completions install: Auto-detects the user's shell and safely installs the completion block to ~/.bashrc or ~/.zshrc.
  • moss completions show: Prints the script for the current shell without installing.
  • Dynamic Index Autocompletion: Pressing <TAB> after moss query, moss index get, moss index delete, or any moss doc subcommand will fetch and list available index names using the configured credentials.

Technical Details & Design Decisions

  • Typer Compatibility: Disabled Typer's hidden --install-completion flags (add_completion=False initially, but reverted to True to preserve Click's env-var processing). We patch the generated Click scripts so their instruction_shell format matches what Typer expects at runtime.
  • Graceful Degradation: The dynamic complete_index_name callback handles missing credentials and API errors by silently returning an empty list, ensuring tab-completion never errors out or blocks the user's terminal.
  • Test Coverage: Added 16 new unit tests in test_completions.py covering script generation, installation idempotency, and the dynamic completion callback behavior.

Testing

  • pytest tests/ (All 40 tests pass)
  • Manually tested in Bash and Zsh.
  • [Link to Loom video demonstrating the tab-completion here]

Open in Devin Review

Sravan1011 and others added 15 commits April 23, 2026 07:55
…and init handler

- Revert moss==1.0.0 back to moss>=1.0.0 to allow patch updates
- Remove unnecessary RuntimeError handling for moss_core in init command
- Remove unnecessary try/except around moss import in version command
- Move _register_moss_commands to module level so app is fully populated for tests
…d lazy-loading

- Set add_completion=False to avoid duplicate completion mechanisms
  (Typer built-in vs custom 'moss completions' command)
- Add test_completions.py with 7 tests covering:
  - Bash/Zsh script output
  - Missing/invalid shell argument errors
  - SDK-dependent command registration (lazy-loading)
  - Help text display
  - Verification that --install-completion/--show-completion are removed

Resolves PR usemoss#192 review comments.
devin-ai-integration[bot]

This comment was marked as resolved.

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@Sravan1011

Copy link
Copy Markdown
Contributor Author

@r4ghu @yatharthk2 can you review this pr

@CoderOMaster CoderOMaster removed the request for review from yatharthk2 June 9, 2026 06:26
@CoderOMaster

Copy link
Copy Markdown
Collaborator

@Sravan1011 can you update your PR for linting fixes? also please attach a 1 min mandatory video showing the working demo

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new moss completions CLI command intended to output Bash/Zsh completion scripts, and adjusts CLI command registration to separate SDK-dependent commands from SDK-independent ones.

Changes:

  • Introduces moss completions <bash|zsh> that prints shell completion scripts (including dynamic index-name completion via moss index list --json).
  • Updates the CLI entrypoint to register version, profile, and completions without importing SDK-dependent modules, and conditionally registers the rest.
  • Adds a new test module covering basic completions output and command registration behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.

File Description
packages/moss-cli/src/moss_cli/main.py Registers completions and refactors command registration to optionally skip SDK-dependent commands.
packages/moss-cli/src/moss_cli/commands/completions.py Implements hard-coded Bash/Zsh completion scripts and the completions command.
packages/moss-cli/tests/test_completions.py Adds tests for completions output, help behavior, and conditional command registration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +5 to +6
from moss_cli.commands.completions import Shell, completions_command
from moss_cli.main import app
Comment on lines +42 to +45
try:
_register_moss_commands()
except ImportError:
pass # moss SDK unavailable; SDK-dependent commands will be absent
esac
}

_moss
Comment on lines +156 to +165
query)
case "$prev" in
--profile|--top-k|-k|--alpha|-a|--filter) ;;
*) COMPREPLY=($(compgen -W "$(_moss_index_names) --profile --top-k -k --alpha -a --filter --cloud -c --interactive -i" -- "$cur")) ;;
esac
;;

completions)
COMPREPLY=($(compgen -W "bash zsh" -- "$cur"))
;;
Comment on lines +367 to +370
_moss_completions_cmd() {
local shells=('bash:Output bash completion script' 'zsh:Output zsh completion script')
_describe 'shell' shells
}
Comment on lines +387 to +394
case $line[1] in
index) _moss_index ;;
doc) _moss_doc ;;
job) _moss_job ;;
profile) _moss_profile ;;
query) _moss_query ;;
completions) _moss_completions_cmd ;;
esac
Comment on lines 15 to 25
app = typer.Typer(
name="moss",
help="Moss Semantic Search CLI",
add_completion=True,
add_completion=False,
no_args_is_help=True,
)

# Register subgroups
app.add_typer(index_app, name="index", help="Manage indexes")
app.add_typer(doc_app, name="doc", help="Manage documents")
app.add_typer(job_app, name="job", help="Track background jobs")
# Register commands that do not depend on the moss SDK
app.command(name="version")(version_command)
app.command(name="completions")(completions_command)
app.add_typer(profile_app, name="profile", help="Manage auth profiles")

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 3 new potential issues.

Open in Devin Review

# eval "$(moss completions bash)"

_moss_index_names() {
moss index list --json 2>/dev/null | python3 -c "

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 _moss_index_names() uses wrong --json flag position, so index name completions always silently fail

The _moss_index_names() helper in both the bash and zsh completion scripts invokes moss index list --json, but --json is a group-level option defined on the top-level @app.callback() (packages/moss-cli/src/moss_cli/main.py:64). Click's MultiCommand has allow_interspersed_args=False, so group-level options must appear before the subcommand name. Running moss index list --json causes Click to pass --json down to the list command, which doesn't recognize it, resulting in "Error: No such option: --json" (exit code 2). Because the script redirects stderr to /dev/null and wraps the Python parser in try/except Exception: pass, this fails silently — the function returns nothing, and tab-completion for index names never works. The correct invocation is moss --json index list. This affects every completion that calls _moss_index_names: index get, index delete, doc add/delete/get, and query.

Suggested change
moss index list --json 2>/dev/null | python3 -c "
moss --json index list 2>/dev/null | python3 -c "
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


_moss_index_names() {
local -a names
names=(${(f)"$(moss index list --json 2>/dev/null | python3 -c '

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Zsh _moss_index_names() also uses wrong --json flag position

Same issue as the bash script: the zsh _moss_index_names() function calls moss index list --json but --json must precede the subcommand for Click to parse it as a group-level option. This silently fails because of 2>/dev/null and except Exception: pass, so zsh index name completions never return any results.

Suggested change
names=(${(f)"$(moss index list --json 2>/dev/null | python3 -c '
names=(${(f)"$(moss --json index list 2>/dev/null | python3 -c '
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +42 to +45
try:
_register_moss_commands()
except ImportError:
pass # moss SDK unavailable; SDK-dependent commands will be absent

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Bare except ImportError may silently swallow SDK-present-but-broken import failures

The try/except ImportError block at packages/moss-cli/src/moss_cli/main.py:42-45 catches all ImportError exceptions, not just ModuleNotFoundError for the missing moss package. If the SDK is installed but its API changes (e.g., QueryOptions is removed from moss), then from moss import QueryOptions in search.py:13 would raise ImportError, and the entire set of SDK-dependent commands would silently disappear without any warning. Consider catching ModuleNotFoundError instead, or logging a warning when ImportError is caught but moss is importable.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

[Feature]: Shell completions for Bash, Zsh

3 participants