Files
commandkit/docs/cli.md

304 lines
11 KiB
Markdown
Raw Normal View History

# Command line reference
CommandKit owns command routing and syntax for commands registered with its
`App`. The caller supplies argv without the executable name, a context, and the
output and diagnostic writers. `App.Execute` returns an `Outcome`; it does not
exit the process.
## Help
The root help command lists registered commands and their summaries. Help is
available through a bare invocation, `--help`, `-h`, and `help`:
```text
example
example --help
example -h
example help
example help config show
example config --help
```
`help [COMMAND...]` resolves an exact registered path. A command group without
an execution handler displays its help when invoked by itself. A runnable
command with children runs its handler when invoked without help; add `--help`
to inspect that command and its children.
Help uses registered descriptions, command summaries, local flags, defaults,
required and repeatable flag metadata, and operand names and counts. It does not
construct the selected command's input or invoke its handler. Supplied flag and
operand values are still parsed so malformed values and unknown flags remain
usage errors. Missing execution-required values and input-combination checks
are skipped for help.
## Version
`version` reports the application identity by default:
```text
example version
example version --scope commandkit
example version --format yaml
```
The supported flags are:
| Flag | Values | Default | Meaning |
| --- | --- | --- | --- |
| `--scope` | `app`, `commandkit` | `app` | Select the caller's application identity or the embedded CommandKit module identity. |
| `--format` | `text`, `yaml` | `text` | Select the output format. |
Text output is `NAME VERSION`, followed by ` (REVISION)` when the selected
identity has a revision. An empty application version is displayed as `dev`;
the revision remains empty when omitted.
CommandKit identity uses the version of its module in build information. A
versioned module replacement supplies the effective version. A local or
versionless replacement, an untagged module, or missing build information
displays `dev`. The CommandKit identity name is `CommandKit`; dependency build
metadata does not supply a revision.
YAML output uses these explicit fields, including an empty revision:
```yaml
name: ExampleApp
version: dev
revision: ""
```
## Registered command syntax
Options are parsed after the complete command path and may be interspersed with
declared operands. Flags are local to the selected command. Use `--` to end
option parsing; all later tokens are operands.
Value flags accept `--name value` and `--name=value`. Boolean flags accept
presence as true and explicit values such as `--enabled=false`. A singleton
flag accepts repeated occurrences; the last successfully parsed occurrence
supplies its value. Every supplied occurrence is converted, so an earlier
malformed value remains an error. Repeatable flags preserve occurrence order,
with each occurrence treated as one value, including strings containing commas.
Typed inputs keep supplied state separate from defaults. An explicit empty,
false, or zero value is supplied. Help and version are available without
constructing application command inputs.
## Configuration scopes
An application installs one configuration suite with `RegisterConfig`. Its
`config scopes` command lists scope names and the configuration operations
currently installed for those scopes:
```text
example config scopes
example config scopes --format yaml
```
Text output uses one `scope: operation, operation` line per scope. YAML uses a
`scopes` sequence with explicit `name` and `operations` fields. Scope order is
`app`, then `promptkit`, then other names alphabetically. A metadata-only scope
can be listed without an acquisition callback. Discovery does not construct a
runtime context or acquire configuration. It reports the intersection between
declared scope capabilities and installed handlers, so an operation is listed
only when the corresponding command is available.
2026-10-07 14:26:32 +00:00
Applications can register the `promptkit` scope with `NewPromptKitScope` to
expose PromptKit engine configuration through these handlers. This configuration
scope can be installed without registering PromptKit prompt or profile
definition commands.
### Validate configuration
`config validate` loads and validates the selected scope. The default scope is
`app`; `--scope all` validates every registered scope and is available when each
scope declares validation. The command checks all selected capabilities before
calling scope providers.
Its default format is text; `--format yaml` emits a `scopes` sequence with
`name` and `valid: true` for each scope that completed successfully.
```text
example config validate
example config validate --scope promptkit --format yaml
example config validate --scope all
```
Each successful scope is reported as `SCOPE: valid`. Aggregate validation stops
at the first load or output failure; records from earlier successful scopes may
already have been written. Provider warnings go to the diagnostic stream and do
not alone make validation fail. `--config` and `--overlay` preserve whether an
empty value was explicitly supplied, so a scope callback can map those inputs to
its own ConfigKit load policy. Help and invalid syntax do not call scope
providers.
2026-10-07 13:55:43 +00:00
### Show effective configuration
`config show` writes the provider's native effective YAML for one scope. Its
default scope is `app`; `--format yaml` is accepted and YAML is the only initial
format. Single-scope output is passed through unchanged, without a CommandKit
header or document marker.
```text
example config show
example config show --scope promptkit
example config show --scope all
```
`--scope all` acquires every selected scope and checks each effective writer
before writing output. It then emits one YAML document per scope in discovery
order, with a `# scope: NAME` comment after each document marker. Existing native
markers and leading comments are retained; documents without a marker receive
one. Scope labels containing line control characters are quoted to keep them on
one comment line. A provider failure leaves the output stream empty. A rendering
or output failure may leave an aggregate prefix, and the outcome reports
incomplete report delivery.
2026-10-07 14:05:26 +00:00
### List configuration sources
`config sources` reports the source inventory captured during the selected
scope's acquisition. It reads the source facet once and does not reload
configuration. The default scope is `app`; `--scope all` is unsupported. Text is
the default format, and `--format yaml` returns a structured report:
```yaml
scope: app
sources:
- id: source-1
label: "application config"
path: /etc/example/config.yml
layer: base
kind: file
underlay_index: 0
imported_from: null
```
Each source includes `id`, `label`, `path`, `layer`, `kind`, `underlay_index`,
and `imported_from`. The import location is null when absent; otherwise it has
`source_id`, `line`, and `column`. Owning values and source order are preserved,
including empty fields, zero coordinates, and synthetic sources without paths.
An empty inventory is `sources: []`. Text output begins with the scope heading
and then prints the same source fields, quoting labels and paths.
2026-10-07 14:17:46 +00:00
### Explain a configuration path
`config explain --path POINTER` explains the effective and historical value at a
JSON Pointer path. `--path` is required; an explicitly empty value selects the
root. The default scope is `app`; `--format yaml` selects structured output, and
text is the default. `--scope all` is unsupported.
```text
example config explain --path /server/addr
example config explain --path /profiles/team~1summary --format yaml
example config explain --path= --format yaml
```
Pointer tokens use JSON Pointer escaping: `~1` represents `/` and `~0`
represents `~`. A malformed pointer is a usage error with status `2` and is
rejected before acquisition. A well-formed path that is unknown in the selected
configuration is an operational error with status `1`. Text output comes from
the scope's native explanation writer.
YAML output uses these root fields:
```yaml
scope: app
path: /server/addr
effective:
present: true
redacted: false
yaml: "localhost:8080\n"
origin:
layer: base
locations:
- source_id: source-1
line: 4
column: 9
operation: ""
inheritance: []
history: []
secret_reference: null
```
Snapshot `yaml` values remain strings, including null and empty fragments.
Origin and history retain source locations, operation names, inheritance paths,
ordered reasons and dependencies. Secret references contain only the owning
environment-variable name; effective and historical secret fragments remain
redacted. Empty location, inheritance, history, reason, and dependency lists are
serialized as `[]`.
2026-10-07 14:40:41 +00:00
## PromptKit definition inspection
Applications can install prompt and profile inspection independently with
`RegisterPromptKit`. Each installed handler constructs the selected engine once
and asks PromptKit to inspect the named definition. Inspection reads the
engine's captured configuration; it does not generate a prompt, contact a
provider, or look up credentials.
Prompt definitions and profile resolution remain owned by
[PromptKit](https://pkg.go.dev/gitea.maximumdirect.net/eric/promptkit).
```text
example promptkit show prompt customer/summary --version 2 --format yaml
example promptkit show prompt customer/summary
example promptkit show profile customer-support --format yaml
```
Both commands require one ID operand and accept `--config`, `--overlay`, and
`--format text|yaml` (default `text`). Prompt inspection also accepts singleton
`--version`, defaulting to the empty string. PromptKit owns version selection:
an omitted version works for a single-version ID, while an ambiguous ID is an
operational error. These commands do not accept `--scope`; their namespace is
`promptkit`.
Prompt YAML has these fields. Input order is preserved and an empty input list is
`[]`. The prompt hash is an opaque owning-library equality value.
```yaml
prompt_id: customer/summary
prompt_version: "2"
prompt_hash: opaque-value
default_profile_id: customer-support
inputs:
- name: topic
required: true
content_type: text/plain
description: Topic to summarize
output_contract:
format: json
validation_mode: basic
schema_path: ""
repair_attempts: 2
```
Profile YAML preserves the effective values reported by PromptKit, including
zero values and nested provider parameters. `api_key_env` is only an
environment-variable name. `api_key_required` reports a direct credential
requirement; neither field reports credential availability. A nil provider
parameter map is displayed as `{}`.
```yaml
profile_id: customer-support
effective_model_params:
backend_id: local
endpoint: https://example.invalid/v1
model: support-model
temperature: 0
max_tokens: 0
top_p: 0
timeout_seconds: 600
service_tier: ""
reasoning_effort: ""
api_key_env: ""
extra_params: {}
api_key_required: true
```
Text uses labeled fields and includes nested `extra_params` values. A missing ID
is a usage error. Blank, unknown, ambiguous, and canceled selections are
operational inspection results from PromptKit and retain its error identity.
## Outcome status
CommandKit usage failures use status `2`; operational failures use status `1`.
Successful operations use status `0`. Application handlers may return a domain
classification and status of their choice, which `Execute` preserves. The caller
chooses how to map an outcome to process exit.