Files
max-sixty__worktrunk/templates/fish_wrapper.fish
Worktrunk Bot c2b7ab683e fix(shell): guard fish lazy-load wrapper against completion-mode recursion (#3250)
Follow-up to #3241, requested in #3240.

#3241 made the completion files **wt itself writes** resolve the binary,
so they no longer re-enter the fish lazy-load stub. But the stub
(`functions/wt.fish`) is still unguarded, leaving one narrow residual
case: a **stale third-party completion** that calls the bare `wt`
command with `COMPLETE` set — e.g. an old Homebrew
`vendor_completions.d/wt.fish` left on disk from before an upgrade —
re-enters the stub and recurses to fish's call-stack limit until the
package is rebuilt.

This adds the same `COMPLETE` short-circuit that bash and zsh already
use, so the stub delegates straight to the binary in completion mode
regardless of which completion file is active:

```fish
function wt
    if set -q COMPLETE
        command wt $argv   # bypass the stub, let the binary emit completions
        return
    end
    command wt config shell init fish | source
    ...
end
```

This makes fish immune to stale third-party completions, matching
bash/zsh.

## Changes
- `templates/fish_wrapper.fish` — add the `COMPLETE` guard to the
lazy-load stub.
- `src/shell/mod.rs` — `test_fish_wrapper_guards_completion_mode`
regression test (#3240).
- Regenerated the `configure_shell_fish_dry_run` snapshot.

Closes #3240.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: worktrunk-bot <worktrunk-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 15:21:39 -07:00

24 lines
1.0 KiB
Fish

# worktrunk shell integration for fish
# Sources full integration from binary on first use.
# Docs: https://worktrunk.dev/config/#shell-integration
# Check: {{ cmd }} config show | Uninstall: {{ cmd }} config shell uninstall
function {{ cmd }}
# Completion mode: let the binary emit completions directly. A stale
# third-party completion (e.g. an old Homebrew vendor_completions.d/wt.fish)
# may invoke the bare `wt` command with COMPLETE set; without this guard
# that lands back on this stub and recurses. Mirrors the bash/zsh guard.
if set -q COMPLETE
command {{ cmd }} $argv
return
end
command {{ cmd }} config shell init fish | source
# Check both command exit code ($pipestatus[1]) and source exit code ($pipestatus[2])
# If source fails, the function isn't replaced and we'd infinite-loop calling ourselves
set -l wt_status $pipestatus[1]
set -l source_status $pipestatus[2]
test $wt_status -eq 0; or return $wt_status
test $source_status -eq 0; or return $source_status
{{ cmd }} $argv
end