Clarify inspection input ownership and documentation

This commit is contained in:
2026-10-11 13:07:00 +00:00
parent cec4da69d3
commit 7ce2fc0bf2
8 changed files with 67 additions and 27 deletions

View File

@@ -69,7 +69,7 @@ type View struct {
type Scope[I, S any] struct {
// Name identifies the scope in CLI selection and reports.
Name string
// Summary is shown when the scope is listed.
// Summary describes the scope. Scope discovery reports name and operations only.
Summary string
// Operations selects the standard handlers exposed for this scope.
Operations []Operation
@@ -89,10 +89,21 @@ type Selector[I any] struct {
// Suite declares the typed input, shared state, selectors, and configuration
// scopes used to assemble configuration commands.
//
// Input initialization is separate for each selected scope; state is shared
// by that invocation's acquisitions. Factory results and callback effects remain
// caller-owned: Command does not deep-copy arbitrary objects or repair aliases
// returned by factories. Core-owned repeated flag collections are copied when
// applied to separate inputs. Factories are not invoked during construction,
// installation, help, version, or scope discovery, and need not run after failure.
type Suite[I, S any] struct {
// NewInput creates fresh input storage for each selected scope.
// NewInput is called once for each selected scope reached after operation
// preflight, before applying its selectors and calling CheckInput.
// If nil, input is the zero value of I, including nil for pointer types.
NewInput func() I
// NewState creates shared acquisition state once per inspection invocation.
// NewState is called once when acquisition is reached, after all selected
// inputs pass their checks. The result is shared by selected acquisitions.
// If nil, state is the zero value of S, including nil for pointer types.
NewState func() S
// Selectors declares typed flags and their applicable scopes.
Selectors []Selector[I]

View File

@@ -43,9 +43,9 @@ type preparedSuite[I, S any] struct {
// Command eagerly captures a configuration suite as a root-only config family.
// It copies suite slices, retains callback references, and returns a reusable
// declaration; installation does not invoke factories or providers. During an
// inspection, it creates separate input for each selected scope, validates
// those inputs before acquisition, and creates shared state once for that
// invocation.
// inspection, it initializes input separately for each selected scope and
// validates those inputs before acquisition. Suite documents factory timing,
// zero values, shared state, and caller ownership of returned objects.
func Command[I, S any](suite Suite[I, S]) commandkit.Command {
prepared := captureSuite(suite)
if len(prepared.scopes) == 0 {

View File

@@ -21,8 +21,11 @@ Add `ckprompt.ConfigScope(loadEngine)` to the scopes passed to
the `config` family. Install `ckprompt.Command(ckprompt.FromEngine(loadEngine))`
separately for named prompt and profile inspection. `FromEngine` supplies
PromptKit-backed callbacks; applications may provide their own callbacks with
`ckprompt.Suite`. Inspection does not execute prompts, contact model providers,
or resolve credentials. The maintained
`ckprompt.Suite`. CommandKit-owned inspection code does not execute prompts,
contact model providers, or resolve credentials; application loaders and direct
callbacks retain their own effects. See the
[CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#promptkit-definition-inspection)
for the inspection boundary and report semantics. The maintained
[composed example](examples/composed) shows complete application wiring.
## License and attribution

View File

@@ -33,10 +33,17 @@ type ProfileRequest struct {
// Suite describes application-owned input, shared state, and named inspection
// capabilities. Its private issues retain adapter construction failures.
// Factory results and callback effects remain caller-owned: Command does not
// deep-copy arbitrary objects or repair aliases returned by factories.
// Factories are not invoked during construction, installation, help, or version,
// and need not run after failure.
type Suite[I, S any] struct {
// NewInput creates input storage once for the selected definition command.
// NewInput is called once when definition input preparation is reached,
// before applying selectors and calling CheckInput.
// If nil, input is the zero value of I, including nil for pointer types.
NewInput func() I
// NewState creates shared inspection state once for that invocation.
// NewState is called once when inspection is reached, after input checks
// pass. If nil, state is the zero value of S, including nil for pointer types.
NewState func() S
// Selectors declares the original typed flags accepted by definition commands.
Selectors []commandkit.Flag[I]

View File

@@ -26,8 +26,8 @@ type definitionInput[I any] struct {
// Command captures the optional named PromptKit inspection tree and adds only
// the inspection capabilities present in suite. It adds no configuration
// family; callers compose ConfigScope independently. Construction and
// installation do not run suite callbacks. A selected definition command gets
// its own input and one shared state value for that invocation.
// installation do not run suite callbacks. Suite documents invocation input
// and state initialization, zero values, and caller ownership of returned objects.
func Command[I, S any](suite Suite[I, S]) commandkit.Command {
if suite.InspectPrompt == nil && suite.InspectProfile == nil {
command := commandkit.NoCommand()

View File

@@ -13,6 +13,10 @@ go run . session restore session-42 --campaign spring
The sources and session store are small in-memory fixtures. `--campaign` is a
typed selector shared by the app and PromptKit configuration scopes. Their
scope contexts share a per-invocation cache created by `ConfigSuite.NewContext`.
Prompt/profile inspection has its own invocation context and composes the same
application and engine loader functions.
`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.