The terminal UI

Run lk with no arguments in an interactive terminal and it opens a full-screen dashboard: the same inbox, runs, workflows, and policies the desktop app shows, without leaving your terminal. It's a first-class way to drive loopkeep, equal to the CLI and the desktop app — the daemon runs underneath all three. Piped or redirected, lk prints its usage instead, so scripts and lk | … keep working.

lk        # opens the dashboard in an interactive terminal

Views

Five views run across the top, each scoped to the selected project:

ViewWhat's in it
InboxAttentions waiting on you, plus the history of past ones.
RunsEvery run and its state — open one for its event timeline.
WorkflowsThe project's workflows: run, edit, or toggle their auto-triggers.
PoliciesThe project and personal policy, editable rule by rule.
SettingsConcurrency caps, worktree retention, and the global pause switch.

Inbox, Policies, and Settings each carry two sub-tabs — Pending / History, Project / Personal, and Global / Project.

Getting around

KeysAction
Tab Shift+TabNext / previous view
h lSwitch sub-tab
j k, Move within the list
EnterOpen or edit the selected item
gToggle scope — this project only, or every one
?Show the full key list
qQuit

What a selection does depends on the view. a approve, s steer and d deny act on an attention, so they work on the Inbox's Pending tab and inside an open run — not on the resolved items under History. When an attention carries a raw diff or command, Enter opens it full-screen (j/k scroll, esc closes) — and approving waits until you have opened it, so you never approve a change you haven't seen. t takes over a run, from the Runs list or from inside an open run. In Workflows: r run now, n new, space enable or disable its auto-triggers, e open in $EDITOR. In Policies: n adds a rule and x deletes the selected one. Settings lists the project's workflows on its Project sub-tab, where space toggles auto-triggers as well.

The keys are configurable — set tui.keybindings in config.yaml (see Daemon & configuration). The mouse works too; m toggles mouse capture when you'd rather select text.

Editing workflows and policies

Open a workflow with Enter and you get a structured form with two sub-tabs. Settings holds its frontmatter execution settings — model, budgets, concurrency, and execution mode — with dropdowns for the choice fields, so there's no allowed value to remember. It also edits the Slack safe-output declarations: a required channel and optional workspace for fixed-destination posts, plus the separate same-thread reply enabled/disabled selector. Other safe-output keys are preserved. Open a policy rule and you get the same field-by-field editor, one rule at a time.

Triggers edits the on: block: cron, file-watch, git, run-completed and manual, plus GitHub, Slack and webhook with their events, alternative condition sets, and per-event filters. Everything is one indented list — Enter opens the row under the cursor, x removes what it points at, and n adds a trigger. In a picker, type to narrow a long list, space ticks a value when a field takes several, and Enter saves.

Where a value names a person, channel, label or repository, the picker lists them by name and writes the id. Those names come from the accounts this device is connected to; when they can't be fetched, the field stays free text, and an app you haven't connected gets a note saying its events won't arrive here. It never stops you writing the declaration.

Anything the form can't represent — bare GitHub event keys, signed webhooks — is carried through your edits untouched, and the tab says so. Comments inside the on: block are the exception: saving from the form drops them, and the tab warns you before you do. To edit the raw file instead, e opens the workflow's Markdown and frontmatter, or the policy's YAML, in your $EDITOR. Save and close, and the TUI re-reads and re-validates it.

Next steps