Motivation
talm CLI today ships with cobra's default completion (subcommand names, flag names) — but no value-aware completion. Every operator workflow that survives a sleepy 3am rotation involves:
- Remembering the exact filename of the node patch (
nodes/cp-01.yaml vs nodes/cp01.yaml)
- Hand-copying node IPs / endpoints from talosconfig because the shell can't suggest them
- Re-typing
--mode=staged / --mode=try / etc. without tab-completion
- Recalling preset names for
talm init -p ...
cobra exposes everything needed to make this work out of the box. talm currently registers exactly one completion hook (pkg/commands/talosctl_wrapper.go:44 borrowing the parent's ValidArgsFunction). The cost of filling the rest is small; the daily friction relief is large.
Scope
Positional args
talm apply <FILE...> — complete to project files that carry the talm modeline (typically nodes/*.yaml). Scan from CWD upward to the project root (same root-detection logic that init already uses).
talm template <FILE...> — same set.
talm upgrade <FILE...> — same set.
Flag values
File-shaped flags (cobra has filename completion as a built-in directive — use it where applicable):
--file / -f on apply, template, upgrade — restrict to *.yaml / *.yml.
--values on template — restrict to *.yaml / *.yml.
--template / -t on template — complete to chart template paths under charts/<chart>/templates/.
--with-secrets on apply, template, init — *.yaml filter.
--talosconfig (global) — file completion.
talosconfig-derived flags:
--nodes (global) — parse the in-scope talosconfig (--talosconfig value, $TALOSCONFIG, default ~/.talos/config, project-local talosconfig), extract every node from every context, dedup, return.
--endpoints (global) — same source, endpoint fields.
Lazy: only resolve talosconfig when the flag is actually being completed.
Enum flags:
--mode on apply — {auto, no-reboot, reboot, staged, try} from helpers.Mode's known set.
--preset / -p on init — enum of valid preset names (currently embedded in talm's preset registry).
--talos-version on apply / template / init / upgrade — known machinery contract values (v1.10, v1.11, v1.12, ...) parsed from siderolabs/talos/pkg/machinery/config.
Out of scope (initial phase)
--set / --set-string / --set-json / --set-literal / --set-file value completion (would need to introspect values.yaml schema — large enough for its own follow-up).
- Dynamic image-tag completion for
--image (would require a network call).
Design
cobra API used per category:
- File-shaped flags:
cmd.RegisterFlagCompletionFunc(name, func) with the []string{"yaml", "yml"} filter via cobra.ShellCompDirectiveFilterFileExt.
- Positional args with modeline filter:
cmd.ValidArgsFunction = func(cmd, args, toComplete) ([]string, cobra.ShellCompDirective) — walk CWD-to-project-root, list *.yaml, filter to files whose head matches the talm modeline regex (already implemented in processModelineAndUpdateGlobals).
- talosconfig-derived:
cmd.RegisterFlagCompletionFunc("nodes", ...) and parse with the existing talosconfig loader.
- Static enums:
cobra.FixedCompletions([]string{"auto", "no-reboot", ...}, cobra.ShellCompDirectiveNoFileComp).
Where it lives
One file per command: pkg/commands/apply_completion.go, template_completion.go, etc. Each init() (or an explicit registerCompletions(cmd) called from the command's init()) attaches its completions. Keeps completion co-located with the command, avoids a god-file.
The shared talosconfig parser (nodes + endpoints extraction) goes in pkg/commands/completion_helpers.go since multiple commands need it.
Tests
cobra completion functions are pure: (cmd, args, toComplete) -> ([]string, ShellCompDirective). Unit-test each:
pkg/commands/apply_completion_test.go — feed fixtures for --mode, --nodes (with a fake talosconfig), positional file argument (with a fake CWD layout), assert returned values + directive.
- Per-shell smoke test (optional): pipe
talm completion bash into bash -n to prove the generated script parses; skip in CI if it adds too much.
How users enable it
Nothing new on the talm side — completion is on once talm completion <shell> is sourced:
# bash
talm completion bash | source
# zsh
talm completion zsh > "${fpath[1]}/_talm"
# fish
talm completion fish | source
# powershell
talm completion powershell | Out-String | Invoke-Expression
cobra already generates talm completion <shell> for free — confirm it's present in pkg/commands/root.go, add if missing.
Acceptance
- All four shells (
bash, zsh, fish, powershell) emit completion scripts via talm completion <shell> and the scripts parse.
- Unit tests cover each completion func with realistic input.
- README gets a small "Shell completion" section pointing at
talm completion --help.
Motivation
talm CLI today ships with cobra's default completion (subcommand names, flag names) — but no value-aware completion. Every operator workflow that survives a sleepy 3am rotation involves:
nodes/cp-01.yamlvsnodes/cp01.yaml)--mode=staged/--mode=try/ etc. without tab-completiontalm init -p ...cobra exposes everything needed to make this work out of the box. talm currently registers exactly one completion hook (
pkg/commands/talosctl_wrapper.go:44borrowing the parent'sValidArgsFunction). The cost of filling the rest is small; the daily friction relief is large.Scope
Positional args
talm apply <FILE...>— complete to project files that carry the talm modeline (typicallynodes/*.yaml). Scan from CWD upward to the project root (same root-detection logic thatinitalready uses).talm template <FILE...>— same set.talm upgrade <FILE...>— same set.Flag values
File-shaped flags (cobra has filename completion as a built-in directive — use it where applicable):
--file / -fonapply,template,upgrade— restrict to*.yaml/*.yml.--valuesontemplate— restrict to*.yaml/*.yml.--template / -tontemplate— complete to chart template paths undercharts/<chart>/templates/.--with-secretsonapply,template,init—*.yamlfilter.--talosconfig(global) — file completion.talosconfig-derived flags:
--nodes(global) — parse the in-scope talosconfig (--talosconfigvalue,$TALOSCONFIG, default~/.talos/config, project-localtalosconfig), extract every node from every context, dedup, return.--endpoints(global) — same source, endpoint fields.Lazy: only resolve talosconfig when the flag is actually being completed.
Enum flags:
--modeonapply—{auto, no-reboot, reboot, staged, try}fromhelpers.Mode's known set.--preset / -poninit— enum of valid preset names (currently embedded in talm's preset registry).--talos-versiononapply/template/init/upgrade— known machinery contract values (v1.10,v1.11,v1.12, ...) parsed fromsiderolabs/talos/pkg/machinery/config.Out of scope (initial phase)
--set/--set-string/--set-json/--set-literal/--set-filevalue completion (would need to introspectvalues.yamlschema — large enough for its own follow-up).--image(would require a network call).Design
cobra API used per category:
cmd.RegisterFlagCompletionFunc(name, func)with the[]string{"yaml", "yml"}filter viacobra.ShellCompDirectiveFilterFileExt.cmd.ValidArgsFunction = func(cmd, args, toComplete) ([]string, cobra.ShellCompDirective)— walk CWD-to-project-root, list*.yaml, filter to files whose head matches the talm modeline regex (already implemented inprocessModelineAndUpdateGlobals).cmd.RegisterFlagCompletionFunc("nodes", ...)and parse with the existing talosconfig loader.cobra.FixedCompletions([]string{"auto", "no-reboot", ...}, cobra.ShellCompDirectiveNoFileComp).Where it lives
One file per command:
pkg/commands/apply_completion.go,template_completion.go, etc. Eachinit()(or an explicitregisterCompletions(cmd)called from the command'sinit()) attaches its completions. Keeps completion co-located with the command, avoids a god-file.The shared talosconfig parser (nodes + endpoints extraction) goes in
pkg/commands/completion_helpers.gosince multiple commands need it.Tests
cobra completion functions are pure:
(cmd, args, toComplete) -> ([]string, ShellCompDirective). Unit-test each:pkg/commands/apply_completion_test.go— feed fixtures for--mode,--nodes(with a fake talosconfig), positional file argument (with a fake CWD layout), assert returned values + directive.talm completion bashintobash -nto prove the generated script parses; skip in CI if it adds too much.How users enable it
Nothing new on the talm side — completion is on once
talm completion <shell>is sourced:cobra already generates
talm completion <shell>for free — confirm it's present inpkg/commands/root.go, add if missing.Acceptance
bash,zsh,fish,powershell) emit completion scripts viatalm completion <shell>and the scripts parse.talm completion --help.