Documentation
¶
Overview ¶
Package clikit is the shared CLI convention layer for the m-cli Go toolchain.
Every Go CLI in the toolchain (m-cli, irissync, vista-meta, kids-vc, m-dev-tools-mcp, …) is built on this package so they share one command grammar, one --output/JSON contract, one error/exit-code ladder, and one TTY-gated styling layer. See m-cli-go-toolchain-spec.md §5 / §5.5.
Index ¶
- Constants
- Variables
- func RenderError(c *Context, err error)
- func Run(name, description string, cli any, g *Globals, extra ...kong.Option) int
- type Context
- func (c *Context) Accent(s string) string
- func (c *Context) Badge(kind, label string) string
- func (c *Context) Diagnostics(data any, diags []Diagnostic, text func()) error
- func (c *Context) EmitJSON(v any) error
- func (c *Context) Failure(s string) string
- func (c *Context) Faint(s string) string
- func (c *Context) Glyphs() Glyph
- func (c *Context) Info(s string) string
- func (c *Context) JSON() bool
- func (c *Context) KV(pairs ...[2]string)
- func (c *Context) Link(text, url string) string
- func (c *Context) List(items ...string)
- func (c *Context) Muted(s string) string
- func (c *Context) NewProgress(total int) *Progress
- func (c *Context) NewSpinner(msg string) *Spinner
- func (c *Context) OK(s string) string
- func (c *Context) Panel(title string, lines ...string)
- func (c *Context) Result(data any, text func()) error
- func (c *Context) Rule(label string)
- func (c *Context) Severity(s string) string
- func (c *Context) Subtitle(s string)
- func (c *Context) Success(s string) string
- func (c *Context) Table(headers []string, rows [][]string)
- func (c *Context) Title(s string)
- func (c *Context) Tree(root TreeNode)
- func (c *Context) Warning(s string) string
- type Diagnostic
- type Envelope
- type Error
- type Globals
- type Glyph
- type OutputFormat
- type Progress
- type SchemaArg
- type SchemaCmd
- type SchemaCommand
- type SchemaDoc
- type SchemaFlag
- type Spinner
- type TreeNode
- type VersionCmd
Constants ¶
const ( ExitOK = 0 // success ExitRuntime = 1 // runtime error (IO / engine / parse) ExitUsage = 2 // usage error (bad flags/args) ExitCheck = 3 // --check / lint found findings or drift ExitRefused = 4 // engine-bound op refused (no engine / substrate unavailable) )
Exit codes — the toolchain-wide ladder (spec §3.3). Every CLI uses these.
const SchemaVersion = "1.0"
SchemaVersion is the semver of the machine surface (envelope + schema). Additive fields bump the minor; removals/renames bump the major (§5.5).
Variables ¶
var ( Version = "dev" Commit = "none" Date = "unknown" )
Build metadata, injected at link time:
go build -ldflags "-X github.com/vista-cloud-dev/go-cli-template/clikit.Version=$VER \
-X …/clikit.Commit=$SHA -X …/clikit.Date=$DATE"
Functions ¶
func RenderError ¶
RenderError prints an error: the JSON envelope in JSON mode, otherwise a styled "Error: …" + optional hint on stderr.
func Run ¶
Run is the single entry point every CLI in the toolchain uses. It wires Kong (the command grammar), shell completion (kongplete), the resolved output Context, the deterministic error/exit-code ladder, and the styled help — so every tool behaves identically. It returns the process exit code.
func main() {
cli := &CLI{}
os.Exit(clikit.Run("hello", "…", cli, &cli.Globals))
}
`g` must point at the Globals embedded in `cli` (populated by Parse).
Types ¶
type Context ¶
type Context struct {
Stdout io.Writer
Stderr io.Writer
Format OutputFormat
Color bool
Verbose bool
Command string
// contains filtered or unexported fields
}
Context carries the resolved output mode + styling into a command's Run. Bind it via clikit.Run; command methods take Run(cc *clikit.Context) error.
All styling lives on this one type (see style.go for the toolkit and spinner.go for the live elements). Every primitive is a no-op unless Color is set, so JSON and piped output stay clean automatically.
func NewContext ¶
NewContext resolves the format/color for this invocation from the globals and the TTY state of stdout. It also picks the glyph set: full Unicode on a UTF-8 terminal, an ASCII fallback otherwise.
func (*Context) Badge ¶
Badge renders an inline pill label. kind is one of ok, warn, err, info, accent, or neutral. Off a color TTY it degrades to "[label]".
func (*Context) Diagnostics ¶
func (c *Context) Diagnostics(data any, diags []Diagnostic, text func()) error
Diagnostics renders a result that carries lint-style findings.
func (*Context) KV ¶
KV prints aligned key/value pairs — keys padded to a common width, in the muted ink, with values in the default foreground.
func (*Context) Link ¶
Link renders an OSC 8 hyperlink — clickable in supporting terminals — and falls back to "text (url)" when styling is off.
func (*Context) NewProgress ¶
NewProgress returns a Progress bar over total steps, bound to this Context's stderr. total <= 0 is treated as 1 to avoid a divide-by-zero.
func (*Context) NewSpinner ¶
NewSpinner returns a Spinner bound to this Context's stderr, theme, and glyph set. It animates only on an interactive color TTY.
func (*Context) Panel ¶
Panel prints a rounded-border box with an optional bold title and body lines. Off a color TTY it falls back to a title line + indented body.
func (*Context) Result ¶
Result renders a command's result: the JSON envelope in JSON mode, otherwise the human-facing text produced by the text closure.
func (*Context) Rule ¶
Rule prints a horizontal divider spanning the terminal width (capped at 80). A non-empty label is centered within the rule.
func (*Context) Severity ¶
Severity returns an uppercased, glyph-prefixed, color-coded severity label (e.g. "✗ ERROR") for diagnostics and check output.
func (*Context) Table ¶
Table renders a rounded-border, color-styled table on a TTY, or a clean tab-aligned table otherwise. (JSON mode never calls this — commands emit rows as data.)
type Diagnostic ¶
type Diagnostic struct {
File string `json:"file,omitempty"`
Line int `json:"line,omitempty"`
Col int `json:"col,omitempty"`
Rule string `json:"rule,omitempty"`
Severity string `json:"severity"`
Message string `json:"message"`
}
Diagnostic is one lint/diagnostic finding (the editor↔CI shared shape).
type Envelope ¶
type Envelope struct {
SchemaVersion string `json:"schemaVersion"`
Command string `json:"command,omitempty"`
OK bool `json:"ok"`
Exit int `json:"exit"`
Data any `json:"data,omitempty"`
Diagnostics []Diagnostic `json:"diagnostics,omitempty"`
Error *Error `json:"error,omitempty"`
}
Envelope is the stable --output json wrapper for every command result (spec §5.5). One shape across the whole toolchain.
type Error ¶
type Error struct {
Code string `json:"code"`
Exit int `json:"exit"`
Message string `json:"message"`
Hint string `json:"hint,omitempty"`
}
Error is the deterministic, machine-parseable error object. Commands return it (via Fail) so agents and CI branch on code+exit, not on prose (§5.5).
type Globals ¶
type Globals struct {
Output string `short:"o" enum:"text,json,auto" default:"auto" help:"Output: text (styled on a TTY), json (machine-readable), or auto."`
NoColor bool `name:"no-color" env:"NO_COLOR" help:"Disable ANSI styling even on a TTY."`
Verbose bool `short:"v" help:"Verbose diagnostics to stderr."`
}
Globals are the flags every CLI in the toolchain shares. Embed it in the root command struct, e.g.:
type CLI struct {
clikit.Globals
Fmt FmtCmd `cmd:"" help:"…"`
}
type Glyph ¶
type Glyph struct {
OK string // success
Err string // error / failure
Warn string // warning
Info string // informational
Bullet string // list item
Arrow string // pointer / transition
Title string // section heading marker
Dot string // active / running
Pending string // not-yet-started
TBranch string // tree: child with siblings below
TLast string // tree: last child
TPipe string // tree: vertical continuation
TSpace string // tree: blank continuation
}
Glyph is the set of status and decoration glyphs. NewContext selects the Unicode set on a UTF-8 terminal and the ASCII set otherwise, so output stays legible in C/POSIX locales and dumb terminals.
type OutputFormat ¶
type OutputFormat string
OutputFormat is the resolved render mode for a single invocation.
const ( // FormatText renders human-facing output (styled when stdout is a TTY). FormatText OutputFormat = "text" // FormatJSON renders the machine-readable envelope (§5.5). FormatJSON OutputFormat = "json" )
type Progress ¶
type Progress struct {
// contains filtered or unexported fields
}
Progress is a determinate progress bar (filled/empty cells + percentage). Create it with Context.NewProgress, advance it with Set, and finish with Done. Like Spinner, it animates only on an interactive color TTY.
type SchemaArg ¶
type SchemaArg struct {
Name string `json:"name"`
Type string `json:"type"`
Enum []string `json:"enum,omitempty"`
Required bool `json:"required,omitempty"`
Help string `json:"help,omitempty"`
}
SchemaArg describes one positional argument.
type SchemaCmd ¶
type SchemaCmd struct{}
SchemaCmd is the reusable `schema` subcommand. Embed it in any CLI:
Schema clikit.SchemaCmd `cmd:"" help:"Emit the command tree as JSON."`
It always emits JSON (the machine surface), regardless of --output.
type SchemaCommand ¶
type SchemaCommand struct {
Path []string `json:"path"`
Help string `json:"help,omitempty"`
Flags []SchemaFlag `json:"flags,omitempty"`
Args []SchemaArg `json:"args,omitempty"`
}
SchemaCommand describes one (sub)command.
type SchemaDoc ¶
type SchemaDoc struct {
SchemaVersion string `json:"schemaVersion"`
Tool string `json:"tool"`
Version string `json:"version"`
GlobalFlags []SchemaFlag `json:"globalFlags,omitempty"`
Commands []SchemaCommand `json:"commands"`
}
SchemaDoc is the JSON `schema` output: the full command/flag/enum tree, reflected from the Kong model so it can never drift from the real surface.
type SchemaFlag ¶
type SchemaFlag struct {
Name string `json:"name"`
Short string `json:"short,omitempty"`
Type string `json:"type"`
Enum []string `json:"enum,omitempty"`
Default string `json:"default,omitempty"`
Required bool `json:"required,omitempty"`
Help string `json:"help,omitempty"`
}
SchemaFlag describes one flag.
type Spinner ¶
type Spinner struct {
// contains filtered or unexported fields
}
Spinner is an indeterminate progress indicator. Create it with Context.NewSpinner, Start it, optionally Update the message, and finish with Success, Fail, or Stop.
func (*Spinner) Start ¶
func (s *Spinner) Start()
Start begins the animation. It is a no-op (and safe) off an interactive TTY.
func (*Spinner) Stop ¶
func (s *Spinner) Stop()
Stop clears the spinner without printing a final line.
type VersionCmd ¶
type VersionCmd struct{}
VersionCmd is the reusable `version` subcommand. Embed it in any CLI:
Version clikit.VersionCmd `cmd:"" help:"Show version and build info."`
func (VersionCmd) Run ¶
func (VersionCmd) Run(c *Context) error
Run prints version + build info (styled text or the JSON envelope).