Expand description
Shared clap chassis and presentation kernel for the *ctl CLIs. A
library, not a command.
A consumer owns typed domain requests and results. ctl-core owns parsing, help, Usage mounts, color policy, terminal layout, streams, errors, and JSON emission. One serializable result feeds pretty, colorless, and JSON output.
§Quick start
use ctl_core::prelude::*;
use serde::Serialize;
#[derive(Parser)]
#[command(version, about = "example")]
struct Cli {
#[command(flatten)]
output: OutputArgs,
#[command(subcommand)]
command: Command,
}
#[derive(Subcommand)]
enum Command {
/// Show status.
Status,
}
#[derive(Serialize)]
struct Status {
pending: usize,
}
impl Present for Status {
fn present(&self) -> Document {
Document::new().fields(Fields::new().row("pending", self.pending.to_string()))
}
}
fn main() -> ExitCode {
App::<Cli>::new("example")
.view(|cli| cli.output.view())
.run(|cli| match cli.command {
Command::Status => Ok(Status { pending: 0 }),
})
}The default app feature covers this example.
§How output flows
Clap types ──→ App ──→ typed domain result ──┬──→ JSON
└──→ Document ──→ pretty/colorless- Domain handlers return data. They do not print, read terminal state, or choose the output format.
Presentmaps a serializable result to a semanticDocument.Viewserializes the result for JSON and renders its document for pretty and colorless output.- JSON always goes to stdout and never contains ANSI. Human failures go to stderr.
- The terminal engines, Comfy Table, Anstyle, and Anstream, stay private.
prelude is the one import a *ctl binary needs.
§Cargo features
Features are additive. Unused ones do not compile clap, comfy-table,
or schemars.
app(enabled by default) — Complete typed CLI lifecycle over the shared help and view layers.cli(enabled by default) — Clap derive helpers (OutputArgs,DryRunArgs) and parser defaults.document(enabled by default) — Semantic presentation documents without a terminal engine.json(enabled by default) — Serde models and the JSON view.render(enabled by default) — Terminal rendering for semantic documents. Engine crates stay private.schema— JSON Schema for the envelope and enums (schemars).help(enabled by default) — Styled-h/--helpthrough the shared document renderer.view(enabled by default) — Pretty / JSON / colorless emitters over serializable models.surface-model— Clap-derived operator metadata without serialization or a template engine.surface-serde— Serializable Surface metadata without a template engine.surface-templates— Shared MiniJinja fragments for committed operator documents.surface— Compatibility aggregate for the complete operator-document surface.served— Files a repository serves, rendered from templates that declare their own target (served::render,Served::write).validate— Garde rules every declared schema shares (validate).input— Declared input: read, parse with serde-saphyr, validate once with garde, and place every problem on its file and line through yamled.input-toml— Declared input from TOML:Input::openreads.tomlfiles, and thetomlcrate’s span-carrying tree places each problem on its line and column. Enablesinput, whoseLimitsit shares.fixture— Temporary file trees for integration tests:Suite, its scenarios, and one call per file.usage— Mise Usage spec from clap (--usage-spec, served-task mount).
Re-exports§
Modules§
- app
app - Fluent typed CLI lifecycle.
- color
- Color policy (
auto/always/never). - document
document - Semantic presentation document shared by every ctl CLI.
- fixture
fixture - Files for integration tests, written through one call instead of
fs::create_dir_all,fs::write, and anexpectper file. - flags
cli - Shared clap flatten structs.
- format
- Output representation (
pretty/json). - help
help - Styled help extracted from Clap and rendered as a semantic document.
- input
input - Declared input: read a file, parse its shape with
serde-saphyr(YAML) or thetomlcrate (TOML, withinput-toml), validate it once with garde, and report every problem on its file and line. - model
- Schema-first wire types. Views render these; they do not own data.
- parser
cli - Parser defaults.
-h/--helpand-V/--versionstay on. - prelude
- Import once in a *ctl
main.rs. - render
render - Render semantic documents without exposing the terminal engine.
- served
served - Files a repository serves, rendered from templates that declare where they go.
- surface
surface-model - Clap-derived operator metadata and validation.
- table
render - Compatibility helpers over the semantic document renderer.
- usage
usage - Mise Usage spec from a clap
Command. - validate
validate - Garde rules every declared schema shares, so a repository’s config and a template’s own exports are held to the same rules and complain the same way.
- view
view - Pretty, colorless, and JSON emission from one typed model.