output

package
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Apr 22, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ExitOK        = 0 // success
	ExitGeneric   = 1 // unclassified failure (reserved for anything we don't map)
	ExitAuth      = 2 // 401 — user must re-authenticate
	ExitForbidden = 3 // 403 — authenticated but lacks scope / ownership
	ExitNotFound  = 4 // 404
	ExitInvalid   = 5 // 400 validation
	ExitConflict  = 6 // 409
	ExitRateLimit = 7 // 429
	ExitAPI       = 8 // 5xx, network, timeout, malformed response
)

Exit codes — keep this table in lock-step with the one in PLAN-CLI.md §7 and the reference CLI projects (basecamp-cli, fizzy-cli, hey-cli).

Agents branch on these in wrapper scripts; changing a value breaks their scripts silently. Only add new codes, never renumber.

Variables

This section is empty.

Functions

func ExitCodeFor

func ExitCodeFor(err error) int

ExitCodeFor maps any error returned by a command to the table above.

Resolution order:

  1. nil error → ExitOK
  2. *api.Error (HTTP status known) → matched by status
  3. network / URL errors, DNS failures → ExitAPI
  4. unknown / typed CLI errors → ExitGeneric

Callers just do `os.Exit(output.ExitCodeFor(err))`.

func PrintTable

func PrintTable(w io.Writer, headers []string, rows [][]string)

PrintTable renders a simple fixed-width table to w. Column widths are calculated automatically from headers and data.

Types

type Breadcrumb struct {
	// Action is a short intent tag — agents route on this.
	// Conventions: "view", "edit", "retry", "revert", "share", "delete",
	// "list", "open", "configure", "docs".
	Action string `json:"action"`

	// Cmd is the exact shell-ready command string, including the `pura `
	// prefix. Must be runnable verbatim. Placeholders in angle brackets
	// (e.g. `<slug>`) are acceptable when a real value isn't known yet.
	Cmd string `json:"cmd"`

	// Description is a one-sentence rationale. Optional but recommended.
	Description string `json:"description,omitempty"`
}

Breadcrumb describes one suggested follow-up command.

type Envelope

type Envelope struct {
	OK          bool         `json:"ok"`
	Data        any          `json:"data,omitempty"`
	Summary     string       `json:"summary,omitempty"`
	Breadcrumbs []Breadcrumb `json:"breadcrumbs,omitempty"`
	Error       any          `json:"error,omitempty"`
	Meta        any          `json:"meta,omitempty"`
}

Envelope is the full response wrapper. Fields use `omitempty` so absent ones disappear from the JSON — keeps small responses small.

func NewError

func NewError(code, message, hint string, opts ...Option) Envelope

NewError creates a failure envelope. Breadcrumbs on errors are especially valuable for agents — e.g. "auth_required" naturally pairs with a `pura auth login` breadcrumb.

func NewOK

func NewOK(data any, opts ...Option) Envelope

NewOK creates a success envelope with optional summary / breadcrumbs / meta.

Simple case: NewOK(data) With summary: NewOK(data, WithSummary("Published %s", slug)) Full: NewOK(data,

WithSummary("…"),
WithBreadcrumb("view", "pura open abc", "Open in browser"),
WithBreadcrumb("edit", "pura chat abc \"…\"", "AI-edit"))

type ErrorDetail

type ErrorDetail struct {
	Code    string `json:"code"`
	Message string `json:"message"`
	Hint    string `json:"hint,omitempty"`
}

ErrorDetail is the structured error body.

type Format

type Format int

Format controls how output is rendered.

const (
	FormatAuto  Format = iota // Styled if TTY, JSON if piped
	FormatJSON                // Always JSON envelope
	FormatQuiet               // Raw data only, no envelope
)

type Option

type Option func(*Envelope)

Option mutates an Envelope during construction. Pass via NewOK / NewError or via the variadic params on Writer.OK / Writer.Error.

Why functional options: call sites stay terse when there's nothing extra to say, but can layer on summary + breadcrumbs without a builder chain.

func WithBreadcrumb

func WithBreadcrumb(action, cmd, description string) Option

WithBreadcrumb appends a single suggested next command.

func WithBreadcrumbs

func WithBreadcrumbs(crumbs ...Breadcrumb) Option

WithBreadcrumbs appends several suggestions at once.

func WithMeta

func WithMeta(meta any) Option

WithMeta attaches arbitrary meta (timings, pagination, …).

func WithSummary

func WithSummary(format string, args ...any) Option

WithSummary attaches a one-line human-readable summary.

type Writer

type Writer struct {
	Out      io.Writer
	Err      io.Writer
	Format   Format
	IsTTY    bool
	JQFilter string // jq expression to filter JSON output
}

Writer handles output formatting.

func NewWriter

func NewWriter(format Format) *Writer

NewWriter creates a Writer with auto-detected TTY.

PURA_FORCE_STYLED=1 forces IsTTY=true so tests can assert the styled human-readable output without wiring a pseudo-terminal. Opposite escape: normal prod detection is via term.IsTerminal on stdout's fd.

func (*Writer) Error

func (w *Writer) Error(code, message, hint string, opts ...Option)

Error outputs an error message. Like OK, accepts options — mostly used to attach a "retry" breadcrumb such as `pura auth login`.

func (*Writer) JSON

func (w *Writer) JSON(data any)

JSON outputs raw JSON data (for --quiet mode or piping).

func (*Writer) OK

func (w *Writer) OK(data any, opts ...Option)

OK outputs successful data. Accepts optional envelope Options (summary, breadcrumbs, meta) — agents consume those to decide the next step.

In --quiet mode we emit just the `data` payload (no envelope) because quiet is meant for raw piping; the breadcrumbs are still available to callers who use --json.

func (*Writer) Print

func (w *Writer) Print(format string, args ...any)

Print writes a formatted string to stdout (styled mode only).

func (*Writer) Println

func (w *Writer) Println(args ...any)

Println writes a line to stdout (styled mode only).

Jump to

Keyboard shortcuts

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