Skip to content

lm — CLI & TUI reference

lm is the integrator's single binary: a kubectl-style CLI plus a k9s-style TUI. This page maps the whole surface; every command also self-documents via lm <cmd> --help.

Global flags on every command: --context / --server / --token (override the current context), -o table|json|yaml, -v. (Three exceptions redefine -o as an output file path: lm source rest from-openapi, lm view get, lm view generate.)

Context & auth

Command What it does
lm config set-context NAME --server URL --oidc-issuer URL create/update a context (--oidc-client-id defaults to lm-cli, the bundled realm client)
lm config use-context NAME switch context
lm config view print ~/.lm/config.yaml
lm login OIDC device flow: prints a URL + code, stores tokens in the context
lm version binary version

First run? The deploy page walks through standing up a hub and pointing lm at it.

Environment & TLS

Two env vars override fields of the resolved context — CI-friendly, no lm login needed: LUMNIK_URL replaces the server, LUMNIK_TOKEN the Bearer token. A context must still exist and be current (lm config set-context ci --server … && lm config use-context ci, once); the env vars swap its values per run, they don't replace it.

Two TLS fields are hand-edited in ~/.lm/config.yaml (not set-context flags): ca-file: /path/to/root.crt trusts an internal CA (the TLS façade's LAN certificate), insecure-skip-verify: true disables verification entirely. When both are set, ca-file wins — trusting a CA is the safer intent.

The tenant: / user: context fields exist too, but they only work against dev-bypass hubs (sent as X-Tenant-ID / X-User-ID headers); a real hub ignores them.

Manifests (all kinds)

Command What it does
lm validate -f FILE validate without applying — field-by-field errors, exit code 1 on error
lm apply -f FILE apply a connector manifest
lm entity apply -f FILE apply a kind: Entity fusion manifest
lm process apply -f FILE / lm process list apply/list kind: Process notify rules
lm workflow apply -f FILE apply a kind: Workflow lifecycle — prints the data-truth report
lm describe connector-type KIND field reference for a connector kind

Connectors, endpoints, sources

Command What it does
lm connector list/get/apply/delete manage connector instances (apply -f = same upsert as lm apply; delete purges connector.t_* tables + registry rows; REST ext.* hybrid tables are kept)
lm connector run NAME trigger an immediate run
lm connector pause/resume NAME stop/restart scheduling
lm connector tag ls/set/add/rm · retag manage tags (scopes); retag propagates to existing chunks
lm endpoint enable/disable/reset-cursor/purge C/E per-endpoint scheduler + cursor; purge deletes the endpoint's ext.* rows (--force skips the prompt)
lm source rest test/probe/from-openapi probe a REST source, generate a manifest from OpenAPI (from-openapi URL --name N required; --tag repeatable, -o FILE writes to a file, --apply upserts straight to the hub; source rest run is a stub — use lm connector run)
lm source jdbc … test/discover a JDBC source, list tables
lm source schema --scope TAG / lm source rediscover --scope TAG show / rebuild the scope's SchemaCard (--scope is required)
lm csv ingest FILE\|sftp://…\|s3://… one-shot CSV ingest (dormant connector, ext.* table, RAG chunks) — full SFTP/S3 flag surface: see File sources

Data, runs & honesty

Command What it does
lm run list/get ID connector runs (records in/out, per-run transparency) (list: --connector NAME, --limit N)
lm dlq list/get ID dead-letter entries (reason + offending row) (--connector / --run filter every subcommand; list --limit N)
lm dlq replayed/discard ID mark an entry handled (replayed --new-run-id RUN links it to the run that replayed it)
lm data tables / lm data row HASH dynamic tables; the raw row behind a citation
lm mapping list/get/apply mapping templates + per-tenant overrides (get --raw = the raw template YAML; apply -f FILE)
lm secret set/list/describe/rm encrypted-at-rest secrets; values never returned (set NAME - reads stdin; set --description "…"; rm --force skips the prompt)

Ask your data

Command What it does
lm ask [--scope S] "question" analytic text-to-SQL over the fused hub — prints the answer and the SQL that ran (the five guards apply); a scope-bound user must name a granted scope or gets 403 scope not granted
lm chat interactive REPL chat — in-REPL commands: :corpus NAME (or all), :topK N, :clear, :help, :exit
lm scopes / lm scope / lm scope set TAG list scopes (a scope-bound user sees only their granted métiers); show/set your default
lm rag search/status/reindex semantic search (--top-k N, default 5); corpus status; full re-index

The apps ladder

Command What it does
lm view -f FILE [--filter …] render a kind: View list — filters: col=v · col~text · col>v (>= < <=, number/ISO date); repeatable (AND)
lm view KEY -f FILE one record's detail (with the _conflicts ledger)
lm view generate SCOPE "DESCRIPTION" [-o FILE] ask the AI to write a kind: View manifest over a scope; review, then render with lm view -f. Refusals (abstention / failed generation) surface verbatim as errors
lm view list [--scope S] list the saved views visible to the caller (scope-bound reads apply)
lm view get NAME [-o FILE] fetch one saved view's manifest YAML — to stdout, or to a file
lm view apply -f FILE validate and upsert a kind: View manifest into the saved-view store
lm workflow apply -f FILE declare a kind: Workflow lifecycle; prints the data-truth report — values in the column the manifest never declared, and declared states never seen. Never blocks
lm workflow list the tenant's declared lifecycles (name, table, column, scope)
lm workflow get NAME [-o FILE] fetch one workflow's manifest YAML — to stdout, or to a file
lm inbox [--limit N] [--all] recent decision.* events — what needs you
lm inbox ack ID dispose of a decision (idempotent — the ack is an event)

Admin & platform

Command What it does
lm module list installed business modules
lm migration status/apply Flyway status per schema (apply --schema core\|identity\|… — required)
lm hook list/get/apply/delete · reload NAME Kotlin platform hooks (hook generate is a v1.x stub)

The TUI

Bare lm (or lm ui) launches the k9s-style TUI. : opens the command palette; the pages are :new :ask :inbox :processes :view :modules :connectors :endpoints :runs :dlq :hooks :migrations :scopes.

Key Where Effect
: / r d y q ? Esc global palette · filter · refresh · describe · yank row · quit · help · close
s :connectors :runs :dlq cycle the sort column
e / R (or ^R) / ^P / Del / t :connectors edit YAML in $EDITOR · run now · pause/resume · delete · edit tags
Enter :connectors REST → its :endpoints; others → its :runs
Enter / Esc :endpoints the endpoint's :runs · back to :connectors
^R / ^D :dlq mark replayed · discard
a / A :inbox ack the selected decision (idempotent) · toggle disposed ([traité])
Enter / e / Esc :new edit the kind's living example in $EDITOR · re-edit after refusals · abandon (buffer kept in a temp file)
e :processes edit the stored manifest through the same validate → apply loop
Enter / f F / g / a / o / r :view record detail (_conflicts ledger) · add/clear server-side filters (honest refusals) · generate from a sentence (AI) · apply the rendered view to the hub store · open another file · refresh
^L :hooks reload
Enter :scopes set the active scope (used by :ask)
Enter / y / e / n :ask run · yank the SQL (OSC52) · export rows to CSV · new question

:runs, :dlq and :inbox live-update.

If your login expires or is rotated mid-session, the TUI raises a session-expired modal — press L to log in again (device flow) and resume where you were; Esc dismisses it.