clikit

package
v0.0.0-...-e8f29ab Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 15, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

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

View Source
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.

View Source
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

View Source
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

func RenderError(c *Context, err error)

RenderError prints an error: the JSON envelope in JSON mode, otherwise a styled "Error: …" + optional hint on stderr.

func Run

func Run(name, description string, cli any, g *Globals, extra ...kong.Option) int

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

func NewContext(g *Globals, command string) *Context

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) Accent

func (c *Context) Accent(s string) string

Accent returns s styled as an accent (or unchanged when !Color).

func (*Context) Badge

func (c *Context) Badge(kind, label string) string

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) EmitJSON

func (c *Context) EmitJSON(v any) error

EmitJSON pretty-prints an arbitrary value as JSON (used by `schema`).

func (*Context) Failure

func (c *Context) Failure(s string) string

Failure returns a "✗ s" failure line.

func (*Context) Faint

func (c *Context) Faint(s string) string

Faint returns s styled faint/dim (or unchanged when !Color).

func (*Context) Glyphs

func (c *Context) Glyphs() Glyph

Glyphs returns the glyph set active for this invocation.

func (*Context) Info

func (c *Context) Info(s string) string

Info returns an "ℹ s" informational line.

func (*Context) JSON

func (c *Context) JSON() bool

JSON reports whether the machine-readable envelope should be emitted.

func (*Context) KV

func (c *Context) KV(pairs ...[2]string)

KV prints aligned key/value pairs — keys padded to a common width, in the muted ink, with values in the default foreground.

func (c *Context) Link(text, url string) string

Link renders an OSC 8 hyperlink — clickable in supporting terminals — and falls back to "text (url)" when styling is off.

func (*Context) List

func (c *Context) List(items ...string)

List prints a bulleted list, one item per line, indented two spaces.

func (*Context) Muted

func (c *Context) Muted(s string) string

Muted returns s in the muted gray ink (or unchanged when !Color).

func (*Context) NewProgress

func (c *Context) NewProgress(total int) *Progress

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

func (c *Context) NewSpinner(msg string) *Spinner

NewSpinner returns a Spinner bound to this Context's stderr, theme, and glyph set. It animates only on an interactive color TTY.

func (*Context) OK

func (c *Context) OK(s string) string

OK returns s styled as success (or unchanged when !Color).

func (*Context) Panel

func (c *Context) Panel(title string, lines ...string)

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

func (c *Context) Result(data any, text func()) error

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

func (c *Context) Rule(label string)

Rule prints a horizontal divider spanning the terminal width (capped at 80). A non-empty label is centered within the rule.

func (*Context) Severity

func (c *Context) Severity(s string) string

Severity returns an uppercased, glyph-prefixed, color-coded severity label (e.g. "✗ ERROR") for diagnostics and check output.

func (*Context) Subtitle

func (c *Context) Subtitle(s string)

Subtitle prints a secondary heading in the accent ink.

func (*Context) Success

func (c *Context) Success(s string) string

Success returns a "✓ s" success line (glyph green on a color TTY).

func (*Context) Table

func (c *Context) Table(headers []string, rows [][]string)

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.)

func (*Context) Title

func (c *Context) Title(s string)

Title prints a styled section heading (e.g. "▸ repos").

func (*Context) Tree

func (c *Context) Tree(root TreeNode)

Tree prints root's label, then its descendants as an indented tree using the active branch glyphs (├─ └─ │). Connectors are dimmed on a color TTY.

func (*Context) Warning

func (c *Context) Warning(s string) string

Warning returns a "⚠ s" warning line.

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).

func Fail

func Fail(exit int, code, message, hint string) *Error

Fail builds a deterministic Error for a command to return.

func (*Error) Error

func (e *Error) Error() string

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.

func (*Progress) Done

func (p *Progress) Done(msg string)

Done clears the bar and prints a final "✓ msg" line (or nothing if msg is empty).

func (*Progress) Set

func (p *Progress) Set(n int, label string)

Set repaints the bar at step n (clamped to [0,total]) with a trailing label.

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.

func (SchemaCmd) Run

func (SchemaCmd) Run(c *Context, k *kong.Kong) error

Run emits the reflected schema. clikit.Run binds the *kong.Kong.

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.

func BuildSchema

func BuildSchema(k *kong.Kong, tool, version string) SchemaDoc

BuildSchema reflects a parsed Kong model into a SchemaDoc.

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) Fail

func (s *Spinner) Fail(msg string)

Fail stops the spinner and replaces it with a "✗ msg" line.

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.

func (*Spinner) Success

func (s *Spinner) Success(msg string)

Success stops the spinner and replaces it with a "✓ msg" line.

func (*Spinner) Update

func (s *Spinner) Update(msg string)

Update changes the message shown next to the spinner.

type TreeNode

type TreeNode struct {
	Label    string
	Children []TreeNode
}

TreeNode is one node in a Tree: a label and zero or more children.

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).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL