Skip to content

CLI reference

laura with no subcommand runs the TUI host; with a subcommand it acts as a thin client that sends one message to the current tab's socket ($LAURA_TAB) and exits. Client verbs are silent on success.

Host

laura                   Run the TUI, hosting your default shell in tab 1.
laura -- <cmd> [args]   Run the TUI, hosting <cmd> in tab 1. New tabs still get your shell.

Commands

A tab's panes form a split tree; the shell is pane 0 and can't be closed. Each open splits a pane and prints the new pane id on stdout — capture it to address that pane later.

laura open <path>       Split a pane and render <path> in the new panel. Prints the new pane id.
                        Relative paths resolve against the *calling* process's cwd, so `cd`
                        inside the PTY then `laura open ./x` works. Warns on stderr (still exit 0)
                        when the file can't be read (`cannot read <path>: …`) or the panel doesn't
                        fit (`overflows:` / `too small`), so `laura layout` is confirmatory, not required.
      --split <id>      Pane to split (default: the focused pane).
      --dir <h|v>       Split orientation: h side-by-side, v stacked (default h).
      --ratio <1..99>   Percent of the split given to the new panel (default 50).
      --side <first|second>  Which side the new panel lands on (default second).
      --no-focus        Don't move focus into the panel.
      --follow          Autoscroll: pin the cursor to the last line on open and every reload.
      --dry-run         Print the would-be overflow report; open nothing.
      --highlight <start> [end]  Point at a line range once open (1-based, inclusive); end
                        defaults to start. Opens the panel already scrolled to and reverse-videoing
                        the range — the one-call "show me where" gesture. e.g. `laura open x.rs
                        --highlight 40 52`. (See `laura highlight` to point at an already-open panel.)
      --diff            Open straight into the inline diff view (vs git HEAD).
laura close [<id>]      Close a panel (default: the focused one).
      --all             Close every panel, back to shell-only.
laura focus <id>        Focus a pane by id.
laura highlight <start> [end]
                        Reverse-video lines start..=end (1-based, inclusive) in a panel and
                        scroll them into view. end defaults to start (single line). Line numbers
                        are the file's real source lines (an editor / wc -l / git blame), for
                        markdown too — a source line inside a hand-wrapped paragraph points at
                        that whole block. e.g. `laura highlight 40 52`.
      --pane <id>       Pane to highlight (default: the focused panel).
laura diff              Toggle a panel's inline diff view vs git HEAD (interleaved +/- lines).
      --pane <id>       Pane to toggle (default: the focused panel).
      --off             Turn the diff view off (default: toggle).
laura layout            Print the layout: per-pane rects + overflow (JSON).
laura ready             Mark the tab as hosting an agent (enables review submission). Prints the journal path.
      --session <id>    Name the journal session (default: laura-<pid>-<n>).
      --agent <name>    Attribute journal events to this agent name.
laura feedback          Append a feedback signal (layout/render quality, a missing tool) to the journal.
      --positive        Positive signal.        (one of --positive/--negative is required)
      --negative        Negative signal.
      [<body>]          Optional free-text note.
some-cmd | laura tail   Spool piped stdin to an internal file and show it in a live panel.
      --title <t>       Panel title (also names the spool file).
      --follow          Autoscroll to the newest line as output arrives.

Commands require $LAURA_TAB to be set — i.e. run them from inside a Laura-hosted shell. Outside a tab they error with not inside a Laura tab (LAURA_TAB unset).

layout and open --dry-run both emit a JSON report — one entry per pane with its rect and overflow, so the agent can size a panel before (or without) committing:

{
  "area": {"x": 0, "y": 1, "width": 120, "height": 39},
  "panes": [
    {"id": 0, "kind": "pty",   "path": null,       "rect": {"x":0,"y":1,"width":48,"height":39},
     "content_rows": null, "visible_rows": 37, "overflow_rows": 0,  "clipped": false},
    {"id": 1, "kind": "panel", "path": "spec.md",  "rect": {"x":48,"y":1,"width":72,"height":39},
     "content_rows": 120, "visible_rows": 37, "overflow_rows": 83, "clipped": true}
  ]
}

overflow_rows > 0 (or clipped) means the panel is taller than its pane — widen/reshape the split or lower --ratio until it fits. A real open (not just --dry-run) surfaces the same condition as a terse overflows: / too small line on stderr, so you rarely need to call layout after opening.

Journal

ready names a per-session append-only NDJSON journal and prints its path. Every open/close/focus/review/feedback event is teed to it, so a session is auditable after it ends. Each event is stamped with ts (unix ms), session, agent (when set), and version — the build that emitted it: X.Y.Z+<commit> off a git checkout, bare X.Y.Z off a tarball, so events are attributable to a build across machines. Files live under the OS data dir (%APPDATA% / $XDG_DATA_HOME / ~/Library/Application Support) at laura/sessions/<session>.ndjson, overridable with LAURA_DATA_DIR. It's just files: cat "$(ls -t <dir>/laura/sessions/*.ndjson | head -1)" | jq ..

Global

laura --help            Print help (also per-subcommand: laura open --help).
laura --version         Print version.

The wire messages behind these verbs are documented in the protocol.