Skip to content

feat: add shell completion command for bash, zsh, and fish#168

Open
404-Page-Found wants to merge 23 commits into
mainfrom
67-add-shell-completion-command
Open

feat: add shell completion command for bash, zsh, and fish#168
404-Page-Found wants to merge 23 commits into
mainfrom
67-add-shell-completion-command

Conversation

@404-Page-Found

@404-Page-Found 404-Page-Found commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Add \commit-echo completion\ subcommand that generates shell completion scripts for bash, zsh, and fish shells. Running without arguments prints a help message showing available shells and usage examples.

What changed

  • *\src/commands/completion.ts* — New command file with completion scripts for all three shells:
    • Bash — Uses \complete -F\ with per-subcommand option completion
    • Zsh — Uses #compdef\ with _arguments\ for subcommand and option completions
    • Fish — Uses \complete -c\ with helper functions for subcommands and options
  • *\src/index.ts* — Registered the \completion\ subcommand and updated help text
  • *\ ests/completion-command.test.mjs* — 14 tests covering all shells, subcommands, options, error handling, and case-insensitive input

Motivation

Provides tab-completion for users who want faster CLI interaction without remembering subcommand names and flags. Referenced in #67.

Testing


  • pm run build\ passes with no errors
  • ✅ All 14 new completion tests pass
  • ✅ 206 of 209 total tests pass (3 pre-existing failures unrelated to this change)

Closes #67

Summary by CodeRabbit

  • New Features
    • Added a completion CLI command to generate shell autocompletion scripts for bash, zsh, and fish.
    • Running without a shell argument shows usage/examples; providing a shell outputs the matching completion script.
  • Documentation
    • Updated CLI help text to include completion usage.
  • Bug Fixes
    • Improved validation for unsupported shells with a clear error and non-zero exit status.
    • Shell selection is case-insensitive for bash, zsh, and fish.
  • Tests
    • Added integration tests covering help output, shell-specific completion content/options, and unsupported-shell failure behavior.

Add \commit-echo completion\ subcommand that generates shell completion
scripts for bash, zsh, and fish shells. Running without arguments prints
a help message showing available shells and usage examples.

Closes #67
@404-Page-Found 404-Page-Found added the enhancement New feature or request label Jun 25, 2026
@404-Page-Found 404-Page-Found linked an issue Jun 25, 2026 that may be closed by this pull request
5 tasks
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 30bc8e70-dece-4e17-9c52-c24dde4158a5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a completion CLI subcommand that prints shell-completion scripts for bash, zsh, and fish, shows usage when no shell is provided, and rejects unsupported shell names. The CLI help text and integration tests were updated to cover the new command.

Changes

Shell completion command

Layer / File(s) Summary
Completion scripts and shell contract
src/commands/completion.ts
SupportedShell defines the accepted shells, embedded bash, zsh, and fish completion scripts are added, and getCompletionScript selects the matching script.
Help text and shell validation
src/commands/completion.ts
printHelp() renders the usage text and supported shells, and completionCommand(shell?) prints help, normalizes shell names, rejects unsupported shells, and writes the selected script.
CLI registration
src/index.ts
The top-level CLI imports completionCommand, adds a commit-echo completion example, and registers a completion subcommand with an optional shell argument.
Completion command tests
tests/completion-command.test.mjs
The integration tests cover help output, per-shell script generation, subcommand names, unsupported shell handling, case-insensitive shell names, and expected option flags.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A bunny hopped with terminal cheer,
bash, zsh, and fish all drew near.
One tiny command took flight tonight,
and tab completion feels just right. 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the new shell completion command and the supported shells.
Linked Issues check ✅ Passed The PR implements the requested completion subcommand, shell outputs, help text, and buildability requirements for #67.
Out of Scope Changes check ✅ Passed The changes stay focused on the completion command, its registration, and tests, with no obvious unrelated additions.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/commands/completion.ts`:
- Around line 22-29: The subcommand detection in completion logic is using
COMP_WORDS[1] directly, so leading global flags are mistaken for the command and
subcommand completion never reaches the case branch for actual commands. Update
the completion flow in the completion script to scan COMP_WORDS for the first
non-option token before assigning subcmd, then use that value in the existing
case handling so completions like suggest and history work after flags such as
--no-color.
- Around line 173-176: The fish completion logic for the completion subcommand
is incomplete: __commit_echo_complete_options() only emits --help for
completion, so shell names are never suggested. Update the completion handling
in completion.ts so that when the current command is completion it also returns
bash, zsh, and fish as available options, and ensure the fallback does not
continue surfacing top-level subcommands for this case.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6b6359b2-7c08-4996-a4f6-0e19cf0a76f8

📥 Commits

Reviewing files that changed from the base of the PR and between 2a1bc65 and 5403f30.

📒 Files selected for processing (3)
  • src/commands/completion.ts
  • src/index.ts
  • tests/completion-command.test.mjs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
src/commands/**/*

📄 CodeRabbit inference engine (AGENTS.md)

Organize command implementations in src/commands/ directory

Files:

  • src/commands/completion.ts
src/index.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript for CLI entry point implementation in src/index.ts

Files:

  • src/index.ts
🔇 Additional comments (3)
src/index.ts (1)

13-13: LGTM!

Also applies to: 50-50, 119-126

tests/completion-command.test.mjs (1)

1-109: LGTM!

src/commands/completion.ts (1)

97-133: 🎯 Functional Correctness

Dispatch on the subcommand from _arguments -C
The suggest|history|batch|init|completion cases need to branch on the parsed subcommand, not the current shell command name.

Comment thread src/commands/completion.ts Outdated
Comment thread src/commands/completion.ts Outdated
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 2 unresolved review comments.

Files modified:

  • src/commands/completion.ts

Commit: 6616a03aefc4b5434de9f0ad1d6b22b8873d5197

The changes have been pushed to the 67-add-shell-completion-command branch.

Time taken: 2m 24s

Fixed 1 file(s) based on 2 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@404-Page-Found

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@404-Page-Found

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/commands/completion.ts`:
- Around line 17-19: The completion logic in completion.ts returns global flags
too early, so subcommand-specific options are never considered for commands like
suggest and completion. Update the completion flow in the script generation
logic to determine the active subcmd before the `if [[ "${cur}" == -* ]]`
branch, then build the option list by merging `global_opts` with the matching
subcommand option set before assigning COMPREPLY.
- Around line 107-140: The zsh dispatcher in completion generation is checking
the executable name instead of the subcommand, so the
suggest/history/batch/init/completion cases never match. Update the dispatcher
in completion.ts to branch on the first argument (or otherwise derive the active
subcommand) so the _arguments definitions for those subcommands and the
bash|zsh|fish choices are reached correctly.
- Around line 154-156: The fish completion path is still selecting the second
token as the subcommand, which breaks cases where options appear before the real
command. Update the fish branch in completion dispatch to derive the first
non-option token from commandline output, matching the bash parsing behavior
used elsewhere, and use that value for the switch instead of $cmd[2].
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5abc0206-d6e2-48b1-abbc-ff9a8df13fe5

📥 Commits

Reviewing files that changed from the base of the PR and between 2a1bc65 and 6616a03.

📒 Files selected for processing (3)
  • src/commands/completion.ts
  • src/index.ts
  • tests/completion-command.test.mjs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
src/index.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript for CLI entry point implementation in src/index.ts

Files:

  • src/index.ts
src/commands/**/*

📄 CodeRabbit inference engine (AGENTS.md)

Organize command implementations in src/commands/ directory

Files:

  • src/commands/completion.ts

Comment thread src/commands/completion.ts Outdated
Comment thread src/commands/completion.ts Outdated
Comment thread src/commands/completion.ts Outdated
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 3 unresolved review comments.

Files modified:

  • src/commands/completion.ts

Commit: 268d34d5a51adb432118bc0f90c85c52782fe508

The changes have been pushed to the 67-add-shell-completion-command branch.

Time taken: 1m 33s

Fixed 1 file(s) based on 3 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@404-Page-Found

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@404-Page-Found

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@404-Page-Found

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@404-Page-Found

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/commands/completion.ts (1)

17-20: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Resolve the active bash subcommand before returning flag completions.

Line 17 exits on any -* token, so commit-echo suggest --<TAB> and commit-echo completion --<TAB> never reach the subcommand-specific option sets. Determine subcmd first, then merge global_opts with the active subcommand options before building COMPREPLY.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/commands/completion.ts` around lines 17 - 20, The bash completion logic
is returning too early for any flag-like token, so active subcommand options are
never considered. Update the completion flow in the completion script to resolve
subcmd before handling "-" prefixed input, then combine global_opts with the
current subcommand’s option set before populating COMPREPLY. Keep the early
return only after the merged option list has been used so subcommand-specific
completions work for commit-echo suggest and commit-echo completion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/commands/completion.ts`:
- Around line 107-140: The zsh completion dispatch in completion.ts is still
using a fixed position ($words[2]), so leading global flags cause the subcommand
detection to miss branches like completion. Update the shell-case logic to
derive the first non-option argument from the words array before the case
statement, and keep the existing suggest/history/batch/init/completion handling
keyed off that resolved subcommand symbol.

---

Duplicate comments:
In `@src/commands/completion.ts`:
- Around line 17-20: The bash completion logic is returning too early for any
flag-like token, so active subcommand options are never considered. Update the
completion flow in the completion script to resolve subcmd before handling "-"
prefixed input, then combine global_opts with the current subcommand’s option
set before populating COMPREPLY. Keep the early return only after the merged
option list has been used so subcommand-specific completions work for
commit-echo suggest and commit-echo completion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b7fd8d37-930a-4751-9ef7-6aeed9f90134

📥 Commits

Reviewing files that changed from the base of the PR and between 2a1bc65 and 268d34d.

📒 Files selected for processing (3)
  • src/commands/completion.ts
  • src/index.ts
  • tests/completion-command.test.mjs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
src/index.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript for CLI entry point implementation in src/index.ts

Files:

  • src/index.ts
src/commands/**/*

📄 CodeRabbit inference engine (AGENTS.md)

Organize command implementations in src/commands/ directory

Files:

  • src/commands/completion.ts
🔇 Additional comments (2)
src/index.ts (1)

13-13: LGTM!

Also applies to: 50-50, 119-126

tests/completion-command.test.mjs (1)

1-110: LGTM!

Comment thread src/commands/completion.ts Outdated
In bash, move subcmd resolution before the flag check so that
subcommand-specific options (e.g. suggest --stream) are offered
after the subcommand is typed, instead of only returning global opts.

In zsh, replace the fixed [2] lookup with a loop that finds
the first non-option argument, so leading global flags like --yes
don't break subcommand option dispatch.
@404-Page-Found

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@404-Page-Found

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/commands/completion.ts`:
- Around line 77-84: The zsh completion command list in completion.ts is missing
the top-level help subcommand, causing an inconsistent set of suggestions
compared with the bash and fish completion generators. Update the commands array
used by the zsh completion script to include help alongside init, config,
suggest, history, batch, and completion so commit-echo tab completion advertises
the same commands across shells.
- Around line 167-176: The fish completion generation in completion.ts is using
the wrong printf shape: each entry already includes option and description
separated by a tab, so the format string should emit one string per line instead
of pairing adjacent arguments. Update the fish completion printf blocks in the
completion generation logic, including the block that emits --commit through
--help and the other repeated blocks later in the file, by changing the format
to match the single tab-delimited entries so Fish parses each
candidate/description correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4f75384b-5f04-4c10-b4b9-25b8d472ae79

📥 Commits

Reviewing files that changed from the base of the PR and between 2a1bc65 and d20a9da.

📒 Files selected for processing (3)
  • src/commands/completion.ts
  • src/index.ts
  • tests/completion-command.test.mjs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
tests/**/*.mjs

📄 CodeRabbit inference engine (AGENTS.md)

tests/**/*.mjs: Use Node.js built-in node:test (not Jest or Mocha) for test files under tests/.
Some tests may skip on Windows when platform-specific mock logic is involved.

Files:

  • tests/completion-command.test.mjs
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use .js extensions for all local imports in ESM TypeScript source files, and use import type for type-only imports.

Files:

  • src/commands/completion.ts
  • src/index.ts

Comment on lines +77 to +84
commands=(
'init:Run interactive setup wizard'
'config:View current configuration'
'suggest:Generate commit suggestions'
'history:View learned style profile and recent commit history'
'batch:Process multiple git repositories in batch mode'
'completion:Generate shell completion scripts'
)

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Zsh omits the help subcommand from top-level completions.

Bash and fish both advertise help, but the zsh commands list stops at completion, so commit-echo <TAB> exposes a different command set on zsh than on the other supported shells.

Suggested fix
   commands=(
     'init:Run interactive setup wizard'
     'config:View current configuration'
     'suggest:Generate commit suggestions'
     'history:View learned style profile and recent commit history'
     'batch:Process multiple git repositories in batch mode'
     'completion:Generate shell completion scripts'
+    'help:Display help'
   )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
commands=(
'init:Run interactive setup wizard'
'config:View current configuration'
'suggest:Generate commit suggestions'
'history:View learned style profile and recent commit history'
'batch:Process multiple git repositories in batch mode'
'completion:Generate shell completion scripts'
)
commands=(
'init:Run interactive setup wizard'
'config:View current configuration'
'suggest:Generate commit suggestions'
'history:View learned style profile and recent commit history'
'batch:Process multiple git repositories in batch mode'
'completion:Generate shell completion scripts'
'help:Display help'
)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/commands/completion.ts` around lines 77 - 84, The zsh completion command
list in completion.ts is missing the top-level help subcommand, causing an
inconsistent set of suggestions compared with the bash and fish completion
generators. Update the commands array used by the zsh completion script to
include help alongside init, config, suggest, history, batch, and completion so
commit-echo tab completion advertises the same commands across shells.

Comment thread src/commands/completion.ts Outdated
Comment on lines +167 to +176
printf '%s\\t%s\\n' \\
'--commit\\tCommit the selected suggestion' \\
'--yes\\tAutomatically select the first suggestion' \\
'--verbose\\tPrint diagnostic information' \\
'--model\\tOverride the configured LLM model' \\
'--stream\\tStream suggestions as they are generated' \\
'--dry-run\\tShow the LLM input without generating suggestions' \\
'--no-commit\\tDeprecated alias' \\
'--auto\\tAlias for --yes' \\
'--help\\tDisplay help'

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fish completion entries are emitted with the wrong printf shape.

These arguments already contain option<TAB>description, but the format string still expects two %s values. Fish will pair adjacent entries onto one line, so the generated script does not expose valid candidates/descriptions. The same bug repeats in the later printf blocks on Lines 178-196, 201-208, and 231-236.

Suggested fix
-      printf '%s\t%s\n' \
+      printf '%s\n' \
         '--commit\tCommit the selected suggestion' \
         '--yes\tAutomatically select the first suggestion' \
         '--verbose\tPrint diagnostic information' \

Apply the same format-string change to the other fish completion printf blocks in this file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/commands/completion.ts` around lines 167 - 176, The fish completion
generation in completion.ts is using the wrong printf shape: each entry already
includes option and description separated by a tab, so the format string should
emit one string per line instead of pairing adjacent arguments. Update the fish
completion printf blocks in the completion generation logic, including the block
that emits --commit through --help and the other repeated blocks later in the
file, by changing the format to match the single tab-delimited entries so Fish
parses each candidate/description correctly.

@404-Page-Found

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@codacy-production

Copy link
Copy Markdown

Not up to standards ⛔

🔴 Issues 1 critical

Alerts:
⚠ 1 issue (≤ 0 issues of at least minor severity)

Results:
1 new issue

Category Results
Security 1 critical

View in Codacy

🟢 Metrics 29 complexity · 0 duplication

Metric Results
Complexity 29
Duplication 0

View in Codacy

AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.

Run reviewer

TIP This summary will be updated as you push new changes.

@codacy-production codacy-production Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull Request Overview

The PR introduces shell completion for Bash, Zsh, and Fish. While the core functionality is present, the Zsh implementation is currently broken due to a syntax error (_compdef) and incorrect subcommand detection logic. Additionally, the Fish script provides redundant suggestions after a subcommand is already selected.

Codacy results are not up to standards due to a potential ReDoS vulnerability in the tests. These functional and security issues should be addressed before merging.

About this PR

  • The Zsh completion implementation is significantly more fragile than the Bash and Fish versions. It currently omits the 'help' subcommand and contains logic that fails if global options are provided before a subcommand. A more robust approach for Zsh is required to ensure parity with the other supported shells.

Test suggestions

  • Found recommended test scenario: Running 'completion' without arguments prints help and usage examples
  • Found recommended test scenario: Generating Bash script outputs valid 'complete -F' logic with subcommands
  • Found recommended test scenario: Generating Zsh script outputs valid '#compdef' logic with subcommands
  • Found recommended test scenario: Generating Fish script outputs valid 'complete -c' logic with helper functions
  • Found recommended test scenario: Passing an unsupported shell name (e.g., 'powershell') returns error and exit code 1
  • Found recommended test scenario: Shell name input is case-insensitive
  • Found recommended test scenario: Zsh script includes correct subcommand-specific options (e.g., --commit for suggest)

TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback

Comment thread src/commands/completion.ts Outdated
esac
}

_compdef _commit_echo commit-echo

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 HIGH RISK

The command _compdef is a typo and will cause the script to fail when sourced. The correct Zsh command for associating a completion function is compdef.

Suggested change
_compdef _commit_echo commit-echo
compdef _commit_echo commit-echo

Comment thread src/commands/completion.ts Outdated
_describe 'command' commands
;;
args)
case \$words[2] in

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 HIGH RISK

Subcommand detection in Zsh is currently incorrect. Using *:: in _arguments shifts the words array so that the subcommand is at index 1. Furthermore, using a hardcoded index is fragile if global flags (e.g., --no-color) are passed before the subcommand.

Suggested change
case \$words[2] in
case \$words[1] in

Consider a loop or checking line[1] via _arguments for a more robust implementation.

Comment thread tests/completion-command.test.mjs Outdated
const { stdout } = await runCompletion(['bash']);
const expectedSubcommands = ['init', 'config', 'suggest', 'history', 'batch', 'completion'];
for (const subcmd of expectedSubcommands) {
assert.match(stdout, new RegExp(subcmd));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 MEDIUM RISK

The use of the RegExp constructor with a non-literal value is flagged as a security risk (ReDoS). Since this is a simple substring check in a test, use includes() for better performance and safety.

Suggested change
assert.match(stdout, new RegExp(subcmd));
assert.ok(stdout.includes(subcmd), `Expected stdout to contain subcommand: ${subcmd}`);

See Issue in Codacy

Comment thread src/commands/completion.ts Outdated
end

# Otherwise, suggest subcommands
__commit_echo_subcommands

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 MEDIUM RISK

In the Fish completion script, subcommands are suggested even when one has already been specified. Only suggest subcommands if no subcommand has been identified yet.

Wrap the call to __commit_echo_subcommands at the end of the __commit_echo_completions function in an if test -z "$subcmd" block.

Comment thread src/commands/completion.ts Outdated
Comment on lines +90 to +91
'completion:Generate shell completion scripts'
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚪ LOW RISK

Suggestion: Add 'help:Display help' to the commands array in the Zsh completion script. The 'help' subcommand is included in the Bash and Fish versions but is missing here, which leads to inconsistent behavior across shells.

@codacy-production codacy-production Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull Request Overview

The PR introduces a necessary completion command but currently fails to meet several quality and functional standards. Codacy analysis indicates the changes are not up to standards, primarily due to potential security risks in the test suite and logic errors in the generated shell scripts.

Several critical logic flaws were identified in the Zsh and Fish script generation that will prevent subcommands and options from being correctly suggested. Additionally, the implementation is inconsistent across shells; for instance, the help subcommand is omitted only in the Zsh implementation. High-priority issues include a misspelled registration command (_compdef) and a logic error in Zsh word-shifting that breaks subcommand-specific completion.

About this PR

  • There is a lack of parity between the three shell implementations. Specifically, Bash and Fish include the 'help' subcommand while Zsh does not. Furthermore, none of the scripts currently include short-form flags or aliases defined in the main CLI entry point, which contradicts the requirement for comprehensive flag support.

Test suggestions

  • Display help message when the completion command is invoked without a shell argument
  • Verify Bash completion script generation contains correct subcommands and global options
  • Verify Zsh completion script generation contains correct subcommands and specific options
  • Verify Fish completion script generation contains correct subcommands and global options
  • Ensure shell argument matching is case-insensitive (e.g., 'FISH' or 'BASH')
  • Verify non-zero exit code and error output for unsupported shell arguments (e.g., 'powershell')

TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback

Comment thread src/commands/completion.ts Outdated
Comment on lines +103 to +108
for w in \$words[2,-1]; do
case \$w in
-*) ;;
*) subcmd=\$w; break ;;
esac
done

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 HIGH RISK

Subcommand detection in Zsh fails because the shifting behavior of *:: is not accounted for. Since the subcommand is now at $words[1], the loop starting at $words[2] skips it. This prevents any subcommand-specific options (like --model for suggest) from being completed.

Comment thread src/commands/completion.ts Outdated
Comment on lines +149 to +150
_compdef _commit_echo commit-echo
`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 HIGH RISK

The registration command uses _compdef, but the standard Zsh command is compdef. Using the underscored version (which is typically an internal function name) will result in a 'command not found' error when the script is sourced directly by a user.

Comment thread src/commands/completion.ts Outdated
end

# Otherwise, suggest subcommands
__commit_echo_subcommands

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 MEDIUM RISK

The script suggests all subcommands even when one has already been selected. It should only suggest subcommands if the $subcmd variable is empty to avoid polluting the suggestion list with redundant commands.

Comment thread tests/completion-command.test.mjs Outdated
const { stdout } = await runCompletion(['bash']);
const expectedSubcommands = ['init', 'config', 'suggest', 'history', 'batch', 'completion'];
for (const subcmd of expectedSubcommands) {
assert.match(stdout, new RegExp(subcmd));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 MEDIUM RISK

Suggestion: Avoid using the RegExp constructor with variables to prevent Potential Regular Expression Denial of Service (ReDoS) risks. Since you are checking for simple substring existence in the test output, use stdout.includes(subcmd) for better security and readability.

Suggested change
assert.match(stdout, new RegExp(subcmd));
assert.ok(stdout.includes(subcmd));

See Issue in Codacy

Comment thread src/commands/completion.ts Outdated
commands="init config suggest history batch completion help"

# Global options
global_opts="--yes --auto --no-color --help --version"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 MEDIUM RISK

Suggestion: The completion scripts are missing several short-form flags (e.g., -y, -v, -m, -n) and long-form aliases (e.g., --auto) defined in the CLI. Please synchronize the scripts with the definitions in src/index.ts to ensure all valid options are suggested to the user.

- Fish completion: fix printf format from '%s\t%s\n' to '%s\n' since entries
  already contain embedded tab-separated option/description pairs
- Zsh completion: fix '_compdef' typo to 'compdef' (underscore variant is
  internal and causes command-not-found when sourced by users)
- Zsh completion: add missing 'help' subcommand to commands array for
  parity with bash and fish scripts
- Zsh completion: fix subcommand detection by starting word scan at
  \[1,-1] instead of \[2,-1] since '*::args:->args' shifts
  the words array so the subcommand is at index 1
- Fish completion: guard subcommand list fallthrough so subcommands are
  not re-suggested after one has already been selected
- Tests: replace new RegExp(subcmd) with stdout.includes(subcmd) for
  safer string matching without ReDoS concern
…gistry

Replaces three hand-maintained shell script template literals with
three small generator functions fed by a single SUBCOMMANDS data
structure (plus a parallel GLOBAL_OPTIONS array). Adding a subcommand
or option now only requires editing one place.

Also fixes two bugs found in PR review:

- Bash completion no longer suggests option flags immediately after a
  value-taking flag like `--model`. The list of value-taking flags is
  auto-derived from each option's `value` field.
- Error output from an unsupported shell no longer emits ANSI red when
  the user passes `--no-color` or has `NO_COLOR` set in the
  environment. The new `shouldUseColor()` helper also feeds the help
  printer.

Tests: 14 -> 20. New cases cover `--help` on the subcommand, value-flag
guards for all three shells, `--no-color` in the error path, and a
`bash -n` syntax check on the generated bash script.
Three behavioral fixes in the generated completion scripts plus added
zsh and fish syntax validation tests.

- Remove the synthetic 'help' subcommand from the bash, zsh, and fish
  completion lists. The CLI does not register a help subcommand, so
  tab-completing 'commit-echo help' would fall through to the default
  action and run suggestCommand({ commit: true }), which is a footgun.
- Replace the bash extglob value-flag guard (@(valueFlag)) with a
  portable case statement. The extglob form required 'shopt -s extglob'
  to be in effect in the user's shell; the case form is POSIX-clean
  and works regardless of extglob state.
- Add a JSDoc comment on the SUBCOMMANDS registry explaining that the
  'hook' subcommand is intentionally omitted because it is registered
  as hidden (it is invoked by Git, not humans).

Tests:
- Update the bash extglob regex to match the new case form.
- Add 'completion zsh script is syntactically valid zsh' and
  'completion fish script is syntactically valid fish' tests, gated on
  the corresponding shell being installed on the test host.

All 22 completion tests pass; full suite (231 tests) green.
The shouldUseColor helper previously required NO_COLOR to be a non-empty
string, but the no-color.org specification states that any form of the
variable (including an explicitly empty value) should disable color.
Drop the empty-string check so the spec is followed literally.

Also rename the misleading 'programArgs' parameter to 'argv' and add
short comments explaining the zsh two-state completion machine so future
maintainers can follow the command/args dispatch at a glance.

Pin the new behavior with a regression test.
Five small follow-up fixes and one docs tweak for the completion
command, all driven by PR #168 review feedback.

Behavior changes:
- Advertise short flag aliases in completion. The CLI accepts `-y`/`-v`/`-m`/`-n`/`-r`
  on the suggest and batch subcommands, but tab-completion was only
  suggesting the long forms. The `SubcommandOption` interface now has an
  optional `short` field, the registry carries the short aliases that
  match `index.ts`, and all three shell generators emit both forms.
- Handle the glued `--flag=value` form for value-taking flags in both
  bash and fish completion. Typing `commit-echo suggest --model=gpt<TAB>`
  no longer tries to complete the value. Zsh's `_arguments` already
  handled the glued form, so no change was needed there.
- Update the bash install example in the help text. The previous
  example appended to `~/.bashrc`, which works but is unconventional.
  The help now shows both a system-wide path
  (`/etc/bash_completion.d/commit-echo`) and a per-user path
  (`~/.local/share/bash-completion/completions/commit-echo`).

Code quality:
- Add an `isSupportedShell(s: string): s is SupportedShell` type guard
  in place of the `VALID_SHELLS.includes(x) as SupportedShell` cast in
  `completionCommand`.
- Hoist the test file's inline `await import(...)` calls to a single
  set of top-of-file imports and a shared `execFilePromisified` helper.

Tests:
- Expand "completion zsh script includes suggest subcommand options" to
  assert all nine registered suggest options are present, not just
  `--commit`/`--stream`/`--dry-run`/`--verbose`.
- Add `completion bash script includes short flag aliases`,
  `completion zsh script includes short flag aliases`, and
  `completion fish script includes short flag aliases` tests.
- Add `completion bash script handles --flag=value glued form`.
- Update `completion fish script guards value-taking flags like --model`
  to match the new `case` shape (long + short + glued forms).

23 -> 27 completion tests; full suite 234 -> 237 (1 pre-existing
Windows-only skip).
…subcmd scan

Zsh _arguments specs for short options incorrectly used ':--yes' suffix,
making zsh treat boolean flags like -y as value-taking. Remove the spurious
value marker for boolean short options and keep ':model:' only for flags
that actually take a value like -m.

Refactor fish __commit_echo_complete_options to accept the subcommand as a
parameter instead of re-scanning commandline tokens, eliminating duplicated
logic between it and __commit_echo_completions.
Commander auto-generates a \help\ subcommand, but it was absent from
the SUBCOMMANDS array so bash, zsh, and fish completions would not
suggest it. Add the entry and update the three subcommand-list tests.
Fish printf requires double-quoted format strings and arguments to
interpret escape sequences like \t (tab) and \n (newline). Single
quotes produced literal backslash-t characters instead of actual tab
separators in completion suggestions.
The 'case completion' block inside __commit_echo_complete_options was
missing its closing 'end', leaving the switch statement unclosed and
producing an invalid fish completion script.
… specs

The zsh _arguments spec for global short options used ':--yes' suffix,
making zsh treat boolean flags like -y as value-taking. Remove the
spurious value marker for boolean options and use stdout.includes()
instead of new RegExp() in the corresponding test.
Parse every subcommand's --help output and verify all flags appear in
the generated bash, zsh, and fish completion scripts. Catches cases where
a new option is added to src/index.ts but not reflected in the
SUBCOMMANDS array in completion.ts.

Also adds a sync requirement comment documenting the coupling.
…ead of hardcoding

Remove special-cased completion subcommand blocks from zsh and fish
generators. Options now come from the SUBCOMMANDS array like every
other subcommand, with the positional shell argument appended
conditionally. Add SHELL_NAMES_LIST constant derived from VALID_SHELLS
to eliminate hardcoded 'bash zsh fish' strings across all three
generators. Fix trailing backslash on last zsh global option spec.
…ommand in fish

Restructure the fish completion dispatch to check for empty subcommand
before the flag-match block. Previously, typing a flag like --y before
selecting a subcommand would fall through to suggest subcommands instead
of global options. Now matches the bash script's behavior.

Also adds docstrings to the three shell generator functions and a test
for the fish edge case.
…ion lines

The fish generator embedded a trailing backslash inside double-quoted
string literals for continuation lines. In fish, this escapes the
closing quote, making the literal string value include a backslash
character (e.g. completion suggestions displayed as 'init\').

Add a joinContinuationLines helper that appends ' \' only to interior
lines, leaving the last line clean. Also add a fish-specific test for
suggest subcommand options to match the existing zsh test coverage.
…dd shell name tests

Skip the zsh _arguments call for subcommands with no options (like
help) to avoid a dangling backslash continuation. Add tests verifying
shell name suggestions work for the completion subcommand across all
three shells, and that zsh omits _arguments for the help case.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add shell completion command

1 participant