Refresh operator documentation and CLI help

This commit is contained in:
2026-11-07 23:31:14 +00:00
parent 69fe35c480
commit c648d1de33
24 changed files with 1088 additions and 812 deletions

View File

@@ -1,40 +1,46 @@
# 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. Core and
compatible integration command factories return canonical `commandkit.Command` values.
Applications may install those alongside application-owned `RoutingRule`
declarations through `commandkit.New` or `App.Register`; routing rules are
installed at the application root, not as group children.
Start with core to build commands with typed inputs and shared output
formatting. Add an integration when your application uses ConfigKit or
PromptKit. The [core command example](#core-commands) below shows the basic
API; the [maintained examples](../../README.md#examples) show complete
applications.
## Module selection
| Import | Use when |
| --- | --- |
| `go.maximumdirect.net/commandkit` | The application needs typed command declarations and common CLI behavior. |
| `go.maximumdirect.net/ckconfig` | The application wants ConfigKit-backed configuration scopes and reports. |
| `go.maximumdirect.net/ckprompt` | The application wants PromptKit engine configuration/comparison, five catalogs, named inspection, requirements discovery, request validation, or native smoke testing. |
| `go.maximumdirect.net/commandkit` | You need commands, typed inputs, help, and common output handling. |
| `go.maximumdirect.net/ckconfig` | You want operators to view, validate, explain, and compare ConfigKit configuration. |
| `go.maximumdirect.net/ckprompt` | You want operators to inspect PromptKit resources, check and preview requests, or run smoke tests. |
Core v0.4.0 is published. The previously published matched releases are core
v0.3.0, ckconfig v0.2.0, and ckprompt v0.2.0.
The published ckconfig v0.3.0 uses ConfigKit v1.1.0 and does not compose
with ckprompt v0.2.0, which retains ckconfig v0.2.0 and ConfigKit v0.8.0.
Install the current core with `go get go.maximumdirect.net/commandkit@v0.4.0`.
For the older matched integration set, select core v0.3.0 and the corresponding
ckconfig or ckprompt v0.2.0 release together.
The following distinguishes published combinations from the current checkout:
Published ckconfig v0.4.0 uses core v0.4.0 and ConfigKit v1.1.0. The ckprompt
v0.3.0 candidate targets those releases and PromptKit v0.20.0. A Go 1.27.0
workspace may compose the three local modules. Current ckprompt source uses a
diagnostic helper introduced in local ckconfig source that is absent from
released ckconfig v0.4.0; independent ckprompt builds require release and
dependency alignment described in [future work](../roadmap/future.md#pending-release-and-integration-work).
| Selection | Core | ckconfig | ckprompt | Upstream libraries and status |
| --- | --- | --- | --- | --- |
| Published core | v0.4.0 | — | — | Usable independently. |
| Published ConfigKit integration | v0.4.0 | v0.4.0 | — | ConfigKit v1.1.0. |
| Earlier matched integration set | v0.3.0 | v0.2.0 | v0.2.0 | ConfigKit v0.8.0 and PromptKit v0.16.0, using their earlier import paths. |
| Current source | Local | Local | Local | ConfigKit v1.1.0 and PromptKit v0.20.0; use an aligned workspace until release dependencies are updated. |
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.
Install the published core with:
```sh
go get go.maximumdirect.net/commandkit@v0.4.0
```
Core v0.5.0 and ckprompt v0.3.0 have unpublished candidate notes. Current
ckprompt source calls `ckconfig.AdaptDiagnostics`, which is absent from its
selected released ckconfig v0.4.0 dependency. It therefore needs local
ckconfig source in the workspace until [release
alignment](../roadmap/future.md#pending-release-and-integration-work) is
complete. Published ckconfig v0.3.0 also uses ConfigKit v1.1.0 and does not
compose with ckprompt v0.2.0's earlier ConfigKit dependency.
Importing a module does not install its commands. Pass commands to
`commandkit.New` or `App.Register` explicitly. ckprompt depends on ckconfig's
public APIs, but you can install its `promptkit` commands without installing
the `config` family.
## Go compatibility
@@ -57,7 +63,6 @@ default from an explicitly supplied empty, false, or zero value.
package example
import (
"fmt"
"strconv"
commandkit "go.maximumdirect.net/commandkit"
@@ -81,8 +86,12 @@ func Greeting() commandkit.Command {
),
},
Run: func(invocation commandkit.Invocation, input GreetInput) commandkit.Outcome {
if _, err := fmt.Fprintln(invocation.Reporter().Output(), input.Count.Value); err != nil {
return commandkit.Failure("Could not write the greeting.").WithCause(err)
greetings := []string{}
for i := 0; i < input.Count.Value; i++ {
greetings = append(greetings, "Hello!")
}
if err := invocation.Reporter().Report(commandkit.Report{Value: greetings}); err != nil {
return commandkit.Failure("Could not write the greetings.").WithCause(err)
}
return commandkit.Success()
},
@@ -90,6 +99,10 @@ func Greeting() commandkit.Command {
}
```
Install `Greeting()` with `commandkit.New(identity, Greeting())`. By default,
`greet` prints `Hello!`; `greet --count=2` prints it twice. Add `--format
json` to receive a JSON list. A count of zero produces an empty list.
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
@@ -134,15 +147,13 @@ installation alongside aliases and integration commands.
## Invocation reporting
`Invocation.Reporter()` supplies the reporter for the current handler. Use
`Report()` for formatted substantive values and optional text templates;
use `Output()` or `RenderOutput()` for deliberate raw output. Use `Warn`, `Info`,
`Progress`, and `Debug` for categorized messages. Queue a summary with
`AtEnd().Info` when it belongs after the handler returns. Deferred submissions
are accepted until finalization begins; later submissions return
`ErrReporterClosed`. The
[CLI reference](../cli.md#reporting) owns flag grammar, visibility, prefixes,
and status behavior.
Use `Invocation.Reporter().Report` to print a value in the selected output
format. Pass ordinary Go values and, optionally, a `text/template` for text
output. Use `Warn`, `Info`, `Progress`, and `Debug` for categorized messages.
Queue a summary with `AtEnd().Info` when it belongs after the handler returns.
Deferred submissions are accepted until finalization begins; later submissions
return `ErrReporterClosed`. The [CLI reference](../cli.md#reporting) owns flag
grammar, visibility, prefixes, and status behavior.
Reports use JSON serialization to establish the common value representation
for YAML and JSON. A text template receives the original value; without one,
@@ -159,22 +170,29 @@ write to their supplied writer only while the callback runs; they must not
submit another message or start another rendering operation through the same
reporter.
For example, a handler can report a count as a small mapping:
```go
Run: func(invocation commandkit.Invocation, input GreetInput) commandkit.Outcome {
if _, err := fmt.Fprintln(invocation.Reporter().Output(), input.Count.Value); err != nil {
return commandkit.Failure("Could not write the greeting.").WithCause(err)
}
return commandkit.Success()
if err := invocation.Reporter().Report(commandkit.Report{
Value: map[string]int{"count": input.Count.Value},
}); err != nil {
return commandkit.Failure("Could not write the count.").WithCause(err)
}
return commandkit.Success()
```
This uses YAML automatically and supports `--format json` without a separate
encoder. Use `Output()` or `RenderOutput()` instead when you deliberately need
raw output; `--format` does not reformat those bytes.
After `App.Execute`, inspect the returned `Outcome`. Its `Cause` retains the
operation error; `Presentation.Output` and `Presentation.Diagnostics` report
delivery state and the first rendering or write errors for their destinations.
CommandKit does not retain a message transcript. Reporter operations for one
invocation are safe concurrently, but concurrent submission order is not
specified. The caller owns the writers passed to `Execute`; CommandKit does not
close them.
Joined operation errors support `errors.Is` and `errors.As` where the
underlying errors do. CommandKit does not retain a message transcript.
Reporter operations for one invocation are safe concurrently, but concurrent
submission order is not specified. The caller owns the writers passed to
`Execute`; CommandKit does not close them.
## Application-owned aliases
@@ -235,18 +253,22 @@ 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. `Selector.AgainstName` opts a selector into an
independent right-side flag. Each comparison side gets its own initialized and
checked input, with only its supplied selectors applied; state is shared by the
invocation. Factory results
remain caller-owned, so separate initialization calls do not guarantee distinct
objects. See
acquisition state or a custom comparison provider. A declared `Diff`
capability uses `Scope.Compare`; `ckconfig.FromConfigKit` and `AppCommand`
provide the ConfigKit-backed implementation. `Selector.AgainstName` opts a
selector into an independent right-side flag. Each comparison side gets its
own initialized and checked input, with only its supplied selectors applied;
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 application owns the state type and what it caches.
`ckconfig.FromConfigKit` adapts a typed ConfigKit loader without calling it
during construction. The bundled comparison adapters call the loader for the
left side before the right, retain left diagnostics if right loading fails,
and collect diagnostics from both loads before native comparison. Custom
comparison callbacks own their loading and diagnostics; loader calls need not
reread sources if the application caches them.
The `config` family provides scope discovery, validation, safe effective configuration display,
source inventory, path explanation, and ConfigKit-backed comparison for the
@@ -274,6 +296,8 @@ it does not install PromptKit catalog, definition, or requirements commands.
Its override feature is disabled because the released PromptKit configuration
loader does not accept ConfigKit override records.
### Install resource commands and optional checks
`ckprompt.FromEngine(loadEngine)` supplies nine callbacks: prompt, profile,
backend, namespace, and collection catalogs; named prompt, profile, and backend
inspection; and native requirements discovery. Concrete request validation,
@@ -308,6 +332,8 @@ suite := ckprompt.WithRequestValidation(
validationCommand := ckprompt.Command(suite)
```
### Request builders and loading
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
@@ -357,6 +383,8 @@ same canonical request flags into their own input types. Each collection exposes
individual handles and an `All` method, so a command can choose its applicable
subset. The application decides how to apply the resulting values to its request.
### Enable namespace flags
`ckprompt.WithNamespaces` enables standard resource namespace selection from
application-supplied defaults. Loaders used with this option should leave view
selection to the adapter. Without it, a loader can supply its own engine view.