Shell completions
Completions are not in the core — they are a separate module, sxcli.dev/completion, and they need nothing from you beyond naming them.
The whole integration#
Each shell package catalogs one service; the composition accepts it, exactly like a log sink:
import ( "sxcli.dev/completion/bash" "sxcli.dev/completion/zsh" ) fw.Builder(). Accept(bash.ID, zsh.ID /* , your services… */). Main()
fw.Solo and fw.Main() accept everything catalogued, so a
single-applet binary just imports and goes.
Then install the script for your binary:
eval "$(mybin completionbash --script)" # bash eval "$(mybin completionzsh --script)" # zsh, after compinit
There is nothing to declare and nothing to keep in sync. Your
config structs, usage: tags and
registration metadata already describe the command line — completions
are computed from those, per keystroke, against the real closure. A
field with Allowed completes exactly its legal values; one with
HintFile hands over to the shell's file completion; --disable
completes the binary's actual services. Declare once, get everything.
Why a module and not a feature#
The framework has no completion code, and that is the point. Everything the module needs is public API any of your own services could use:
- the Introspector — the read-only view of applets, services and closure-true argument schemas;
Systemapplets — the per-shell query endpoints (completionbash,completionzsh) are machinery, never listed in usage, and excluded from single-applet counting so accepting the module cannot change your binary's dispatch mode;- value hints — so the generator knows a flag takes a file, a directory or a service id.
Each of those landed in the core because an outside module needed it. That is the deal: capability gaps become core API improvements, never backdoors — and the same doors are open to anything you build.
Full documentation, including what completes and how to add a third shell, is in the completion module.