Documentation
¶
Overview ¶
Package cliutil holds small helpers shared across forge's CLI surface.
The package's first inhabitant is the user-facing error helper. Forge errors that bubble up to the CLI boundary follow a consistent shape so users (humans + LLM agents) always know:
- Which subcommand surfaced the error (the context).
- What concretely failed (the message).
- Optionally, where in the source tree the failure points (file:line).
- A one-line suggestion for the next action (the Fix clause).
The shape:
<context>: <what failed> (at <file:line>). Fix: <one-line suggestion>.
`at <file:line>` and `Fix: ...` are both optional; UserErr drops the clause entirely when its argument is empty rather than padding the message with `at unknown` or `Fix: see docs`. Internal errors (helper → helper) are NOT expected to use this helper — the wrapper's job is only to format the final user-visible boundary.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func StdinIsTTY ¶
func StdinIsTTY() bool
StdinIsTTY reports whether forge's standard input is connected to an interactive terminal.
Forge is an LLM-first tool: the common driver is an agent or CI runner, neither of which has a TTY on stdin. Any code path that would otherwise block on an interactive prompt MUST gate on this helper first. When it returns false the command must NOT prompt — it either applies a safe default (for non-destructive actions) or fails fast with an actionable error that names the flag which avoids the prompt (for destructive ones).
Centralising the check here keeps the TTY policy consistent across the CLI surface and gives us a single seam to override in tests if needed.
func UserErr ¶
UserErr formats a user-facing CLI error as:
<context>: <what> (at <at>). Fix: <fix>.
Both `at` and `fix` are optional; pass "" to omit the corresponding clause cleanly. `context` and `what` are required.
Example:
return cliutil.UserErr("forge pack add api-key",
"pack 'api-key' depends on 'audit-log' which is not installed",
"",
"run 'forge pack add audit-log api-key' (auto-installs in topological order)",
)
func UserErrf ¶
UserErrf is the printf-style sibling of UserErr — `what` is rendered with fmt.Sprintf(format, args...). Use this when the message needs dynamic interpolation (e.g. the failing pack name); use UserErr when the message is a literal string.
func WrapUserErr ¶
WrapUserErr wraps an underlying error with the standard user-facing shape, preserving `errors.Is` / `errors.As` semantics on the inner error. Use this when the inner error already has a meaningful message (e.g. an io.ErrClosedPipe, or a forge/pkg/* sentinel) and you only need to add the context/fix wrapping.
The result reads as:
<context>: <what>: <inner>. Fix: <fix>.
`at` and `fix` may be empty — the corresponding clause drops cleanly.
Types ¶
This section is empty.