Documentation
¶
Overview ¶
Package cli implements the brainjar command-line interface on top of cobra. Commands are registered against a single root command; each command resolves `--home`, loads config, and opens a LocalBackend.
Index ¶
- Constants
- func Execute(ctx context.Context, app *App, args []string) int
- func ExitCodeFor(err error) int
- func NewRootCmd(app *App) *cobra.Command
- func NewUsageError(format string, args ...any) error
- func PrintError(w io.Writer, err error, jsonOut bool)
- func StdinIsTTY() bool
- type App
- func (a *App) Backend() (backend.Backend, error)
- func (a *App) EmitJSON(v any)
- func (a *App) EmitTable(rows [][]string)
- func (a *App) EmitText(format string, args ...any)
- func (a *App) JSON() bool
- func (a *App) LocalBackend() (*backend.LocalBackend, error)
- func (a *App) ReadContent(content, file string) (string, error)
- func (a *App) ResolveHome() (string, error)
- func (a *App) WithBackend(fn func(backend.Backend) error) error
- type IO
- type ProjectScope
- type UsageError
Constants ¶
const ( ExitOK = 0 ExitGeneric = 1 ExitBadUsage = 2 ExitNotFound = 3 ExitConflict = 4 )
Exit codes — stable contract published to scripts and CI.
Variables ¶
This section is empty.
Functions ¶
func Execute ¶
Execute runs the CLI with the given args (usually os.Args[1:]) and returns the exit code. Errors are printed to app.IO.Err; success output has already been written by the command that ran.
func ExitCodeFor ¶
ExitCodeFor maps any error returned by a command to the process exit code the CLI should terminate with.
func NewRootCmd ¶
NewRootCmd builds the cobra tree and returns the root command.
func NewUsageError ¶
NewUsageError returns a UsageError with the given message.
func PrintError ¶
PrintError writes the error to w. In text mode it writes a plain line (plus hint/invalid-refs indented on following lines); in JSON mode it writes a single structured envelope matching apperrors.ToHTTP.
Errors whose Error() returns the empty string are treated as "silent" — they exist only to convey an exit code (e.g. agentExitError from `shell`). Nothing is written for them.
func StdinIsTTY ¶
func StdinIsTTY() bool
StdinIsTTY reports whether the real process stdin is a terminal. CLI commands use this to fail fast when content is expected on a pipe but the user invoked the command interactively without flags.
Types ¶
type App ¶
type App struct {
IO IO
// RemoteHTTPClient overrides the default RemoteBackend transport.
// Set by integration tests so httptest self-signed certs validate;
// production leaves it nil and NewRemote builds a client using the
// system trust store.
RemoteHTTPClient *http.Client
// contains filtered or unexported fields
}
App holds global CLI state shared across commands.
func (*App) Backend ¶
Backend resolves the active context and returns the matching backend: LocalBackend when the context has no URL, RemoteBackend when it does. The caller is responsible for calling Close() when done.
func (*App) EmitJSON ¶
EmitJSON writes v to stdout as a single JSON document. No-op when --json is not set — call EmitText for human output instead.
func (*App) EmitTable ¶
EmitTable writes a tab-aligned table to stdout using text/tabwriter. Each row is a slice of column strings; widths are computed across all rows so columns line up even when per-cell length varies (e.g. `soul=mentor` beside `soul=coach`).
JSON mode is a no-op: callers emit the structured form via EmitJSON before calling this, and the text table is suppressed.
Columns are separated by two spaces in the rendered output (no leading padding, no minwidth). If you need a header row, include it as the first row — it will be aligned with the data.
func (*App) EmitText ¶
EmitText writes a human-readable line to stdout. No-op when --json is set — agents consume EmitJSON output instead.
func (*App) LocalBackend ¶
func (a *App) LocalBackend() (*backend.LocalBackend, error)
LocalBackend opens a LocalBackend unconditionally, regardless of the active context's URL. Filesystem-bound commands (init, reset, hooks, sync, serve) call this instead of Backend() because they can only run against the embedded SQLite. Commands that can work against either backend (soul/persona/rule/brain/compose/status/versions, workspace + api-key management, pack, and mcp) use Backend().
func (*App) ReadContent ¶
ReadContent returns the content for a `create` command. Precedence: --content > --file > stdin. Errors if both flags are set, or if neither is set and stdin is a TTY.
func (*App) ResolveHome ¶
ResolveHome returns the resolved home directory, honoring the flag and environment. Safe to call from any command's RunE.
type IO ¶
IO holds the in/out/err streams a command reads and writes. Tests substitute buffers; the root command wires stdin/stdout/stderr.
type ProjectScope ¶
type ProjectScope struct {
Slug models.Slug
Source string
Root string // absolute path of the git repo root when Source=="git"
Warning string // non-empty when we fell back to workspace for a visible reason
}
ProjectScope reports which project slug the CLI resolved for this invocation and where the resolution came from ("flag", "git", or "" when no project is in play). The source tag is surfaced on `brainjar status` so users can see why the resolved scope is what it is.
type UsageError ¶
type UsageError struct{ Msg string }
UsageError marks a cobra-level usage problem (unknown flag, missing positional arg, mutually-exclusive flags). It maps to ExitBadUsage.
func (*UsageError) Error ¶
func (e *UsageError) Error() string