Add aliases to maintained examples

This commit is contained in:
2026-10-19 19:56:33 +00:00
parent c3bb3941d3
commit 666c006a89
8 changed files with 194 additions and 11 deletions

View File

@@ -15,8 +15,11 @@ go run . promptkit list profiles --config fixtures/after.yml --campaign autumn -
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 . pk show prompt briefing --campaign spring --fmt yaml
go run . promptkit show profile spring --campaign spring
go run . promptkit requirements show briefing --campaign spring
go run . promptkit requirements show briefing --campaign spring --var mode=full --format yaml
@@ -24,10 +27,19 @@ go run . promptkit requirements validate briefing --campaign spring --input topi
go run . promptkit requirements validate briefing --campaign spring --input topic=fixtures/topic.txt --var mode=full --input notes=fixtures/notes.txt --format yaml
go run . promptkit requirements validate briefing --campaign spring
go run . promptkit test text_inference --campaign spring --prompt briefing --profile spring
go run . smoke text_inference --campaign spring --prompt briefing --profile spring
go run . promptkit test all --campaign spring --prompt briefing --profile spring
go run . pk --hlep
go run . session restore session-42 --campaign spring
```
`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 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
@@ -92,3 +104,12 @@ 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 alias examples use the local CommandKit source because the composed
module's published core dependency, v0.2.0, predates alias declarations. From
the repository root, add the three local modules to `go.work` as described in
the [developer guide](../../../../docs/development.md#documentation-validation),
then run `go test ./...` from this example directory. This checks the example
against the current local core and integration sources; it does not claim that
published v0.2.0 supports aliases. The next core dependency adoption is handled
after the core release is prepared.

View File

@@ -200,6 +200,10 @@ func newApp() (*commandkit.App, error) {
}
func newAppWithLLMClient(client promptkit.LLMClient) (*commandkit.App, error) {
return newAppWithEngineLoader(client, loadPromptEngine)
}
func newAppWithEngineLoader(client promptkit.LLMClient, engineLoader func(context.Context, ckconfig.Selection, *inspectionInput, *runCache) (*promptkit.Engine, error)) (*commandkit.App, error) {
if client == nil {
client = &exampleLLMClient{}
}
@@ -210,7 +214,7 @@ func newAppWithLLMClient(client promptkit.LLMClient) (*commandkit.App, error) {
stateFactory := func() *runCache { return &runCache{llmClient: client} }
appScope := ckconfig.FromConfigKit("app", "Application settings.", loadApplicationConfig)
engineScope := ckprompt.ConfigScope(loadPromptEngine)
engineScope := ckprompt.ConfigScope(engineLoader)
configCommand := ckconfig.Command(ckconfig.Suite[*inspectionInput, *runCache]{
NewInput: inputFactory,
NewState: stateFactory,
@@ -227,12 +231,12 @@ func newAppWithLLMClient(client promptkit.LLMClient) (*commandkit.App, error) {
Scopes: []ckconfig.Scope[*inspectionInput, *runCache]{appScope, engineScope},
})
definitions := ckprompt.FromEngine(loadPromptEngine)
definitions := ckprompt.FromEngine(engineLoader)
definitions.NewInput = inputFactory
definitions.NewState = stateFactory
definitions.Selectors = []commandkit.Flag[*inspectionInput]{campaignSelector()}
definitions = ckprompt.WithRequestValidation(definitions, loadPromptEngine, buildValidationRequest)
definitions = ckprompt.WithSmokeTesting(definitions, loadPromptEngine, nil)
definitions = ckprompt.WithRequestValidation(definitions, engineLoader, buildValidationRequest)
definitions = ckprompt.WithSmokeTesting(definitions, engineLoader, nil)
definitionCommand := ckprompt.Command(definitions)
store := map[string]session{
@@ -270,12 +274,18 @@ func newAppWithLLMClient(client promptkit.LLMClient) (*commandkit.App, error) {
return commandkit.Success()
},
})
return commandkit.New(
commandkit.Identity{Name: "composed-example", Version: "1.0"},
declarations := []commandkit.Declaration{
configCommand,
definitionCommand,
commandkit.Group("session", "Manage saved sessions.", restore),
)
commandkit.Alias("list collections", "promptkit list collections"),
commandkit.Alias("promptkit list bundles", "promptkit list collections"),
commandkit.Alias("pk", "promptkit"),
commandkit.Alias("smoke", "promptkit test"),
commandkit.FlagAliasFor("promptkit show prompt", "--fmt", "--format"),
commandkit.FlagAlias("--hlep", "--help"),
}
return commandkit.New(commandkit.Identity{Name: "composed-example", Version: "1.0"}, declarations...)
}
func parseString(raw string) (string, error) { return raw, nil }

View File

@@ -5,6 +5,7 @@ import (
"context"
"io"
"reflect"
"strings"
"testing"
commandkit "gitea.maximumdirect.net/eric/CommandKit"
@@ -350,6 +351,54 @@ func TestComposedCatalogsAndSmokeUseInjectedClientOnlyForInference(t *testing.T)
}
}
func TestComposedAliasesReachCanonicalCommands(t *testing.T) {
clientCalls := 0
engineLoads := 0
engineLoader := func(ctx context.Context, selection ckconfig.Selection, input *inspectionInput, cache *runCache) (*promptkit.Engine, error) {
engineLoads++
return loadPromptEngine(ctx, selection, input, cache)
}
app, err := newAppWithEngineLoader(&exampleLLMClient{calls: &clientCalls}, engineLoader)
if err != nil {
t.Fatal(err)
}
var output bytes.Buffer
outcome := app.Execute(context.Background(), []string{"pk", "--hlep"}, commandkit.Streams{Out: &output, Err: io.Discard})
if outcome.Kind != commandkit.OutcomeSuccess || !strings.Contains(output.String(), "--hlep → --help") || strings.Contains(output.String(), "field-notes") || engineLoads != 0 || clientCalls != 0 {
t.Fatalf("group help alias outcome/output/engine loads/client calls = (%#v, %q, %d, %d)", outcome, output.String(), engineLoads, clientCalls)
}
for _, args := range [][]string{
{"list", "collections", "--campaign", "spring"},
{"pk", "list", "bundles", "--campaign", "spring"},
{"promptkit", "list", "collections", "--campaign", "spring"},
} {
output.Reset()
outcome = app.Execute(context.Background(), args, commandkit.Streams{Out: &output, Err: io.Discard})
if outcome.Kind != commandkit.OutcomeSuccess || !strings.Contains(output.String(), "field-notes") {
t.Fatalf("collection route %q outcome/report = (%#v, %q)", args, outcome, output.String())
}
}
for _, args := range [][]string{
{"pk", "show", "prompt", "briefing", "--campaign", "spring", "--fmt", "yaml"},
{"promptkit", "show", "prompt", "briefing", "--campaign", "spring", "--format", "yaml"},
} {
output.Reset()
outcome = app.Execute(context.Background(), args, commandkit.Streams{Out: &output, Err: io.Discard})
if outcome.Kind != commandkit.OutcomeSuccess || !strings.Contains(output.String(), "prompt_id: briefing") {
t.Fatalf("prompt inspection route %q outcome/report = (%#v, %q)", args, outcome, output.String())
}
}
output.Reset()
outcome = app.Execute(context.Background(), []string{"smoke", "text_inference", "--campaign", "spring", "--prompt", "briefing", "--profile", "spring"}, commandkit.Streams{Out: &output, Err: io.Discard})
if outcome.Kind != commandkit.OutcomeSuccess || !strings.Contains(output.String(), "kind: text_inference") || !strings.Contains(output.String(), "completed: true") || clientCalls != 1 {
t.Fatalf("smoke shortcut outcome/report/client calls = (%#v, %q, %d)", outcome, output.String(), clientCalls)
}
}
func composedReportValue(t *testing.T, data []byte, category string, fields ...string) *yaml.Node {
t.Helper()
var document yaml.Node