The engine shipped opt-in behind --new-completion, with the old scripts
still on --completion. That split was never released, so flip it now
rather than carry a third flag through a deprecation later.
--completion serves the engine wrappers; the hand-written scripts move to
completion/legacy/ and stay reachable via --legacy-completion for a
release or two.
.goreleaser.yml needed to follow: it packages the static files from
completion/ into the deb/rpm/apk contents and the Homebrew cask, so
leaving it untouched would have shipped the engine to anyone running
`eval "$(task --completion zsh)"` and the old scripts to everyone
installing from a package. The paths it references are unchanged and now
resolve to the wrappers. Its archive glob is narrowed at the same time,
so the test harness under completion/tests/ stops being shipped in the
release archives.
CLI variables are global to the invocation, not scoped to a task: `args.Parse` turns every word holding `=` into a global and every other word into a call, so `task build ENV=dev deploy` and `task build deploy ENV=dev` are the same command. The engine assumed the opposite and, as soon as a word matched a task, served only that task's variables — nothing at all when it had none. `task build <TAB>` and even `task build de<TAB>` went silent, where all five legacy wrappers offered task names at every position.
The engine now unions the still-unset requirements of every task named on the line, and falls through to task names once they are all set. The line resolves itself: fill in what blocks execution, then add another task. Keeping the two families exclusive means each keeps a coherent directive, so nothing loses its trailing space.
Task words are matched with FindMatchingTasks instead of a hand-built list of names truncated at their first `*`, which is why `task wildcard-foo <TAB>` used to offer task names rather than the variables of `wildcard-*`. Completion also disables fuzzy matching: a suggestion list has no "did you mean".
Three fixes ride along. `--sort default` left the sorter nil and cleared the one NewExecutor had set, so completion listed tasks in Taskfile order while `--list` sorted them — and a single templated description silently restored the sort through GetTaskList. The bash wrapper never defined KeepOrder, losing the declaration order of `requires`; it now passes `compopt -o nosort`, which bash 3.2 ignores as it already ignores nospace. And the shell suite unsets TASK_EXE and GO_TASK_PROGNAME: fish, Nushell and PowerShell resolve the binary through them, so an ambient value silently tested something other than the binary just built.
`--temp-dir` was missing from the flag-to-directive map, so it fell back to plain file completion while `--dir` and `--remote-cache-dir` offered directories.
The rest is dead weight: `listTasks` re-defaulted a sorter `NewExecutor` already sets and scanned descriptions for templates even with `--no-descriptions`; `detectTaskName` had a `--` branch `Complete` returns before reaching; the two flag-value branches built the same suggestion slice twice. `os.Args[2:]` is now sliced in one place, `complete.Words()`, instead of three, and the test helpers reuse `slicesext.Convert`.
Bash, Fish, Zsh, Nushell and PowerShell now share a single backend: `task __complete` returns the suggestions plus a directive, and every wrapper is a thin shim around it. All five shells offer the same suggestions — task names, aliases, flags, flag values and per-task CLI variables. The Zsh `show-aliases` and `verbose` zstyles keep working, now backed by the `--no-aliases` and `--no-descriptions` completion flags.
The engine is opt-in via `task --new-completion <shell>`, leaving `--completion` and the legacy scripts untouched; it will become the default in a future release. The new wrappers live under `completion/next/`.
Completing a keystroke never reaches the network, never blocks on a stdin entrypoint, and honors every flag that decides how the Taskfile is loaded. Ref resolution shared by `requires` and enum completion moved to `internal/refs`.
A cross-shell test suite exercises the protocol in Go with thin shell smoke tests, and runs in CI.
* feat: nested json
* feat: remove up_to_date from json output when --no-status flag is set
* feat: restrict use of --nested with --json and --list/--list-all
* refactor: executor functional options
* refactor: minor tidy up of list code
* fix: WithVersionCheck missing from call to NewExecutor
* feat: docstrings for structs with functional options
* refactor: prefix the functional options with the name of the struct they belong to