fix(completions): stop Fish completions falling back to filenames - #1199
fix(completions): stop Fish completions falling back to filenames#1199leo-ar wants to merge 9 commits into
Conversation
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 5 remain after this review. 📝 WalkthroughWalkthroughFish completion generation now prevents filesystem fallback for non-path completions. It adds indexed positional completion support, path metadata for flags, Fish helper logic, and tests for forced and path-specific completion rules. ChangesFish Completion Fallback Prevention
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to This change prevents Fish from suggesting repository filenames for non-path arguments while preserving completion for true paths; no actionable merge-blocking risk remains after normal checks and review. Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
test/core/completions/generators/fish-generator.test.ts (1)
428-429: 💤 Low valueConsider breaking up the long assertion for maintainability.
The assertion spans the entire Fish completion condition string. While this ensures exact format, it's brittle—generator changes to whitespace, condition order, or quoting would break the test even if the semantic behavior is correct.
♻️ More maintainable alternative
Check the key components separately rather than the full string:
- expect(secondLine).toContain("complete -c openspec -n '__fish_openspec_using_subcommand workspace; and __fish_openspec_using_subcommand relink; and __fish_openspec_positional_index 1 2 --workspace'"); - expect(secondLine).not.toContain('-f'); + expect(secondLine).toContain('__fish_openspec_using_subcommand workspace'); + expect(secondLine).toContain('__fish_openspec_using_subcommand relink'); + expect(secondLine).toContain('__fish_openspec_positional_index 1 2 --workspace'); + expect(secondLine).not.toContain('-f');This preserves semantic correctness checks while being more resilient to formatting changes.
🤖 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 `@test/core/completions/generators/fish-generator.test.ts` around lines 428 - 429, The long brittle assertion on secondLine should be split into multiple targeted checks: replace the single expect(secondLine).toContain(...) with separate expectations that secondLine contains the completion command prefix ("complete -c openspec -n"), contains "__fish_openspec_using_subcommand workspace", contains "__fish_openspec_using_subcommand relink", and contains "__fish_openspec_positional_index 1 2 --workspace", while keeping the existing expect(secondLine).not.toContain('-f'); this uses the secondLine variable in test/core/completions/generators/fish-generator.test.ts and makes the test resilient to formatting or ordering changes.
🤖 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.
Nitpick comments:
In `@test/core/completions/generators/fish-generator.test.ts`:
- Around line 428-429: The long brittle assertion on secondLine should be split
into multiple targeted checks: replace the single
expect(secondLine).toContain(...) with separate expectations that secondLine
contains the completion command prefix ("complete -c openspec -n"), contains
"__fish_openspec_using_subcommand workspace", contains
"__fish_openspec_using_subcommand relink", and contains
"__fish_openspec_positional_index 1 2 --workspace", while keeping the existing
expect(secondLine).not.toContain('-f'); this uses the secondLine variable in
test/core/completions/generators/fish-generator.test.ts and makes the test
resilient to formatting or ordering changes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 0d28a349-8fdf-42aa-b558-1cdba32f0860
📒 Files selected for processing (6)
.changeset/fish-completion-no-file-fallback.mdsrc/core/completions/command-registry.tssrc/core/completions/generators/fish-generator.tssrc/core/completions/templates/fish-templates.tssrc/core/completions/types.tstest/core/completions/generators/fish-generator.test.ts
alfred-openspec
left a comment
There was a problem hiding this comment.
PR #1199 review: Fish completion filesystem fallback
Date: 2026-06-12
PR: #1199
Author: @leo-ar
Summary
The product direction is right: Fish completions should use -f for commands, subcommands, boolean flags, enum values, and non-path positional/value completions so Fish does not mix filesystem suggestions into OpenSpec command suggestions. The PR also correctly introduces completionType: 'path' for value-taking flags where file completion should remain enabled.
Codebase pattern check
Referenced Product/Codebase/core-completions.md:
COMMAND_REGISTRYremains the single source of truth for completion data.- Shell-specific logic stays inside the Fish generator/template pair.
- New positional behavior is covered in Fish-specific tests rather than changing other shell generators.
- No installer or marker-block behavior changed.
Blocking finding
The submitted Fish generator test suite fails on the PR branch.
Command run in a temporary clone of the PR branch:
pnpm exec vitest run test/core/completions/generators/fish-generator.test.tsResult:
FAIL test/core/completions/generators/fish-generator.test.ts > FishGenerator > generate > should allow file completion for path-typed indexed positionals
AssertionError: the given combination of arguments (undefined and string) is invalid for this assertion.
The failing assertion means completionLine(...) did not find the expected line for the path-typed indexed positional case. Until that is fixed, this PR should not merge.
Likely area to inspect
The failure is probably in the exact emitted condition for indexed positionals with value-consuming flags:
generateIndexedPositionalCompletions(...)collectValueFlags(...)- the test expectation for
__fish_openspec_positional_index 1 2 --workspace
The generated condition may include both long and short value flags, have different ordering, or not emit a path positional rule because generatePositionalCompletion('path', ...) intentionally emits no explicit completion rule. If Fish needs filesystem fallback for path positionals, no explicit complete line may be correct, but then the test should assert the absence of -f differently or the implementation should emit a path rule intentionally.
Review decision
Changes requested.
Once the failing Fish test is fixed and the completion test suite passes, I expect this to be mergeable. The underlying behavior is useful and scoped, and it complements discussion #1197 without claiming to solve Fish install/detection issues.
d033217 to
a404118
Compare
|
Thanks for the review — addressed in the latest push. I split the brittle assertion into smaller checks, and I also fixed the path-typed indexed positional case by emitting an explicit Fish completion rule for path positionals so filesystem completion is preserved there. I re-ran the Fish completion test suite and typecheck, and both pass on the updated branch. |
Fish never restores filesystem completion once a matching rule sets --no-files, so a path positional needs an explicit --force-files rule. Without it, `openspec store register <TAB>` lost file completion because the sibling subcommand rules in the same context now carry -f. Also drop retired "context store" vocabulary from the test fixtures. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
a404118 to
1860966
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
|
Hardened and ready for re-review at 25b804c. The original failing indexed-path case passes, and the follow-up adds real Fish 4.8.1 coverage for scoped path fallback, exact command paths, global/parent options, command-name value collisions, and attached short path values. Focused completion checks are green locally; CI is rerunning on the pushed head. |
Status
LGTM for re-review. The implementation has been hardened against real Fish 4.8.1 behavior, the branch is mergeable without conflicts, and all GitHub checks are green on the updated head.
What was wrong
Fish falls back to filename completion whenever no matching rule suppresses it. OpenSpec's commands, subcommands, boolean flags, enum values, and non-path positionals therefore mixed repository files into their own suggestions.
The first implementation also had three edge cases: path-option rules could enable files outside the option value, command-name-like values could activate the wrong completion scope, and parent/global options could hide the real command path.
How it was fixed
=forms, named workset members, and attached short values.--no-colorcompletion and keep top-level commands available after it.The shared command registry remains the source of truth for command-specific metadata. Other shell generators are unchanged.
Replication / proof
git diff --checkpass.=forms,name=path, attached short values, command-name value collisions, parent/global options, indexed positionals,--, and fallback suppression after a path is consumed.Notes / nits
This changes generated Fish completion behavior only. Commands and subcommands suppress arbitrary files by default; explicit path metadata is required to restore filesystem suggestions.