# Consumer guide CommandKit is distributed as three Go modules. Start with the core and add an integration module only when the application uses that library. Each module returns core `commandkit.Command` declarations, which the application installs through `commandkit.New` or `App.Register`. ## Module selection | Import | Use when | | --- | --- | | `gitea.maximumdirect.net/eric/CommandKit` | The application needs typed command declarations and common CLI behavior. | | `gitea.maximumdirect.net/eric/CommandKit/integrations/ckconfig` | The application wants ConfigKit-backed configuration scopes and reports. | | `gitea.maximumdirect.net/eric/CommandKit/integrations/ckprompt` | The application wants PromptKit engine configuration/comparison, prompt/profile catalogs, named inspection, requirements discovery, or concrete request validation. | The two integrations are independent optional imports. `ckprompt` uses the public scope and error contracts from `ckconfig`; importing it does not add the `config` family. An application that wants both families passes both returned declarations to core. The [maintained examples](../../README.md#examples) show core-only, ConfigKit-only, and composed applications. ## Go compatibility All three modules declare a consumer minimum of Go 1.26.0. The root module also selects ReleaseKit v0.4.0 as a Go tool, which makes that tool's module graph part of the root consumer module requirements even though production packages do not import ReleaseKit. The [release policy](../policy/release.md#consumer-minimum-and-release-toolchain) defines the support assumption. Maintainers use Go 1.26.8 for validation and publication; see the [release procedure](../release.md#release-toolchain). ## Core commands Declare typed flags and operands with `CommandSpec[I]`, then capture them with `NewCommand`. Bindings deliver `Supplied[T]`, which distinguishes an omitted default from an explicitly supplied empty, false, or zero value. ```go package example import ( "fmt" "strconv" commandkit "gitea.maximumdirect.net/eric/CommandKit" ) type GreetInput struct { Count commandkit.Supplied[int] } func Greeting() commandkit.Command { countDefault := 1 return commandkit.NewCommand(commandkit.CommandSpec[GreetInput]{ Name: "greet", Summary: "Write a greeting.", Flags: []commandkit.Flag[GreetInput]{ commandkit.ValueFlag( commandkit.FlagMeta{Name: "count", Usage: "Number of greetings."}, &countDefault, strconv.Atoi, func(input *GreetInput, value commandkit.Supplied[int]) { input.Count = value }, ), }, Run: func(invocation commandkit.Invocation, input GreetInput) commandkit.Outcome { _, _ = fmt.Fprintln(invocation.Streams.Out, input.Count.Value) return commandkit.Success() }, }) } ``` The application supplies `context.Context`, argv without the executable name, and output streams to `App.Execute`; it decides how the returned status maps to process exit. `New` installs generated help/version and caller declarations as one batch. `Register` validates each call as a batch before changing that App. Invalid declaration errors retain their wrapped identity for `errors.Is` and `errors.As`. Declarations copy their metadata and slice inputs when captured, retain callback references, and can be reused across applications. Copies of a typed binding preserve its identity; a separately constructed lookalike does not. Supplied values convert before input construction. A command's `NewInput` creates input only when execution reaches it; help does not construct caller input or run provider callbacks. ## ConfigKit scopes For an application with one ordinary app configuration loader, `ckconfig.AppCommand` supplies the state-free convenience declaration: ```go app, err := commandkit.New( commandkit.Identity{Name: "Example", Version: "dev"}, ckconfig.AppCommand(loadAppConfig), ) ``` `loadAppConfig` has the signature `func(context.Context, ckconfig.Selection) (*configkit.Result[T], error)`. Construction, installation, and help do not call it. `Selection` preserves whether config and overlay paths were explicitly supplied, including empty values. Use `ckconfig.Command(ckconfig.Suite[I, S]{...})` when the application needs multiple named scopes, selector flags, scope-aware input checks, or shared acquisition state or a custom comparison provider. A declared `Diff` capability uses `Scope.Compare`; `ckconfig.FromConfigKit` and `AppCommand` provide the ConfigKit-backed implementation. Each comparison side gets its own initialized and checked input, while state is shared by the invocation. Factory results remain caller-owned, so separate initialization calls do not guarantee distinct objects. See [ckconfig.Suite's GoDoc](../../integrations/ckconfig/contracts.go) for factory timing, omitted-factory zero values (including nil pointers), and ownership. The application owns the state type and what it caches. `ckconfig.FromConfigKit` adapts a typed ConfigKit loader without calling it during construction. The `config` family provides scope discovery, validation, native effective YAML, source inventory, path explanation, and ConfigKit-backed comparison for the capabilities declared by its scopes. The [CLI reference](../cli.md#configuration-scopes) owns operator syntax and report details. ## PromptKit configuration, definitions, and requirements `ckprompt.ConfigScope(loadEngine)` returns a `ckconfig.Scope` for the PromptKit engine's captured configuration. Add that scope to a `ckconfig.Suite` to expose it under `config` with validate/show/sources/explain and native diff operations; it does not install PromptKit catalog, definition, or requirements commands. `ckprompt.FromEngine(loadEngine)` supplies five callbacks: prompt and profile catalogs, named prompt and profile inspection, and native requirements discovery. Concrete request validation is a sixth, independently optional capability and is added explicitly with `ckprompt.WithRequestValidation`. `ckprompt.Command(suite)` creates only operations whose callbacks are present; discovery and validation share `promptkit requirements` but can be installed independently. A composed suite can keep the standard five and add validation: ```go suite := ckprompt.FromEngine(loadEngine) suite = ckprompt.WithRequestValidation(suite, loadEngine, buildRequest) suite.NewInput = newInput suite.NewState = newState suite.Selectors = selectors definitionCommand := ckprompt.Command(suite) ``` A validation-only suite can start empty. With application types named `Input` and `State`, a nil builder forwards the request fields populated by standard flags directly to PromptKit: ```go suite := ckprompt.WithRequestValidation( ckprompt.Suite[Input, State]{}, loadEngine, nil, ) validationCommand := ckprompt.Command(suite) ``` If the loader is nil, the returned suite retains a wiring issue for installation to report, even if capabilities are narrowed later. A builder runs before the engine loader and receives the seed request, selection, typed input, shared state, and invocation context. It returns the concrete request; the adapter does not merge seed fields back afterward. The loader receives the original selection. Builders should start from the seed, preserve operator values and bindings, and apply defaults only when a map key is absent, so explicitly supplied empty values stay meaningful. Applications that validate and then execute a request are encouraged to share their request construction logic between those paths. All six suite capabilities are independently optional. For catalogs without named or requirements inspection, narrow the suite before command capture: ```go definitions := ckprompt.FromEngine(loadEngine) definitions.InspectPrompt = nil definitions.InspectProfile = nil definitions.InspectRequirements = nil definitionCommand := ckprompt.Command(definitions) ``` Each selected inspection, requirements, validation, or catalog operation prepares one input, applies its captured selectors, checks that input, and initializes one state value when those steps are reached. The bundled validation adapter delegates concrete request preparation to PromptKit and carries its native errors plus engine-loading diagnostics through the acquisition. It does not call the model or retain a prepared execution snapshot. See [ckprompt.Suite's GoDoc](../../integrations/ckprompt/adapters.go) for factory timing, omitted-factory zero values, and caller-owned objects and effects. The loader receives invocation context, explicitly supplied selection, input, and state. `FromEngine` uses PromptKit's public listing and inspection methods, including `Engine.InspectRequirements`; validation must be opted into separately and uses `Engine.ValidateRequest`. Catalog, named definition inspection, and requirements discovery do not render messages or load request artifacts. Concrete request validation follows native PromptKit preparation, which can resolve prompt/profile resources, load artifacts and schemas, render messages, and perform applicable configuration and credential checks. It does not make a model call or certify that a later execution will succeed. Application loaders and direct callbacks retain their own effects. The [CLI reference](../cli.md#promptkit-definition-inspection) and [requirements contract](../cli.md#promptkit-requirements) own operator syntax and reports. The [composed example](../../integrations/ckprompt/examples/composed/README.md) combines app and PromptKit config scopes, comparison and catalogs, named and requirements inspection, and an application-owned `session restore` command. ## Outcomes and ownership Core classifies usage and operational failures while preserving application domain outcomes and supported error identity. Report and diagnostic delivery errors remain inspectable separately from the operation cause. The caller owns process startup, signal handling, and exit mapping; `Execute` never exits the process. Go declarations and GoDoc own exact exported contracts. ConfigKit owns configuration decoding, validation, and provenance. PromptKit owns prompt formats, profile resolution, and inspection details. See the [ConfigKit inspection API](https://gitea.maximumdirect.net/eric/ConfigKit/src/commit/dc09959cca4e105f49ec316c6d4ba585bd2340bd/inspection.go), [PromptKit engine methods](https://gitea.maximumdirect.net/eric/promptkit/src/commit/4b8169da286917fde7875425bb32b799b12c6af3/engine.go), [configuration inspection](https://gitea.maximumdirect.net/eric/promptkit/src/commit/4b8169da286917fde7875425bb32b799b12c6af3/configuration_inspection.go), and [inspection types](https://gitea.maximumdirect.net/eric/promptkit/src/commit/4b8169da286917fde7875425bb32b799b12c6af3/types.go).