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,36 +1,30 @@
# CommandKit ckconfig
`ckconfig` is the optional ConfigKit integration for CommandKit. It adapts
ConfigKit loaders and scopes into reusable `commandkit.Command` declarations;
installing the integration is explicit and does not modify an application by
itself.
`ckconfig` adds configuration inspection commands to Go applications that use
CommandKit and ConfigKit. Operators can view settings, validate configuration,
find where values came from, and compare two configurations.
The application chooses which commands to install. Importing the package alone
does not install commands.
## Module
The module path is `go.maximumdirect.net/ckconfig`. Version v0.4.0 requires Go
1.27.0 and uses `go.maximumdirect.net/commandkit v0.4.0` and
`go.maximumdirect.net/configkit v1.1.0`; it does not import PromptKit. See the
[consumer guide](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/consumers/guide.md#configkit-scopes)
for exact callback and lifetime contracts.
The module path is `go.maximumdirect.net/ckconfig`. It does not import PromptKit.
See the [consumer guide](https://forge.maximumdirect.net/base-layer/commandkit/src/branch/main/docs/consumers/guide.md#module-selection)
for compatible releases and Go requirements.
## Example
For one application configuration scope, install the convenience declaration:
To inspect one application configuration, pass your loader to `AppCommand`:
```go
app, err := commandkit.New(identity, ckconfig.AppCommand(loadAppConfig))
```
Use `ckconfig.Command(ckconfig.Suite[Input, State]{...})` to define named
scopes, selectors, input checks, and state shared by the selected acquisitions
or comparison in a config invocation. `ckconfig.FromConfigKit` adapts a typed
ConfigKit loader. The `config` command family exposes scope discovery and the
validate, show, sources, explain, and diff operations supported by the declared
scopes. Source reports include native destination, placement, destination
fallback, version evidence, and empty-import selections. Comparison returns
ConfigKit's native records to shared report rendering; the
[CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#compare-configuration-selections)
owns its operator details.
For multiple named configurations or application-specific flags, use
`ckconfig.Command` with a `ckconfig.Suite`. The
[integration guide](https://forge.maximumdirect.net/base-layer/commandkit/src/branch/main/docs/consumers/guide.md#configkit-scopes)
explains loader setup, inputs, and shared state.
The maintained [simple example](examples/simple) shows a complete consumer.
The [CommandKit CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#configuration-scopes)

View File

@@ -1,10 +1,11 @@
// Package ckconfig, provided by go.maximumdirect.net/ckconfig, provides
// CommandKit's optional ConfigKit v1.1.0 integration, requiring Go 1.27.0. Its
// canonical Command declaration installs the standard config command family
// through the core commandkit package. Applications can install CommandKit
// RoutingRule declarations alongside it through commandkit.New or
// App.Register. Source reports preserve ConfigKit's destination, placement,
// version, and empty-import evidence. Invocation reporting applies CommandKit's shared
// visibility and delivery policy; provider warnings remain independent of
// failure explanations. Importing ckconfig alone installs no commands.
// Package ckconfig adds commands to view, validate, explain, and compare
// ConfigKit configuration in CommandKit applications.
//
// Use AppCommand for one application configuration loader, or Command with a
// Suite for multiple named configurations and application-specific flags.
// Install the returned command with commandkit.New or App.Register.
// Importing this package alone installs no commands.
//
// ConfigKit owns configuration loading and interpretation. CommandKit formats
// reports and messages using its shared reporting policy.
package ckconfig

View File

@@ -1,37 +1,90 @@
# Simple consumer
# ConfigKit example
This example imports `go.maximumdirect.net/ckconfig` and
`go.maximumdirect.net/commandkit`; ckconfig v0.4.0 uses core
v0.4.0, ConfigKit v1.1.0, and Go 1.27.0. Set `GOWORK=off GOTOOLCHAIN=local`
for the commands below.
This example adds configuration inspection and a custom `greet` command to a
small application. It uses local fixtures and in-memory defaults, with no
external services. See [module selection](../../../../docs/consumers/guide.md#module-selection)
for dependencies and Go requirements. Use Go 1.27.0 on `PATH` for this checkout.
Run the maintained example with:
From the repository root:
```sh
cd integrations/ckconfig/examples/simple
export GOWORK=off GOTOOLCHAIN=local
go run . config show
go run . config show --config fixtures/before.yml --verbose
go run . config show --config fixtures/before.yml --quiet
```
The output includes the default greeting, `Hello`, and schema version 2.
This example can run against its declared released dependencies with the
workspace disabled.
## Inspect and override a value
```sh
# Discover configuration paths under schema.
go run . config explain --list --under /schema
# Change the greeting for this invocation and show just that value.
go run . config show --path /greeting --set '/greeting="Hi"'
```
The second command prints `Hi`. It does not edit a file.
## Compare configurations
```sh
go run . config diff --config fixtures/before.yml --against-config fixtures/after.yml
```
The report includes `changes.greeting: Goodbye`.
```sh
# Expected status 3: the overridden greeting differs from the ordinary default.
go run . config diff --set '/greeting="Hi"' --details --check
```
This compares the overridden left side with ordinary configuration on the
right. `go run` prints `exit status 3` and itself exits with status 1; a built
executable returns the application's status 3 directly.
## Inspect warnings and failed loads
```sh
# Schema version 1 produces a warning, visible in verbose mode.
go run . config show --config fixtures/before.yml --verbose
# Quiet mode hides the configuration report and warning.
go run . config show --config fixtures/before.yml --quiet
```
Ordinary mode hides the warning but still displays configuration.
```sh
# Intentional failure: show detailed validation findings for the invalid fixture.
go run . config validate --config fixtures/invalid.yml --details --severity error
# Intentional failure: still show the source recorded before loading failed.
go run . config sources --config fixtures/invalid.yml --source-id source-1
```
Both commands retain the load failure. `source-1` belongs to this fixture's
load; other configurations can have different source IDs. See the
[CLI reference](../../../../docs/cli.md#configuration-scopes) for report and status rules.
## Try a custom command
```sh
go run . greet
go run . greet --count=0 --tag=first --tag second
```
The `config` family comes from one typed ConfigKit scope. The custom `greet`
command uses CommandKit's typed bindings and shows the difference between an
omitted `--count` and an explicitly supplied zero, plus ordered repeated tags.
With no `--config`, application settings use the in-memory default. A supplied
configuration and overlay are passed to ConfigKit unchanged. The comparison
command loads the two local fixtures and reports `changes.greeting: Goodbye`.
The before fixture uses schema version 1, which ConfigKit reports as a provider
warning in verbose mode. Ordinary mode hides the warning while preserving the
effective YAML report; quiet mode suppresses that report.
The invalid fixture demonstrates a failed-load report and captured source
inventory; `source-1` is the ID from that fixture's acquisition. The scope opts
in to transient overrides and passes them into its normal ConfigKit load. The
diff example compares an overridden left side with ordinary configuration on
the right and returns status 3 because the values differ.
The handler reports its greeting, count, and tags. It distinguishes an omitted
count from an explicitly supplied zero and preserves repeated tag order.
## How it is wired
One ConfigKit scope supplies the standard `config` commands. Without `--config`,
its loader uses an in-memory default. Supplied configuration and overlay values
are passed to ConfigKit unchanged. The scope enables temporary overrides and
passes them into its ordinary ConfigKit load. The
[consumer guide](../../../../docs/consumers/guide.md#configkit-scopes) explains
loader and scope setup.
Run `GOWORK=off GOTOOLCHAIN=local go test ./...` from this example directory to
check it against its declared dependencies.

View File

@@ -73,13 +73,13 @@ func newConfigOperationCommand[I, S any](prepared *preparedSuite[I, S], operatio
scopeChoices = append(scopeChoices, commandkit.CompletionChoice{Value: "all"})
}
flags := []commandkit.Flag[*configCommandInput[I, S]]{
commandkit.ValueFlag(commandkit.FlagMeta{Name: "scope", Usage: "Configuration scope name or all where supported.", Completion: commandkit.CompleteChoices(scopeChoices...)}, &defaultScope, parseConfigString,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "scope", Usage: "Select a named configuration, or all where supported.", Completion: commandkit.CompleteChoices(scopeChoices...)}, &defaultScope, parseConfigString,
func(input **configCommandInput[I, S], value commandkit.Supplied[string]) { (*input).scope = value }),
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Configuration source.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseConfigString,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Select the configuration source.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseConfigString,
func(input **configCommandInput[I, S], value commandkit.Supplied[string]) {
(*input).selection.Config = value
}),
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Overlay source.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseConfigString,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Select the configuration overlay.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseConfigString,
func(input **configCommandInput[I, S], value commandkit.Supplied[string]) {
(*input).selection.Overlay = value
}),
@@ -89,11 +89,11 @@ func newConfigOperationCommand[I, S any](prepared *preparedSuite[I, S], operatio
}
if operation == Validate {
flags = append(flags,
commandkit.BoolFlag(commandkit.FlagMeta{Name: "details", Usage: "Show native validation findings."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).details = value }),
commandkit.BoolFlag(commandkit.FlagMeta{Name: "details", Usage: "Show detailed validation findings."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).details = value }),
commandkit.RepeatFlag(commandkit.FlagMeta{Name: "severity", Usage: "Filter detailed findings by error or warning."}, []configkit.Severity(nil), parseValidationSeverity, func(input **configCommandInput[I, S], value commandkit.Supplied[[]configkit.Severity]) {
(*input).severities = value.Value
}),
commandkit.RepeatFlag(commandkit.FlagMeta{Name: "code", Usage: "Filter detailed findings by exact native code."}, []string(nil), parseConfigString, func(input **configCommandInput[I, S], value commandkit.Supplied[[]string]) {
commandkit.RepeatFlag(commandkit.FlagMeta{Name: "code", Usage: "Filter detailed findings by exact diagnostic code."}, []string(nil), parseConfigString, func(input **configCommandInput[I, S], value commandkit.Supplied[[]string]) {
(*input).codes = value.Value
}),
)
@@ -114,16 +114,16 @@ func newConfigOperationCommand[I, S any](prepared *preparedSuite[I, S], operatio
flags = append(flags,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "path", Usage: "JSON Pointer path to explain."}, (*string)(nil), parseConfigString, func(input **configCommandInput[I, S], value commandkit.Supplied[string]) { (*input).path = value }),
commandkit.BoolFlag(commandkit.FlagMeta{Name: "list", Usage: "List configuration paths."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).list = value }),
commandkit.BoolFlag(commandkit.FlagMeta{Name: "historical", Usage: "Include historical-only paths when listing."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).historical = value }),
commandkit.BoolFlag(commandkit.FlagMeta{Name: "historical", Usage: "Include paths that exist only in configuration history."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).historical = value }),
commandkit.ValueFlag(commandkit.FlagMeta{Name: "under", Usage: "List paths under a JSON Pointer."}, (*string)(nil), parseConfigString, func(input **configCommandInput[I, S], value commandkit.Supplied[string]) { (*input).under = value }),
commandkit.BoolFlag(commandkit.FlagMeta{Name: "explicit", Usage: "Filter listed current paths by explicitness."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).explicit = value }),
commandkit.BoolFlag(commandkit.FlagMeta{Name: "explicit", Usage: "Filter current paths by whether ConfigKit marks them explicit."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).explicit = value }),
)
}
if operation == Show {
flags = append(flags, commandkit.ValueFlag(commandkit.FlagMeta{Name: "path", Usage: "JSON Pointer to one effective value."}, (*string)(nil), parseConfigString, func(input **configCommandInput[I, S], value commandkit.Supplied[string]) { (*input).path = value }))
}
if operation == Sources {
flags = append(flags, commandkit.ValueFlag(commandkit.FlagMeta{Name: "source-id", Usage: "Select one source ID from this acquisition."}, (*string)(nil), parseConfigString, func(input **configCommandInput[I, S], value commandkit.Supplied[string]) { (*input).sourceID = value }))
flags = append(flags, commandkit.ValueFlag(commandkit.FlagMeta{Name: "source-id", Usage: "Show one source ID from this configuration load."}, (*string)(nil), parseConfigString, func(input **configCommandInput[I, S], value commandkit.Supplied[string]) { (*input).sourceID = value }))
}
flags = append(flags, commandkit.CaptureFlags(prepared.bindingsByOperation[operation], func(input **configCommandInput[I, S]) *commandkit.FlagValues[I] {
if input == nil || *input == nil {
@@ -160,7 +160,7 @@ func newConfigOperationCommand[I, S any](prepared *preparedSuite[I, S], operatio
func comparisonOperationFlags[I, S any]() []commandkit.Flag[*configCommandInput[I, S]] {
return []commandkit.Flag[*configCommandInput[I, S]]{
commandkit.BoolFlag(commandkit.FlagMeta{Name: "details", Usage: "Show native before and after difference evidence."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).details = value }),
commandkit.BoolFlag(commandkit.FlagMeta{Name: "details", Usage: "Show before and after values with presence and redaction details."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).details = value }),
commandkit.BoolFlag(commandkit.FlagMeta{Name: "check", Usage: "Return status 3 when differences are found."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).check = value }),
commandkit.ValueFlag(commandkit.FlagMeta{Name: "against-config", Usage: "Configuration source for the right side.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseConfigString,
func(input **configCommandInput[I, S], value commandkit.Supplied[string]) {
@@ -191,7 +191,7 @@ func operationDeclaration(operation Operation) (string, string) {
case Explain:
return "explain", "Explain a configuration path."
case Diff:
return "diff", "Compare two configuration selections."
return "diff", "Compare two configurations."
default:
return string(operation), "Inspect configuration."
}

View File

@@ -1,37 +1,40 @@
# CommandKit ckprompt
`ckprompt` is the optional PromptKit integration for CommandKit. It adapts
PromptKit engine configuration, native comparison, five catalogs, named
inspection, requirements discovery and validation, and native smoke tests.
Importing it does not install either command family.
`ckprompt` adds PromptKit inspection and testing commands to Go applications
that use CommandKit. Operators can list prompts, profiles, and backends, inspect
their settings, discover required inputs, validate and preview requests, and
run smoke tests.
The application chooses which commands to install. Importing the package alone
does not install commands.
## Module
The module path is `go.maximumdirect.net/ckprompt`. This source uses Go 1.27.0,
`go.maximumdirect.net/commandkit v0.4.0`, `go.maximumdirect.net/ckconfig v0.4.0`,
`go.maximumdirect.net/configkit v1.1.0`, and `go.maximumdirect.net/promptkit v0.20.0`. See the
[consumer guide](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/consumers/guide.md#promptkit-configuration-definitions-and-requirements)
for callback, input, state, and acquisition contracts.
The module path is `go.maximumdirect.net/ckprompt`. See the
[consumer guide](https://forge.maximumdirect.net/base-layer/commandkit/src/branch/main/docs/consumers/guide.md#module-selection)
for compatible releases, Go requirements, and the current source's dependency
alignment requirement.
## Example
Add `ckprompt.ConfigScope(loadEngine)` to the scopes passed to
`ckconfig.Command` when the application wants PromptKit engine configuration
and native comparison in the `config` family. Install
`ckprompt.Command(ckprompt.FromEngine(loadEngine))` separately for catalogs,
named inspections, and requirements discovery. `FromEngine` supplies nine
PromptKit-backed callbacks: four inspections and five catalogs. Applications
may narrow, wrap, or replace them before capture or provide custom callbacks
with `ckprompt.Suite`. Add concrete request validation, prepared-request preview,
and smoke testing explicitly with `WithRequestValidation`,
`WithRequestPreparation`, and `WithSmokeTesting`. Inspection,
requirements, and catalog operations do not execute prompts or contact model
providers; application loaders and callbacks retain their own effects. Smoke
testing invokes the selected native PromptKit operation; the
application retains ownership of client and configuration choices. See the
[CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#promptkit-smoke-testing)
for operator commands and report semantics. The maintained
[composed example](examples/composed) shows complete application wiring.
Pass your engine loader to `FromEngine` to add resource listings, inspection,
and requirements discovery:
```go
app, err := commandkit.New(identity, ckprompt.Command(ckprompt.FromEngine(loadEngine)))
```
Add request validation, preview, and smoke tests with `WithRequestValidation`,
`WithRequestPreparation`, and `WithSmokeTesting`. To expose engine configuration
under `config`, add `ckprompt.ConfigScope(loadEngine)` to a `ckconfig.Suite`.
The [integration guide](https://forge.maximumdirect.net/base-layer/commandkit/src/branch/main/docs/consumers/guide.md#promptkit-configuration-definitions-and-requirements)
explains these choices; the [composed example](examples/composed) shows them together.
Inspection commands do not call the model. Smoke tests can use the application's
configured client or network probes. Applications own engine setup, credentials,
and any effects of their loaders and callbacks. See the
[CLI reference](https://forge.maximumdirect.net/base-layer/commandkit/src/branch/main/docs/cli.md#promptkit-smoke-testing)
for commands and results.
## License and attribution

View File

@@ -91,7 +91,7 @@ func buildCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.Declaration
showCommands = append(showCommands, newPreparationCommand(suite, aliases))
}
if len(showCommands) != 0 {
rootCommands = append(rootCommands, commandkit.Group("show", "Show a named PromptKit definition.", showCommands...))
rootCommands = append(rootCommands, commandkit.Group("show", "Show PromptKit definitions or preview a prepared request.", showCommands...))
}
listCommands := make([]commandkit.Command, 0, 5)
if suite.ListPrompts != nil {
@@ -110,7 +110,7 @@ func buildCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.Declaration
listCommands = append(listCommands, newCatalogListCommand(suite, "collections"))
}
if len(listCommands) != 0 {
rootCommands = append(rootCommands, commandkit.Group("list", "List PromptKit catalogs.", listCommands...))
rootCommands = append(rootCommands, commandkit.Group("list", "List available PromptKit resources.", listCommands...))
}
requirementsCommands := make([]commandkit.Command, 0, 2)
if suite.InspectRequirements != nil {
@@ -125,7 +125,7 @@ func buildCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.Declaration
if suite.SmokeTest != nil {
rootCommands = append(rootCommands, newSmokeTestCommand(suite, aliases))
}
command := commandkit.RootGroup("promptkit", "Inspect, list, validate requests, and run PromptKit smoke tests.", rootCommands...)
command := commandkit.RootGroup("promptkit", "Inspect PromptKit resources, check requests, and run smoke tests.", rootCommands...)
for _, issue := range suite.issues {
command = commandkit.WithError(command, issue)
}
@@ -140,16 +140,16 @@ func newCatalogListCommand[I, S any](suite Suite[I, S], name string) commandkit.
return &(*input).captured
})
flags = append(flags,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Select the configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
func(input **catalogInput[I], value commandkit.Supplied[string]) { (*input).selection.Config = value }),
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Select the configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
func(input **catalogInput[I], value commandkit.Supplied[string]) { (*input).selection.Overlay = value }),
)
if name == "prompts" || name == "profiles" || name == "backends" {
flags = append(flags,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "namespace", Usage: "Select one native namespace."}, (*string)(nil), parseDefinitionString,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "namespace", Usage: "List resources in one namespace."}, (*string)(nil), parseDefinitionString,
func(input **catalogInput[I], value commandkit.Supplied[string]) { (*input).namespace = value }),
commandkit.BoolFlag(commandkit.FlagMeta{Name: "all-namespaces", Usage: "Select identities from every namespace."}, false,
commandkit.BoolFlag(commandkit.FlagMeta{Name: "all-namespaces", Usage: "List resources from every namespace."}, false,
func(input **catalogInput[I], value commandkit.Supplied[bool]) { (*input).allNamespaces = value }),
)
}
@@ -243,9 +243,9 @@ func newDefinitionCommand[I, S any](suite Suite[I, S], name string, aliases *[]c
return &(*input).captured
})
flags = append(flags,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Select the configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
func(input **definitionInput[I], value commandkit.Supplied[string]) { (*input).selection.Config = value }),
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Select the configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
func(input **definitionInput[I], value commandkit.Supplied[string]) {
(*input).selection.Overlay = value
}),
@@ -288,11 +288,11 @@ func newRequirementsCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.D
return &(*input).captured
})
flags = append(flags,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Select the configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
func(input **requirementsInput[I], value commandkit.Supplied[string]) {
(*input).selection.Config = value
}),
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Select the configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
func(input **requirementsInput[I], value commandkit.Supplied[string]) {
(*input).selection.Overlay = value
}),
@@ -308,8 +308,8 @@ func newRequirementsCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.D
spec := commandkit.CommandSpec[*requirementsInput[I]]{
Name: "show",
Summary: "Inspect requirements for a named PromptKit prompt.",
Description: "Profile selection establishes the reported profile identity, not a different set of requirements. A profile namespace qualifies an explicitly supplied short profile ID, not the prompt’s stored default reference.",
Summary: "Discover the inputs and variables a prompt needs.",
Description: "List required inputs without running the prompt. Choosing a profile changes the reported profile ID, not the requirements. A profile namespace applies to a short profile ID supplied here; it does not change the prompt’s stored default reference.",
NewInput: func() *requirementsInput[I] {
return &requirementsInput[I]{}
},

View File

@@ -1,13 +1,13 @@
// Package ckprompt, provided by go.maximumdirect.net/ckprompt, provides optional
// PromptKit configuration comparison,
// prompt catalogs, named inspections, requirements discovery and validation,
// prepared-request preview, and native smoke testing for CommandKit. Command
// returns a canonical declaration; Declarations adds scoped flag aliases.
// Applications can install those alongside other declarations through
// commandkit.New or App.Register. Importing ckprompt installs neither family; callers compose its
// declarations with core and ckconfig explicitly. Provider diagnostics remain
// passive until the owning command submits them through the invocation
// reporter, separately from any terminal explanation. This module uses
// PromptKit v0.20.0 and its native engine inventory, including configured
// bundled resources.
// Package ckprompt adds PromptKit inspection and testing commands to CommandKit
// applications. Operators can list resources, inspect definitions, discover
// required inputs, validate and preview requests, and run smoke tests.
//
// Start with FromEngine and add optional operations with WithRequestValidation,
// WithRequestPreparation, and WithSmokeTesting. Command returns the command
// family; Declarations also includes its convenience flag aliases. Install
// these with commandkit.New or App.Register.
//
// ConfigScope separately exposes engine configuration through ckconfig.
// Importing this package installs neither command family. Applications own
// engine construction, credentials, and client configuration.
package ckprompt

View File

@@ -1,27 +1,40 @@
# CommandKit ckprompt v0.3.0
CommandKit ckprompt v0.3.0 adopts PromptKit v0.20.0 and ConfigKit v1.1.0,
and requires CommandKit core v0.4.0, ckconfig v0.4.0, and Go 1.27.0.
The integration uses shared core reporting for text, YAML, and JSON output.
This unpublished candidate adds PromptKit v0.20.0 support, including request
preview, namespace selection, and shared text, YAML, and JSON output. It uses
ConfigKit v1.1.0 and requires Go 1.27.0.
Prompt, profile, and backend commands report PromptKit's native resource
inspections. Applications may opt into prepared-request preview, concrete
request validation, smoke testing, and namespace selectors independently.
Reusable request flag collections support application-owned commands;
`ckprompt.Declarations` installs the standard family with scoped aliases.
Literal and file inputs retain their command-line order. Provider parameters
can be supplied for preparation and applicable diagnostics.
## Operator features
The PromptKit configuration scope exposes native metadata and load-failure
evidence through ckconfig, including independent comparison selections,
detailed differences, and validation findings. Smoke reports retain native
evidence and operation failures separately from presentation failures.
- Inspect prompts, profiles, and backends, and list available resources.
- Preview rendered requests without calling the model, or validate that a
request can be prepared with the supplied inputs.
- Choose namespaces and override request settings for supported commands.
- Run smoke tests and inspect their results, including incomplete or unsupported
checks and reports returned alongside errors.
- Inspect engine configuration through `config`, including detailed validation
findings, source information after failed loads, and configuration comparisons.
This pre-1.0 release changes resource report shapes, input flags, formatting,
and configuration comparison behavior. Applications should update declarations
and report consumers to the current [CLI reference](../../../../docs/cli.md#promptkit-definition-inspection)
and [consumer guide](../../../../docs/consumers/guide.md#promptkit-configuration-definitions-and-requirements).
Applications continue to own engine construction, credentials, and execution.
Applications choose which commands to enable. Reusable flag collections also
let application commands offer the same request flags. `ckprompt.Declarations`
adds the standard commands with their shorter flag aliases. Literal and file
inputs keep their command-line order.
## Compatibility and preparation
This candidate changes resource report shapes, input flags, formatting, and
configuration comparison behavior. Review the current
[CLI reference](../../../../docs/cli.md#promptkit-definition-inspection) and
[consumer guide](../../../../docs/consumers/guide.md#promptkit-configuration-definitions-and-requirements)
when updating declarations or code that reads reports. Applications continue to
own engine construction, credentials, and execution.
The current source requires `ckconfig.AdaptDiagnostics`, which is absent from
its selected ckconfig v0.4.0 dependency. Before publication, complete
[dependency alignment](../../../../docs/roadmap/future.md#pending-release-and-integration-work)
and update this candidate's dependency guidance to the selected releases.
The [module selection table](../../../../docs/consumers/guide.md#module-selection)
distinguishes published combinations from the current workspace.
[COPYRIGHT](https://forge.maximumdirect.net/base-layer/commandkit/src/tag/integrations/ckprompt/v0.3.0/integrations/ckprompt/COPYRIGHT) |
[LICENSE](https://forge.maximumdirect.net/base-layer/commandkit/src/tag/integrations/ckprompt/v0.3.0/integrations/ckprompt/LICENSE) |

View File

@@ -1,141 +1,172 @@
# Composed consumer
# ConfigKit and PromptKit example
This example is part of the ckprompt module and uses core v0.4.0, ckconfig
v0.4.0, ConfigKit v1.1.0, and PromptKit v0.20.0. It requires Go 1.27.0.
This example combines application and PromptKit configuration, resource
inspection, request checks, and smoke tests. It uses local fixtures and an
in-memory model client. **No model service or credentials are required.**
This example composes application configuration, PromptKit configuration,
PromptKit comparison and catalogs, definition and requirements inspection, and
one application-owned command:
Use Go 1.27.0 on `PATH` and an aligned workspace containing all three local
modules. Follow the [workspace setup](../../../../docs/development.md#documentation-validation)
from the repository root first. Current ckprompt source needs a helper in local
ckconfig source that its released dependency does not yet contain; independent
builds remain pending [release alignment](../../../../docs/roadmap/future.md#pending-release-and-integration-work).
The [consumer guide](../../../../docs/consumers/guide.md#module-selection) owns
version and compatibility details.
From the repository root:
```sh
cd integrations/ckprompt/examples/composed
export GOWORK=auto GOTOOLCHAIN=local
go run . config scopes
go run . promptkit list prompts --campaign spring
go run . promptkit show prompt briefing --campaign spring --format yaml
```
The first command lists `app` and `promptkit` configurations and their available
operations. The next commands find and inspect the `briefing` prompt.
`--campaign` is a selector supplied by this example, not a standard PromptKit flag.
## Validate and compare configuration
```sh
go run . config validate --scope all --campaign spring --limit=0
go run . config diff --scope app --config fixtures/before.yml --against-config fixtures/after.yml
go run . config diff --scope app --config fixtures/before.yml --against-config fixtures/after.yml --campaign spring --limit=0
go run . config diff --scope app --campaign spring --limit=0 --against-campaign autumn --against-limit=0 --set '/campaigns/spring/model="left"' --against-set '/campaigns/spring/model="right"' --details
go run . config diff --scope promptkit --config fixtures/before.yml --against-config fixtures/after.yml --campaign spring --against-campaign spring
go run . promptkit list prompts --config fixtures/before.yml --campaign spring
```
The application scope requires `--limit=0` when `--campaign` is supplied.
The app comparison reports a changed default campaign and `campaigns.spring.model`.
The PromptKit comparison selects spring on both sides and reports the changed
profiles list as one value.
The two sides have independent selectors and overrides:
```sh
go run . config diff --scope app --campaign spring --limit=0 --against-campaign autumn --against-limit=0 --set '/campaigns/spring/model="left"' --against-set '/campaigns/spring/model="right"' --details
```
Only the application scope supports `--set` here. The released PromptKit loader
has no override handoff, so its configuration scope does not enable the feature.
An aggregate operation that includes that scope rejects overrides.
## List resources and select namespaces
```sh
go run . promptkit list profiles --config fixtures/after.yml --campaign autumn --format yaml
go run . promptkit list backends --campaign spring
go run . promptkit list namespaces --campaign spring
go run . promptkit list collections --campaign spring
go run . list collections --campaign spring
go run . pk list bundles --campaign spring
go run . promptkit list prompts --namespace field-notes --campaign spring
go run . promptkit show prompt briefing --campaign spring --format yaml
go run . promptkit show prompt briefing --campaign spring --prompt-namespace field-notes
go run . promptkit show prepared briefing --campaign spring --input topic=sprint --profile spring --extra-params '{"campaign":"preview"}'
go run . pk show prompt briefing --campaign spring --fmt yaml
go run . promptkit show profile spring --campaign spring
```
The profile list includes the selected `autumn` profile. PromptKit's default
bundle contributes additional resources. The example also supplies a
`field-notes` collection containing a backend, profile, and prompt. Listing
filters and resource namespace flags let you inspect that collection.
## Discover inputs, then check a request
```sh
go run . promptkit requirements show briefing --campaign spring
go run . promptkit requirements show briefing --campaign spring --var mode=full --format yaml
```
The first report is incomplete: the `notes` input is conditional and `mode` is
missing. Supplying `mode=full` selects that branch and makes `notes` required.
Both commands succeed; discovery alone does not establish that a request can run.
```sh
go run . promptkit requirements validate briefing --campaign spring --llm-input-file topic=fixtures/topic.txt
go run . promptkit requirements validate briefing --campaign spring --llm-input-file topic=fixtures/topic.txt --llm-var mode=full --llm-input-file notes=fixtures/notes.txt --format yaml
```
Both commands check request preparation and report `prompt_id` and `valid: true`.
The builder provides campaign-specific variable defaults; the operator supplies
the input files. For comparison, this command intentionally fails because the
required `topic` input is missing:
```sh
# Intentional failure: missing topic input.
go run . promptkit requirements validate briefing --campaign spring
```
Preview a request with literal input instead of a file:
```sh
go run . promptkit show prepared briefing --campaign spring --input topic=sprint --profile spring --extra-params '{"campaign":"preview"}'
```
The preview includes rendered messages and effective provider settings.
Validation and preview do not call the model or guarantee later execution.
## Run smoke tests
```sh
go run . promptkit test text_inference --campaign spring --prompt briefing --profile spring
go run . smoke text_inference --campaign spring --llm-prompt briefing --llm-profile spring
# Some diagnostics can fail or be unsupported; inspect the retained report.
go run . promptkit test all --campaign spring --llm-prompt briefing --llm-profile spring
```
Inference uses the example's in-memory client. HTTP checks may be unsupported
or not applicable because the local backend has no network probe. The aggregate
can return a failure while still showing results. Read the facts in the report;
a successful command status does not mean every observation is positive.
For any command that returns nonzero, `go run` prints `exit status N` and itself
exits with status 1. A built executable returns the application's status directly.
The [CLI reference](../../../../docs/cli.md#promptkit-smoke-testing) explains the
standard test kinds, results, and statuses.
## Try aliases and application commands
```sh
go run . list collections --campaign spring
go run . pk list bundles --campaign spring
go run . pk show prompt briefing --campaign spring --fmt yaml
go run . smoke text_inference --campaign spring --llm-prompt briefing --llm-profile spring
go run . pk --hlep
go run . session restore session-42 --campaign spring
go run . request inspect --llm-prompt briefing --llm-profile= --llm-model example --llm-input-text topic=sprint --format json
```
`newApp` installs application-owned command and flag aliases alongside the
complete `ckconfig` and `ckprompt` declarations. `list collections` and
`promptkit list bundles` both reach the canonical collection command; `pk`
shortens the PromptKit group. `--fmt` is scoped to named prompt inspection and
`--hlep` is available globally. The `smoke` shortcut retains the canonical
`promptkit test KIND` operand, including the special `all` aggregate.
The first two commands reach `promptkit list collections`. `pk` shortens the
PromptKit group; `--fmt` is an alias on prompt inspection and `--hlep` is a global
help alias. `smoke` shortens `promptkit test` while leaving the test kind as an
argument. The session command uses an in-memory store. `request inspect` shows
how an application command can reuse canonical `--llm-*` flag collections without
installing PromptKit's short aliases.
The example installs `Completion("composed-example")`. Build it as
`go build -o composed-example .`. Initialize `bash-completion` first if using
Bash, then load a shell script as described in the
[CLI reference](../../../../docs/cli.md#shell-completion). Try completion after
`composed-example pk show prompt briefing --fmt=` or after the filename prefix
in `composed-example config show --config=fixtures/`. The already-entered `pk`
alias selects the PromptKit command context without loading an engine.
## Try shell completion
The composition installs `ckconfig.Command(suite)` and the complete
`ckprompt.Declarations(definitions)` in a `[]commandkit.Declaration` with
root-installed routing rules. The PromptKit declarations include scoped aliases;
the application-owned `request inspect` command reuses the flag collections
with their canonical names and does not install those aliases.
Group children remain canonical `Command` values. For command-only slices,
convert each `Command` to `Declaration` before appending aliases. The
[consumer guide](../../../../docs/consumers/guide.md#application-owned-aliases)
includes minimal direct-call and slice-conversion examples; this README documents
the maintained complete consumer.
The sources and session store are small in-memory fixtures. `--campaign` is a
typed selector shared by the app and PromptKit configuration scopes. Their
`ckconfig.Suite[*inspectionInput, *runCache]` uses `NewInput` to initialize each
selected scope's input separately and `NewState` to create one cache shared by
that invocation's acquisitions. Prompt/profile inspection prepares its input and
cache independently for its invocation, using the same application and engine
loader functions. See the
[consumer guide](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/consumers/guide.md)
and the suites' GoDoc for initialization timing and ownership.
The application-scope comparison reports the changed default campaign and the
updated `campaigns.spring.model`. The PromptKit-scope comparison selects spring
on both sides and reports the native engine change in the atomic profiles list.
The application input check requires `--limit=0` when `--campaign` is supplied.
Catalogs use the same selection-aware loader: the prompt catalog includes
`briefing`, and the profile catalog includes the selected `autumn` profile.
Prompt inspection uses an ID only. The default PromptKit bundle also contributes
profiles and a backend to the engine inventory and source reports. The synthetic `field-notes` collection
provides one backend, profile, and prompt for collection discovery and native
namespace filtering. The example's shared run cache keys successful results by
the complete supplied configuration/overlay selection, CLI overrides, and the
supplied campaign, including presence. The campaign override and application
scope's `--set` records are applied through ConfigKit before loading. The
PromptKit configuration scope does not enable `--set` because its released
configuration loader has no override handoff. An aggregate operation therefore
rejects overrides when that scope is selected. These are choices for this
example's loaders and do not define a CommandKit cache policy.
Smoke testing is explicitly wired with `ckprompt.WithSmokeTesting` and its
optional request builder is nil, so CommandKit forwards the selected native
request. Applications that need to adjust the request can provide a typed
builder that starts with the seed and returns the chosen native request:
```go
definitions = ckprompt.WithSmokeTesting(definitions, loadEngine,
func(ctx context.Context, seed ckprompt.SmokeRequest, input *inspectionInput, state *runCache) (promptkit.SmokeTestRequest, error) {
request := seed.Request
request.ProfileID = "spring"
return request, nil
})
```sh
go build -o composed-example .
./composed-example completion bash
```
The example injects a small in-memory `promptkit.LLMClient` through its shared
run state. Catalog, inspection, and requirements commands do not call it;
inference smoke commands do. No model service or credentials are required.
Native HTTP checks may retain unsupported or not-applicable observations because
the selected local backend does not configure a network probe. An aggregate smoke command can
return an operational outcome for a native diagnostic while still delivering
the complete aggregate report.
Initialize `bash-completion` if using Bash, then load the generated script using
the [CLI reference](../../../../docs/cli.md#shell-completion). Try completing
`composed-example pk show prompt briefing --fmt=` or
`composed-example config show --config=fixtures/`. The already-entered `pk` alias
selects the command context without loading an engine.
The first requirements command reports incomplete discovery: PromptKit records
the conditional `notes` input and a missing `mode` issue. Supplying `mode=full`
selects that branch, classifies the undeclared `notes` input as required, and
completes discovery. Both commands return successful reports; the result does
not execute the prompt or establish input, credential, or execution readiness.
See the [CLI reference](../../../../docs/cli.md#promptkit-requirements) for the
command and report contract.
## How it is wired
The validation and preview commands exercise concrete PromptKit request preparation.
The first uses the builder's campaign-specific default topic variable and the
operator's topic file. The second also selects the notes branch and supplies its
file. Validation reports only `prompt_id` and `valid: true`; preview returns the
prepared request, including rendered messages and effective provider settings.
Neither executes the prompt. The validation command without inputs intentionally
fails because the prompt's
required `topic` artifact is not supplied. The builder defaults variables from
the selected campaign but leaves artifact bindings to the operator. The
`requirements show` commands remain discovery reports: partial discovery can
succeed even when a concrete request would fail validation.
The example installs `ckconfig.Command(suite)` and
`ckprompt.Declarations(definitions)` with application-owned aliases in a
`[]commandkit.Declaration`. `NewInput` initializes scope inputs; `NewState`
creates a cache shared within an invocation. The loaders cache successful
configuration results by the complete configuration/overlay selection,
overrides, and supplied campaign, including whether each value was supplied.
These are example choices, not a CommandKit cache policy.
Run `GOWORK=off go test ./...` from this example directory to check it against
its declared dependencies. The [developer guide](../../../../docs/development.md#documentation-validation)
also describes aligned workspace tests.
Smoke testing uses `WithSmokeTesting` with a nil builder, forwarding the request
selected by flags. Applications can supply a builder to customize that request.
See the [consumer guide](../../../../docs/consumers/guide.md#promptkit-configuration-definitions-and-requirements)
for suite composition, builders, and ownership, and the [source](main.go) for
the complete application.
Run `GOWORK=auto GOTOOLCHAIN=local go test ./...` from this example directory
for an aligned workspace check. Once dependency alignment is complete, also use
`GOWORK=off GOTOOLCHAIN=local go test ./...` to check the declared releases.

View File

@@ -39,9 +39,9 @@ func namespaceFlags[I any](destination func(*I) *namespaceInput, kinds ...string
}
var namespaceFlagDefinitions = struct{ prompt, profile, backend requestFlagDefinition }{
prompt: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-prompt-namespace", Usage: "Prompt resource namespace."}, []string{"prompt-namespace"}},
profile: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-profile-namespace", Usage: "Profile resource namespace."}, []string{"profile-namespace"}},
backend: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-backend-namespace", Usage: "Backend resource namespace."}, []string{"backend-namespace"}},
prompt: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-prompt-namespace", Usage: "Use this namespace for unqualified prompt IDs."}, []string{"prompt-namespace"}},
profile: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-profile-namespace", Usage: "Use this namespace for unqualified profile IDs."}, []string{"profile-namespace"}},
backend: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-backend-namespace", Usage: "Use this namespace for unqualified backend IDs."}, []string{"backend-namespace"}},
}
func selectedNamespaces(defaults *promptkit.Namespaces, selected namespaceInput) *promptkit.Namespaces {

View File

@@ -35,24 +35,24 @@ var requestFlags = struct {
InputText requestFlagDefinition
InputFile requestFlagDefinition
}{
Endpoint: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-endpoint", Usage: "Execution endpoint override."}, []string{"endpoint"}},
Model: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-model", Usage: "Execution model override."}, []string{"model"}},
Temperature: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-temperature", Usage: "Execution temperature override."}, []string{"temperature"}},
MaxTokens: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-max-tokens", Usage: "Execution maximum tokens override."}, []string{"max-tokens"}},
TopP: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-top-p", Usage: "Execution top-p override."}, []string{"top-p"}},
TimeoutSeconds: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-timeout-seconds", Usage: "Execution timeout override in seconds."}, []string{"timeout-seconds"}},
ServiceTier: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-service-tier", Usage: "Execution service tier."}, []string{"service-tier"}},
ReasoningEffort: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-reasoning-effort", Usage: "Execution reasoning effort override."}, []string{"reasoning-effort"}},
APIKeyEnv: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-api-key-env", Usage: "Execution API key environment variable."}, []string{"api-key-env"}},
TransientRetries: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-transient-retries", Usage: "Inference transient retry count."}, []string{"transient-retries"}},
ExtraParams: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-extra-params", Usage: "Execution provider parameters as a JSON object."}, []string{"extra-params"}},
Prompt: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-prompt", Usage: "PromptKit prompt ID."}, []string{"prompt"}},
Profile: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-profile", Usage: "PromptKit profile ID."}, []string{"profile"}},
Backend: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-backend", Usage: "PromptKit backend ID."}, []string{"backend"}},
SessionID: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-session-id", Usage: "PromptKit session ID."}, []string{"session-id"}},
Var: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-var", Usage: "Caller variable assignment KEY=VALUE."}, []string{"var"}},
InputText: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-input-text", Usage: "Literal prompt input assignment NAME=TEXT."}, []string{"input-text", "llm-input", "input"}},
InputFile: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-input-file", Usage: "Prompt input file assignment NAME=PATH."}, []string{"input-file"}},
Endpoint: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-endpoint", Usage: "Use this endpoint."}, []string{"endpoint"}},
Model: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-model", Usage: "Use this model."}, []string{"model"}},
Temperature: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-temperature", Usage: "Use this temperature."}, []string{"temperature"}},
MaxTokens: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-max-tokens", Usage: "Use this maximum token count."}, []string{"max-tokens"}},
TopP: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-top-p", Usage: "Use this top-p value."}, []string{"top-p"}},
TimeoutSeconds: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-timeout-seconds", Usage: "Set the request timeout in seconds."}, []string{"timeout-seconds"}},
ServiceTier: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-service-tier", Usage: "Use this service tier."}, []string{"service-tier"}},
ReasoningEffort: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-reasoning-effort", Usage: "Use this reasoning effort."}, []string{"reasoning-effort"}},
APIKeyEnv: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-api-key-env", Usage: "Name the environment variable containing the API key."}, []string{"api-key-env"}},
TransientRetries: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-transient-retries", Usage: "Set the retry count for transient inference failures."}, []string{"transient-retries"}},
ExtraParams: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-extra-params", Usage: "Supply provider parameters as a JSON object."}, []string{"extra-params"}},
Prompt: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-prompt", Usage: "Select a prompt by ID."}, []string{"prompt"}},
Profile: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-profile", Usage: "Select a profile by ID."}, []string{"profile"}},
Backend: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-backend", Usage: "Select a backend by ID."}, []string{"backend"}},
SessionID: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-session-id", Usage: "Supply the session ID."}, []string{"session-id"}},
Var: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-var", Usage: "Supply a prompt variable as KEY=VALUE."}, []string{"var"}},
InputText: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-input-text", Usage: "Supply text for a prompt input as NAME=TEXT."}, []string{"input-text", "llm-input", "input"}},
InputFile: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-input-file", Usage: "Supply a file for a prompt input as NAME=PATH."}, []string{"input-file"}},
}
// ExecutionInput contains request-scoped execution controls supplied on the CLI.

View File

@@ -29,11 +29,11 @@ func newSmokeTestCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.Decl
return &(*input).captured
})
flags = append(flags,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Select the configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
func(input **smokeCommandInput[I], value commandkit.Supplied[string]) {
(*input).selection.Config = value
}),
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Select the configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
func(input **smokeCommandInput[I], value commandkit.Supplied[string]) {
(*input).selection.Overlay = value
}),
@@ -53,14 +53,15 @@ func newSmokeTestCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.Decl
}
return commandkit.NewCommand(commandkit.CommandSpec[*smokeCommandInput[I]]{
Name: "test",
Summary: "Run one PromptKit smoke test.",
Name: "test",
Summary: "Run one or all PromptKit smoke tests.",
Description: "Tests use the configured client or probes and may contact a provider. The all option runs the four tests in order. Read the report: a successful command status does not mean every observation is positive.",
NewInput: func() *smokeCommandInput[I] {
return &smokeCommandInput[I]{}
},
Flags: flags,
Arguments: []commandkit.Argument[*smokeCommandInput[I]]{
commandkit.ValueArgument(commandkit.ArgumentMeta{Name: "kind", Usage: "Native smoke-test kind.", Completion: smokeKindCompletion()}, true, parseDefinitionString,
commandkit.ValueArgument(commandkit.ArgumentMeta{Name: "kind", Usage: "Test kind: reachability, authentication, text_inference, structured_output, or all.", Completion: smokeKindCompletion()}, true, parseDefinitionString,
func(input **smokeCommandInput[I], value commandkit.Supplied[string]) { (*input).kind = value.Value }),
},
CheckInput: func(input *smokeCommandInput[I]) error {

View File

@@ -31,11 +31,11 @@ func newConcreteRequestSpec[I, S any](suite Suite[I, S], path string, aliases *[
return &(*input).captured
})
flags = append(flags,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Select the configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
func(input **concreteRequestInput[I], value commandkit.Supplied[string]) {
(*input).request.Selection.Config = value
}),
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Select the configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
func(input **concreteRequestInput[I], value commandkit.Supplied[string]) {
(*input).request.Selection.Overlay = value
}),
@@ -93,7 +93,7 @@ func newConcreteRequestSpec[I, S any](suite Suite[I, S], path string, aliases *[
func newValidationCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.Declaration) commandkit.Command {
spec := newConcreteRequestSpec(suite, "promptkit requirements validate", aliases)
spec.Name = "validate"
spec.Summary = "Validate a concrete PromptKit request without executing it."
spec.Summary = "Check whether a request can be prepared without calling the model."
spec.Run = func(invocation commandkit.Invocation, input *concreteRequestInput[I]) commandkit.Outcome {
return runRequestValidation(invocation, suite, input)
}