CLI
lk is the command-line client to the loopkeep daemon. Install it with the
standalone installer or the desktop app. In an interactive terminal,
lk with no arguments opens the terminal UI; piped or redirected, it
prints its usage. This page is the full command surface, grouped.
Most commands act on a workspace. The target resolves in order:
--workspace <id|path> → the LOOPKEEP_WORKSPACE environment variable → the
current directory.
init, trust, untrust, secret, and export are the exception: they read
and write the current directory only, so --workspace and LOOPKEEP_WORKSPACE
do not redirect them.
Workspace setup
| Command | What it does |
|---|
lk init | Create .loopkeep/ in this workspace (starter policy + one workflow). Idempotent. |
lk trust | Approve the current policy — enables the project policy and automatic triggers. Required again after the policy file changes. |
lk untrust | Stop this workspace's triggers from firing automatically — the same kill switch as the desktop app. Manual and in-flight runs keep going; lk trust re-enables it. |
Daemon
| Command | What it does |
|---|
lk start | Start loopkeepd (alias: up). |
lk stop | Stop it (alias: down). Runs in flight are restored as interrupted on the next start. |
lk restart | Stop, then start. |
lk status | Daemon status. |
Runs
| Command | What it does |
|---|
lk run <workflow> | Run a workflow by hand. |
lk rerun <run> | Run a finished run's workflow again, reusing its trigger context. |
lk runs | List runs. |
lk pause <run> / lk resume <run> | Suspend at the next step boundary / resume. |
lk abort <run> | End a run; the worktree is kept. --rollback resets to the last checkpoint first. |
lk finish <run> | End an attended run you are steering: keep its deliverable if it produced one, otherwise leave it resumable. |
lk take-over <run> [--no-mux] | Drive the run's claude session yourself, interactively. It opens in your preferred multiplexer when one is configured; --no-mux keeps it in the current terminal. |
lk hand-back <run> [--summary <text>] | End the take-over and return the run to running. |
Inbox
| Command | What it does |
|---|
lk inbox [<seq>] | Attentions still waiting on you. With a seq, print just that attention's exact change — the raw diff or command, unformatted and ready to pipe into delta or less, so you can read it before you approve. |
lk watch [--json] [--no-notify] | Stream new attentions as they arrive; rings on ask-first. --json emits NDJSON. Covers every workspace unless --workspace narrows it. |
lk approve <seq> [--steer|--abort|--ack] [--instruction <t>] | Decide a waiting attention. --steer requires an instruction; --abort stops the run; --ack marks a notification as seen. Notifications accept nothing but --ack, and items that need a decision do not accept it. |
lk notify <message> [--url <url>] | Post an external notification into the inbox — for CI hooks and scripts. Markdown supported. |
Triggers
| Command | What it does |
|---|
lk trigger explain [<workflow>] | Print what each workflow's triggers declare and how they resolve here — the repository they bind to, and what me points at. |
lk disable <workflow> / lk enable <workflow> | Turn a workflow's automatic triggers off/on in this workspace. Manual and in-flight runs are unaffected. |
lk pause --all / lk resume --all | Global kill switch: stop triggers from starting new runs in every workspace, and lift it again. Runs already in flight and manual runs keep going. Independent of trust. |
trigger explain reads local files and asks the daemon for your linked
identity; it never asks the Console whether a given event would match. Remote
matching happens in the Console — this tells you what you declared:
triage (.loopkeep/workflows/triage.md)
coalesce: on — a burst is held and run once, carrying every event it stood for
local triggers: schedule
remote triggers:
github issue_comment
repos: kumaaa-inc/loopkeep (from this workspace's git origin)
mentions: me → alice
github issues
repos: kumaaa-inc/loopkeep (from this workspace's git origin)
labels: bug
actions: opened
webhook
hook: deploy
run `lk hooks` to see which hooks exist
remote triggers are matched in the Console; this explains the declaration and how it resolves on this machine
today's delivery drop counts and reasons are available in the Console under Connections
For the gateway's UTC-day counts of where remote delivery stopped, open
Console → Connections. There is no dedicated subcommand for per-event
delivery-stop reasons.
me → alice is the identity the Console reports for this account. When it
cannot be resolved the line says why — the device is not paired, the Console has
not answered yet, or the daemon is not running.
Webhooks
| Command | What it does |
|---|
lk hooks | List your personal webhooks by name and creation date (alias: lk hooks list). |
lk hooks add <name> | Issue a URL for a new hook and print it. This is the only time the URL is shown. |
lk hooks rotate <name> | Replace a hook's URL, keeping the name — workflows that declare it don't change. |
lk hooks rm <name> | Delete a hook; posts to its URL are refused from then on. |
The URL is the credential: whoever holds it can wake your workflows. Declare
hooks with on.webhook — see Triggers.
Policy
| Command | What it does |
|---|
lk policy explain <tool> [paths...] [--tags a,b] [--self <level>] [--workflow <name>] [--command <text>] | Evaluate a hypothetical action and print every matching rule with its layer, file, and the final level. |
lk policy test <tool> [paths...] [--expect <level>] […] | Same evaluation, exit-code driven: with --expect, 0 on match, 1 on mismatch; without it, the final level's rank (auto-approve 0, notify 1, ask-first 2, deny 3). Errors exit ≥ 10. |
Both work without the daemon running — usable in CI.
Secrets
| Command | What it does |
|---|
lk secret set <name> [--value <v>] | Store a secret in the OS keychain (reads stdin without --value). |
lk secret list | List the secret names recorded in this workspace. |
GitHub Agentic Workflows
| Command | What it does |
|---|
lk export <workflow> [--json] | Translate to gh-aw with a green/yellow/red report. The workflow is a name under .loopkeep/workflows/ or a path to a file; --to-gh-aw <workflow> names the same thing. |
lk import <gh-aw-file> | Write a gh-aw file into the workspace as .loopkeep/workflows/<name>.md, keeping its own triggers as written and adding manual so it can always be started by hand. The name comes from the source file; --name <name> overrides it, and an existing workflow is an error unless you pass --force. Prints the path it wrote, any warnings, and the resulting on:. |
Workspaces & configuration
| Command | What it does |
|---|
lk workspaces | List registered workspaces. |
lk workspaces add <path> [--name <n>] / lk workspaces remove <id> | Register / remove a workspace (home cannot be removed). |
lk global-max [<n>] | Get/set the cap on runs in flight across every workspace. |
lk workspace-max [<n>|clear] | Get/set this workspace's own cap on runs in flight (clear removes it; the effective limit is the lower of this and global-max). |
lk retention [<days>|off|never] | Get/set how long finished runs' worktrees are kept. off and never both mean keep them forever. |
lk cleanup | Remove finished runs' worktrees now (checkpoint branches are kept). |
Console
| Command | What it does |
|---|
lk login [--env <name>] | Pair this device with the Console (approved in your browser). --env pairs a non-production environment into its own slot. |
lk logout [--env <name>] | Revoke this device and log out. With --env, only that environment's pairing goes; a bare lk logout removes every pairing this machine holds. |
lk account | Show login state and the Console connection. |
lk connectors | List the GitHub installations and Slack workspaces connected to your account, and the identity each me resolves to. Connect them in the Console. |
lk directory <kind> [--repo owner/name] [--installation <id>] | List the names and ids you can write in a trigger, one per line as name (id). Kinds: slack-users, slack-channels, github-users, github-labels, github-repos, github-workflows. --repo names the repository for github-users, github-labels and github-workflows; --installation names the account for github-repos (the id lk connectors prints). Either flag on a kind that doesn't take it is a usage error. With neither, the GitHub kinds use the repository this workspace points at, and the Slack kinds cover every connected workspace. |
Runtime
| Command | What it does |
|---|
lk update [--check|--rollback|--force] | Update the runtime (lk + loopkeepd + adapter) to the latest release. During an actual update it prints every bundled release note newer than the installed version, so skipped versions remain visible. --check only reports; --rollback returns to the previous version; --force reinstalls the latest release even when you are already on it or ahead of it. Homebrew and desktop-app installs update through that channel instead. |
lk --version | Show the lk version, and the daemon's if it's running. |
Environment variables
| Variable | Meaning |
|---|
LOOPKEEP_WORKSPACE | Default target workspace when --workspace isn't given. |
LOOPKEEP_SOCKET | Daemon socket path (default /tmp/loopkeepd.sock). |
LOOPKEEP_CONFIG | Path to config.yaml, overriding the default location. |
LOOPKEEP_DAEMON_BIN | Explicit loopkeepd binary for lk start. |
LOOPKEEP_CLAUDE_BIN | Explicit claude binary, for when it is installed somewhere loopkeep cannot find. |
NO_COLOR | Set to any value to drop the bold and underline from lk --help. |