app

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Aug 1, 2026 License: MIT Imports: 18 Imported by: 0

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

func Main(argv []string) int

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

func Run(ctx context.Context, o Options) error

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.

func (ExitError) Error

func (e ExitError) Error() string

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.

Jump to

Keyboard shortcuts

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