# Shell completion Status: initial scope and all four product decisions selected; implementation has not started. Provide canonical suggestions with alias-aware interpretation for Bash, Zsh, and Fish through explicitly installed completion support. ## Purpose Provide useful shell completion for core-only applications and applications with optional integrations. Reuse installed command declarations and CommandKit's routing rules so consumers need little completion-specific wiring. Completion helps an operator construct an invocation. It does not execute the selected application command. Preserve application ownership of runtime behavior and upstream ownership of configuration and prompt semantics. ## Current baseline Reviewed baseline: `2301872` (`Stop flag interpretation at unknown flags`). - Core captures declarations and builds a routing snapshot containing canonical commands and separate application aliases. - [Neutral metadata](../../internal/commandmeta/metadata.go) describes command names, descriptions, flags, boolean/value distinctions, repetition, required flags, and operand cardinality. It has no completion choices or path hints. - The [Cobra adapter](../../internal/cobra/parse.go) constructs a backend tree for parsing and help. CommandKit owns execution and presentation outside that tree; enabling Cobra's default completion command alone is insufficient. - [Alias routing](../../route.go) resolves complete command paths and coordinates canonical parsing with entered spellings. Completion must also handle partial words and an empty current word. - Invocation reporting controls ordinary output and diagnostics. Shell completion queries need machine-readable replies independent of flags in the unfinished command line. - The core module uses Cobra v1.10.1 and pflag v1.0.9. Cobra supplies script generators and completion callbacks for Bash, Zsh, Fish, and PowerShell. See its [versioned completion documentation](https://github.com/spf13/cobra/blob/v1.10.1/site/content/completions/_index.md). [ADR 0013](../adr/0013-application-alias-routing.md) owns the separation between alias routes and canonical commands. [ADR 0014](../adr/0014-invocation-reporting.md) owns invocation reporting. This roadmap defines completion within those boundaries; it does not establish a replacement command model. ## Target experience An operator generates and loads a shell integration script, then receives suggestions for installed commands, applicable canonical flags, and declared value choices or paths. The selected script-generation grammar is: ```text app completion bash app completion zsh app completion fish ``` Consumers explicitly install a core completion declaration through the existing installation API. The completion namespace is reserved only when installed. Keep the machine query hidden from ordinary help, with collision validation for its selected path. Installation must not replace an application-owned command. Script generation writes to the caller-selected result stream. Shell setup instructions explain loading the script; automatic modification of shell startup files is outside the initial implementation. The initial MVP suggests canonical command names and flag spellings. Completed aliases already entered by the operator are interpreted to identify the canonical target. For example, with `jobs` routing to `workspace jobs`, completing after `app jobs ` can suggest the canonical children of `workspace jobs`. Completion should preserve the text the operator has already entered. Matching partial canonical names, resolving completed aliases, and interpreting an alias-only discovery prefix are distinct cases. Initially, an alias-only prefix with no canonical target offers no command continuations. For example, if `legacy inspect` is an alias but `legacy` has no canonical target, `app legacy ` offers no command continuations. After the complete alias is entered, completion uses its canonical target. Applicable flag suggestions can still follow the existing discovery context. Suggested continuations must form a valid next step when inserted into the entered route. Do not append canonical words that would create an invalid route. Alias discovery may be omitted from the initial MVP; this is a scope choice, not a permanent limitation of CommandKit. Suggesting alias names or alias-path continuations remains [potential future work](deferred.md#alias-completion-and-discovery). ### Flag suggestions Initially suppress already supplied singleton flags from flag-name suggestions. Canonical and aliased occurrences count as the same flag. Keep repeatable flags available. Keep all four reporting flags (`--quiet`, `--verbose`, `--debug`, and `--progress`) available because later occurrences can intentionally change or reset their settings. Suggestion filtering leaves accepted syntax unchanged. Operators can still type singleton flags again under the existing repetition rules. If an operator has already entered a repeated flag, continue completing its value according to its hint even when its name would have been omitted from suggestions. ## Selected initial scope Provide canonical command and flag suggestions, descriptions where supported by the selected shells, alias-aware interpretation, static value choices, and file/directory hints. Apply the same declaration facilities to application-owned commands and optional integrations. Support Bash, Zsh, and Fish using the existing backend generators, with validation in each shell. PowerShell is outside the initial supported shell set because there is no current consumer need; this does not preclude future support. Static suggestions should come from captured metadata. Completion should not invoke ordinary handlers, input/state factories, or acquisition callbacks to obtain it. Application startup and declaration-factory effects remain owned by the consumer, just as they do for help. Dynamic discovery of configured prompt names, remote resources, or other live values is a possible later extension. Deferring it avoids selecting provider lifetimes and latency behavior before a concrete consumer need; it is not a permanent prohibition on dynamic completion. ## Ownership and implementation approach Core owns completion context, alias interpretation, and neutral suggestions. The internal backend adapter owns Cobra-specific types, directives, script emission, and protocol details. Prefer the existing backend facilities where compatible with CommandKit's grammar. Verify the adapter approach with a small end-to-end prototype before fixing private interfaces. A completion request identifies completed words and the current partial word, including an empty word after a space. Interpret only what is needed to locate suggestions. Ordinary required-value validation and input conversion must not reject a partially constructed invocation before completion can help fill it. Reuse token and flag interpretation helpers where practical without changing normal execution grammar or treating incomplete input as an executable command. Account for command-local flags, aliases, consumed values, `--`, attached values, boolean assignments, short clusters, repeatable flags, and operand positions. Keep provenance sufficient to return a replacement for the word being edited. Completion candidates are suggestions, not an additional input validator. When both an operand and a flag are valid, use the operand's hint for an empty current word after a space. Offer flag names when the operator starts the word with `-` in a context where flags are accepted. Value choices and path hints belong in CommandKit-owned public metadata. Carry them through declaration capture and neutral metadata to the adapter. Arbitrary converter functions cannot reliably reveal their accepted values. Adding a list of suggestions must not silently restrict the values a converter accepts. Provide declarative static choices with optional descriptions, file/directory hints, and an explicit way to request no value suggestions. Unannotated values default to no value suggestions; applicable commands and flags still complete. Filename completion requires a path hint. This keeps unrelated filenames out of identifier and numeric completions. The implementation plan specifies how hints fit into existing binding declarations. Initially use one hint strategy per value position: static choices, files, directories, or no value suggestions. Optional choice descriptions belong to the static-choice strategy. Combined choices and filesystem suggestions can be considered later if consumers need them; the initial API need not define their merging or deduplication behavior. Verify the same strategy works for separated and attached flag values, such as `app serve --config ./par` and `app serve --config=./par`. For the attached form, preserve `--config=` and complete its value correctly. Validate the resulting command line in each supported shell. Keep ordinary script generation under the existing reporting policy. A hidden shell query is a protocol exchange: flags in the command being completed are request data, so `--quiet` must not erase its reply and `--debug` must not append ordinary diagnostics to it. When an unrecognized or incomplete command line leaves no inferable completion context, return a valid empty reply that disables filename fallback. Reserve protocol errors for failures in the query itself. Specify their wire behavior and output ownership in the implementation plan. A completion request must not accidentally run the target command. Hidden protocol names are implementation details unless deliberately published. ## Delivery plan The [implementation plan](implementation.md) owns the sprint sequence, API and protocol design, and validation steps. The target includes behavioral coverage and shell-level validation through the public consumer path in Bash, Zsh, and Fish. ## Deferred scope Alias discovery remains a potential extension beyond the MVP. Dynamic discovery remains deferred until a concrete consumer need justifies its callback, cancellation, error-handling, and provider-lifetime design.