Documentation
¶
Overview ¶
Package app is nib's entrypoint, importable so nib can be embedded in another binary. nib's own main.go is a thin wrapper over Main.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Main ¶
Main runs nib and returns a process exit code. argv is the full argument vector including the program name. It routes through the same code as Run, so the process-wide xlog side effect noted there applies here too.
func Run ¶
Run runs nib and returns an error. It never calls os.Exit.
Every failure comes back as a bare ExitError carrying nothing but an exit code, the cause having been written to Stderr instead: an unparseable flag, an unknown --init shell, an MCP transport failure, the setup abort, the injected-stream refusal and a management subcommand's non-zero code are all indistinguishable to the caller. The code is 1 for every one of those except an unparseable flag, which is 2 and the only non-1 code runCtx produces.
Run also reconfigures the process-wide xlog logger from the resolved config, which an embedder sharing that logger will observe.
Types ¶
type ExitError ¶
type ExitError struct{ Code int }
ExitError carries a non-zero exit code out of Run.
type Options ¶
type Options struct {
// Args are the arguments after the program name (os.Args[1:]).
Args []string
// ProgramName is the name shown in the messages this package prints itself:
// the --version line, the flag package's usage and parse errors, the setup
// gate's two aborts, and the injected-stream refusal. Empty means "nib".
//
// It reaches nothing else, so parts of an embedded nib still say "nib"
// whatever this is set to: the management subcommands' usage strings
// ("usage: nib plugin ..." and its skill and mcp equivalents), the --init
// shell snippets, and the "nib: ..." diagnostics that config loading and
// plugin/skill discovery write straight to os.Stderr on every run.
// Threading the name through those is follow-up work.
ProgramName string
// BaseDir overrides the config, plugins, and skills root. Empty means
// nib's default XDG resolution.
BaseDir string
// Stdin, Stdout, Stderr default to the process streams when nil.
//
// CLI mode (--cli) reads and writes exactly these. The TUI, which is the
// DEFAULT mode, does not: it renders on /dev/tty, because the terminal is
// still there even when stdout is a pipe, and serving that case is why it
// opens /dev/tty at all. Only the shell-capture line the TUI prints on exit
// goes to Stdout.
//
// For an embedder that is a rule rather than a caveat: injecting a Stdin or
// a Stdout that is NOT a terminal (a buffer, a pipe, a file) requires --cli,
// or the run is refused with an error saying so, rather than rendering into
// a stream the TUI cannot drive. Injecting the process streams, or any other
// terminal, leaves every mode working.
//
// Only those two are gated (see decideStreamRefusal). A non-terminal Stderr
// is always accepted, because every error this package prints goes through
// o.stderr() rather than through the TUI, so a TUI session with its error
// output captured to a buffer or a log file is a supported combination.
//
// One consequence is worth spelling out, because it inverts the usual
// instinct that passing os.Stdout is the safe, explicit choice. An embedder
// that wants nib's shell-capture idiom, where the user runs
// `out=$(myprog agent)` and the TUI prints the selected command on stdout
// for the shell to capture, must leave Stdout NIL rather than set it to
// os.Stdout. Nil means "not injected": nib falls back to the process stream,
// the TUI runs, and the capture line lands on stdout as it should. Setting
// os.Stdout explicitly injects whatever stdout happens to be, and under
// $(...) that is a pipe, so the run is refused for a stream nib would have
// used anyway.
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
// Defaults seed config fields the config file leaves empty. Every field of
// types.Config is seedable except BaseDir, which is ignored: the root has
// exactly one knob, the BaseDir field above, and it overwrites any seeded
// value. See config.LoadOptions.Defaults for what "empty" means for maps,
// slices and booleans, including that a seeded true beats an explicit
// `false:` in the config file for every bool.
Defaults types.Config
// SkipSetup suppresses the first-run model wizard. Embedders that resolve
// the model themselves set this. It suppresses the whole gate, so an
// explicit --setup in Args becomes a silent no-op rather than an error.
SkipSetup bool
// SkipBareEnv suppresses the bare MODEL / API_KEY / BASE_URL variables, and
// only those three. nib's prefixed variables keep reading the ambient
// environment and still outrank a seed: NIB_TRACE_DIR overrides a seeded
// TraceDir, NIB_YOLO forces ApprovalMode to "auto" over a seeded one, and
// LOG_FORMAT selects the log encoding.
SkipBareEnv bool
}
Options configures a nib invocation. The zero value reproduces standalone nib's behavior exactly, so embedders opt in to each difference.