Documentation
¶
Overview ¶
Package output provides JSON/Markdown output formatting and error handling.
Index ¶
- Constants
- func ExitCodeFor(code string) int
- func IsJQError(err error) bool
- func NormalizeData(data any) any
- func PluralNoun(s string) string
- func RequestID(err error) string
- func TruncationNotice(count, defaultLimit int, all bool, explicitLimit int) string
- func TruncationNoticeWithTotal(count, totalCount int) string
- type Breadcrumb
- type Error
- func AsError(err error) *Error
- func AsGateError(err error) *Error
- func ErrAPI(status int, msg string) *Error
- func ErrAmbiguous(resource string, matches []string) *Error
- func ErrAuth(msg string) *Error
- func ErrForbidden(msg string) *Error
- func ErrForbiddenScope() *Error
- func ErrInterrupted(msg string) *Error
- func ErrJQConflict(flag string) *Error
- func ErrJQNotSupported(command string) *Error
- func ErrJQRuntime(cause error) *Error
- func ErrJQValidation(cause error) *Error
- func ErrNetwork(cause error) *Error
- func ErrNotFound(resource, identifier string) *Error
- func ErrNotFoundHint(resource, identifier, hint string) *Error
- func ErrRateLimit(retryAfter int) *Error
- func ErrTerminated(msg string) *Error
- func ErrUsage(msg string) *Error
- func ErrUsageHint(msg, hint string) *Error
- func WithAuthHint(e *Error) *Error
- type ErrorResponse
- type ErrorResponseOption
- type Format
- type MarkdownRenderer
- type Options
- type Renderer
- type Response
- type ResponseOption
- func WithBreadcrumbs(b ...Breadcrumb) ResponseOption
- func WithContext(key string, value any) ResponseOption
- func WithDiagnostic(s string) ResponseOption
- func WithDisplayData(data any) ResponseOption
- func WithEntity(name string) ResponseOption
- func WithGroupBy(field string) ResponseOption
- func WithMeta(key string, value any) ResponseOption
- func WithNotice(s string) ResponseOption
- func WithStats(metrics *observability.SessionMetrics) ResponseOption
- func WithSummary(s string) ResponseOption
- func WithoutBreadcrumbs() ResponseOption
- type Writer
Constants ¶
const ( ExitOK = clioutput.ExitOK ExitUsage = clioutput.ExitUsage ExitNotFound = clioutput.ExitNotFound ExitAuth = clioutput.ExitAuth ExitForbidden = clioutput.ExitForbidden ExitRateLimit = clioutput.ExitRateLimit ExitNetwork = clioutput.ExitNetwork ExitAPI = clioutput.ExitAPI ExitAmbiguous = clioutput.ExitAmbiguous )
Exit codes matching the Bash implementation (re-exported from shared module).
const ( CodeUsage = clioutput.CodeUsage CodeNotFound = clioutput.CodeNotFound CodeAuth = clioutput.CodeAuth CodeForbidden = clioutput.CodeForbidden CodeRateLimit = clioutput.CodeRateLimit CodeNetwork = clioutput.CodeNetwork CodeAPI = clioutput.CodeAPI CodeAmbiguous = clioutput.CodeAmbiguous )
Error codes for JSON envelope (re-exported from shared module).
const ( CodeValidation = "validation" CodeLimitExceeded = "limit_exceeded" ExitValidation = 9 // Validation error (422) ExitLimit = 10 // Account limit reached (507) )
Codes the shared module does not know yet. The SDK started emitting both at v0.13.0/v0.14.0 (422 validation, 507 account limits); values match the SDK's own exit-code mapping. Local arms below keep them from collapsing into the shared table's ExitAPI default until the shared module catches up.
const ( CodeInterrupted = "interrupted" ExitInterrupted = 130 CodeTerminated = "terminated" ExitTerminated = 143 )
CodeInterrupted marks a command the person stopped with Ctrl-C after it had started waiting on them (a login waiting for approval); CodeTerminated the same stop by a SIGTERM from whatever supervises the process. The command has already said what happened on its own terms, so the root renders nothing more and exits with the shell's conventional status for a process the signal ended.
const ( CodeBusy = "busy" )
CodeBusy marks work another process is doing right now — a profile's credential or connector policy locked by another command — and CodeLockUnavailable a host that cannot lock at all, so a command whose guarantee is the lock refuses to run. Both are the caller's cue to try again (the first shortly, the second after fixing the host), which is what the rate-limit status says in this table.
const DefaultAuthHint = "Run: basecamp auth login"
DefaultAuthHint is the remedy an auth_required error carries when nothing closer to the credential has named one. The app boundary (appctx.App.Err) replaces it with a remedy that knows the active profile and whether BASECAMP_TOKEN is in play; this is the floor beneath that.
Variables ¶
This section is empty.
Functions ¶
func ExitCodeFor ¶
ExitCodeFor returns the exit code for a given error code.
func IsJQError ¶ added in v0.7.0
IsJQError returns true if the error is a jq-related error (validation failure, unsupported command, or flag conflict).
func NormalizeData ¶
NormalizeData converts json.RawMessage and other types to standard Go types.
func PluralNoun ¶ added in v0.7.0
PluralNoun returns a simple English plural for tool-related nouns. Handles the sibilant cases we encounter (inbox → inboxes) and falls back to appending "s".
func TruncationNotice ¶
TruncationNotice returns a notice string if results may be truncated.
func TruncationNoticeWithTotal ¶
TruncationNoticeWithTotal returns a truncation notice using totalCount from the API.
Types ¶
type Breadcrumb ¶
type Breadcrumb struct {
Action string `json:"action"`
Cmd string `json:"cmd"`
Description string `json:"description"`
}
Breadcrumb is a suggested follow-up action.
type Error ¶
Error is a structured error with code, message, and optional hint. Type alias — zero-cost, full compatibility with errors.As.
func AsError ¶
AsError converts err to the CLI's structured error. An *Error already in the chain is the CLI's own verdict and wins over the SDK error it may wrap as its cause; only a bare SDK error is converted from its taxonomy.
func AsGateError ¶ added in v0.12.0
AsGateError converts a resilience gate rejection, which arrives through any SDK operation, into the rate-limit error the user sees: the gate's own message and hint (which limit, how long it waited, what to do), retryable. Nil when err is not a gate rejection.
func ErrAmbiguous ¶
func ErrForbidden ¶
func ErrForbiddenScope ¶
func ErrForbiddenScope() *Error
func ErrInterrupted ¶ added in v0.12.0
ErrInterrupted reports a command stopped by the person at the terminal. msg is for machine consumers; the command prints its own human line.
func ErrJQConflict ¶ added in v0.7.0
ErrJQConflict returns a usage error for flags that conflict with --jq.
func ErrJQNotSupported ¶ added in v0.7.0
ErrJQNotSupported returns a usage error for commands that don't support --jq.
func ErrJQRuntime ¶ added in v0.7.0
ErrJQRuntime returns a usage error for jq runtime failures (e.g. type errors, non-serializable results).
func ErrJQValidation ¶ added in v0.7.0
ErrJQValidation returns a usage error for invalid --jq expressions.
func ErrNetwork ¶
func ErrNotFound ¶
func ErrNotFoundHint ¶
func ErrRateLimit ¶
func ErrTerminated ¶ added in v0.12.0
ErrTerminated reports a command stopped by a SIGTERM while it waited. msg is for machine consumers; the command prints its own human line.
func ErrUsageHint ¶
func WithAuthHint ¶ added in v0.12.0
WithAuthHint adds the login remedy to an auth_required error that has none. A 401 from the API and the SDK's own auth errors arrive without a hint, and "authentication required" alone leaves the reader to guess what to run. Errors that already carry a hint, or are not auth errors, pass through untouched; a hinted copy is returned so the caller's error is not rewritten under it.
type ErrorResponse ¶
type ErrorResponse struct {
OK bool `json:"ok"`
Error string `json:"error"`
Code string `json:"code"`
Retryable bool `json:"retryable"`
Hint string `json:"hint,omitempty"`
Meta map[string]any `json:"meta,omitempty"`
}
ErrorResponse is the error envelope for JSON output.
Retryable is always present on an error envelope and never on a success one: true when the failure was classified transient (network, timeout, rate limit, circuit open, bulkhead full, and most 5xx/gateway responses — not all: 507 and a raw-client 500 are verdicts), false for a verdict (usage, not found, auth, forbidden, validation, account limit) and for any error nothing classified. Consumers key on the field rather than on the code or message, which describe the failure and not whether a retry can change it.
type ErrorResponseOption ¶
type ErrorResponseOption func(*ErrorResponse)
ErrorResponseOption modifies an ErrorResponse.
func WithErrorStats ¶
func WithErrorStats(metrics *observability.SessionMetrics) ErrorResponseOption
WithErrorStats adds session metrics to the error response metadata.
type MarkdownRenderer ¶
type MarkdownRenderer struct {
// contains filtered or unexported fields
}
MarkdownRenderer outputs literal Markdown syntax (portable, pipeable).
func NewMarkdownRenderer ¶
func NewMarkdownRenderer(w io.Writer) *MarkdownRenderer
NewMarkdownRenderer creates a renderer for literal Markdown output.
func (*MarkdownRenderer) RenderError ¶
func (r *MarkdownRenderer) RenderError(w io.Writer, resp *ErrorResponse) error
RenderError renders an error response as literal Markdown.
func (*MarkdownRenderer) RenderResponse ¶
func (r *MarkdownRenderer) RenderResponse(w io.Writer, resp *Response) error
RenderResponse renders a success response as literal Markdown.
type Options ¶
type Options struct {
Format Format
Writer io.Writer
ErrWriter io.Writer // Notices stdout cannot carry (see write); defaults to os.Stderr.
Verbose bool
JQFilter string // jq expression to apply to JSON output (built-in via gojq)
}
Options controls output behavior.
func DefaultOptions ¶
func DefaultOptions() Options
DefaultOptions returns options for standard output.
type Renderer ¶
type Renderer struct {
// Text styles
Summary lipgloss.Style
Muted lipgloss.Style
Data lipgloss.Style
Error lipgloss.Style
Hint lipgloss.Style
Warning lipgloss.Style
Success lipgloss.Style
Subtle lipgloss.Style // for footer elements (most understated)
// Table styles
Header lipgloss.Style
Cell lipgloss.Style
CellMuted lipgloss.Style
// contains filtered or unexported fields
}
Renderer handles styled terminal output.
func NewRenderer ¶
NewRenderer creates a renderer with styles from the resolved theme. Styling is enabled when writing to a TTY, or when forceStyled is true. Theme resolution follows: NO_COLOR env → BASECAMP_THEME env → user theme (~/.config/basecamp/theme/colors.toml, which may be symlinked to system themes) → default.
func NewRendererWithTheme ¶
NewRendererWithTheme creates a renderer with a specific theme (for testing).
func (*Renderer) RenderError ¶
func (r *Renderer) RenderError(w io.Writer, resp *ErrorResponse) error
RenderError renders an error response to the writer with a styled error box.
type Response ¶
type Response struct {
OK bool `json:"ok"`
Data any `json:"data,omitempty"`
Summary string `json:"summary,omitempty"`
Notice string `json:"notice,omitempty"` // Informational message (e.g., truncation warning)
Breadcrumbs []Breadcrumb `json:"breadcrumbs,omitempty"`
Context map[string]any `json:"context,omitempty"`
Meta map[string]any `json:"meta,omitempty"`
Entity string `json:"-"` // Schema hint for presenter (not serialized)
DisplayData any `json:"-"` // Alternate data for styled/markdown rendering (not serialized)
// contains filtered or unexported fields
}
Response is the success envelope for JSON output.
type ResponseOption ¶
type ResponseOption func(*Response)
ResponseOption modifies a Response.
func WithBreadcrumbs ¶
func WithBreadcrumbs(b ...Breadcrumb) ResponseOption
WithBreadcrumbs adds breadcrumbs to the response.
func WithContext ¶
func WithContext(key string, value any) ResponseOption
WithContext adds context to the response.
func WithDiagnostic ¶ added in v0.7.0
func WithDiagnostic(s string) ResponseOption
WithDiagnostic sets a notice that is also emitted to stderr in quiet mode. Use this for degraded-operation warnings (e.g. unresolved mentions) that automation consumers need to detect. Truncation and other informational notices should use WithNotice instead — which still reaches stderr under --ids-only and --count; the distinction is quiet mode, whose stdout already carries the whole payload.
func WithDisplayData ¶ added in v0.2.2
func WithDisplayData(data any) ResponseOption
WithDisplayData provides alternate data for styled/markdown rendering. When set, the presenter uses this instead of Data, keeping Data untouched for JSON serialization. Use this when the response wrapper struct should be preserved for machine consumption but a different shape (e.g. an unwrapped slice) is better for human-oriented output.
func WithEntity ¶
func WithEntity(name string) ResponseOption
WithEntity hints which schema to use for entity-aware presentation.
func WithGroupBy ¶ added in v0.2.2
func WithGroupBy(field string) ResponseOption
WithGroupBy overrides the schema's default group_by field for task list rendering. For example, WithGroupBy("due_on") groups todos by due date instead of project.
func WithMeta ¶
func WithMeta(key string, value any) ResponseOption
WithMeta adds metadata to the response.
func WithNotice ¶
func WithNotice(s string) ResponseOption
WithNotice adds an informational notice to the response. Use this for non-error messages like truncation warnings. Like WithSummary, the value is stored verbatim; terminal sinks sanitize.
Every format renders it: the envelope formats carry it in the response, and the rows-only ones (--ids-only, --count) print it on stderr, since their stdout has no field to carry it in.
func WithStats ¶
func WithStats(metrics *observability.SessionMetrics) ResponseOption
WithStats adds session metrics to the response metadata.
func WithSummary ¶
func WithSummary(s string) ResponseOption
WithSummary adds a summary to the response. The value is stored verbatim so machine (JSON) output preserves the original content; terminal sinks (styled/markdown renderers, quiet-mode stderr diagnostics) sanitize at render time.
func WithoutBreadcrumbs ¶ added in v0.2.0
func WithoutBreadcrumbs() ResponseOption
WithoutBreadcrumbs removes all breadcrumbs from the response.
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer handles all output formatting.
func New ¶
New creates a new output writer. If JQFilter is set, the jq expression is parsed and compiled eagerly so errors surface immediately rather than on the first write.
func (*Writer) EffectiveFormat ¶
EffectiveFormat resolves FormatAuto based on TTY detection.