CLI reference
Every lich command. The same content is what lich --help and lich <command> --help print — when you're at a terminal, the CLI itself is the most up-to-date source.
lich up
Bring the current worktree's stack up.
Usage: lich up [profile]
Bring the current worktree's stack up. Starts every compose service
and owned process declared by the active profile, runs lifecycle
hooks, and prints a summary with the resolved URLs.
With no argument, activates the default profile. Pass a profile
name to activate it explicitly.
Flags:
--json Emit machine-readable progress on stdout.
--quiet Suppress progress; print final summary only.
--no-browser Skip opening the dashboard in the browser.
--raw Print raw localhost URLs in the summary.
Exit codes: 0 on success, non-zero on any failure.lich down
Stop the current worktree's stack and release resources.
Usage: lich down [--worktree <id-or-name>]
Stop the current worktree's stack. Tears down every compose service
and owned process, runs before_down lifecycle hooks, and releases
allocated host ports. State directory is preserved.
Flags:
--json Emit machine-readable progress on stdout.
--quiet Suppress progress; print final summary only.
--worktree <id-or-name> Target a stack by ID or worktree name instead
of the current directory (see `lich stacks`).
Exit codes: 0 on success, non-zero on failure.lich restart
Restart the stack (or selected services).
Usage: lich restart [service ...] [--worktree <id-or-name>]
Restart the whole stack, or the named services only. Respects
depends_on ordering.
Flags:
--json Emit machine-readable progress on stdout.
--quiet Suppress progress; print final summary only.
--worktree <id-or-name> Target a stack by ID or worktree name instead
of the current directory (see `lich stacks`).lich logs
Stream logs from the stack's services.
Usage: lich logs [service] [--tail=N] [--no-follow] [--worktree <id-or-name>]
Stream logs from the stack's services. Defaults to tailing all
services with --follow. Pass a service name to filter to one.
Flags:
--tail=N Show the last N lines (default 50 with --follow,
200 with --no-follow).
--no-follow Print existing logs and exit; do not stream.
--worktree <id-or-name> Target a stack by ID or worktree name instead
of the current directory (see `lich stacks`).lich urls
Print the reachable URLs for the running stack.
Usage: lich urls [--raw] [--worktree <id-or-name>]
Print every reachable URL for the running stack. By default emits
the friendly <service>.<worktree>.lich.localhost:<proxy-port>
form; --raw prints the underlying localhost:<allocated-port> URLs.
Flags:
--raw Emit raw localhost URLs instead of friendly form.
--worktree <id-or-name> Target a stack by ID or worktree name instead
of the current directory (see `lich stacks`).lich dashboard
Open the lich dashboard in the default browser.
Usage: lich dashboard [--no-browser]
Open the lich dashboard (http://lich.localhost:<proxy-port>/) in
the default browser. Auto-starts the daemon if needed; can be run
from any directory.
Flags:
--no-browser Print the URL only; skip the browser open.
(Also honored via LICH_NO_BROWSER=1.)
Exit codes: 0 on success; non-zero if the daemon fails to start
or its reverse proxy is unavailable.lich stacks
List every running lich stack on this machine.
Usage: lich stacks [--json]
List every lich stack currently running on this machine, with
worktree name, status, and uptime. --json emits machine-readable
output.
Both renderers read from the same in-memory snapshot — every value
shown in the table is derivable from --json.
JSON shape (array; one entry per stack, sorted by worktree_name):
[
{
"stack_id": string, // opaque ID, stable across `up`s
"worktree_name": string, // basename of the worktree dir
"status": "starting" | "up" | "partial" | "stopping" |
"stopped" | "failed",
"lifecycle"?: { // present iff lifecycle hooks ran
"before_up"?: PhaseStatus,
"after_up"?: PhaseStatus,
"before_down"?: PhaseStatus,
"after_down"?: PhaseStatus
},
"started_at": string, // ISO 8601 timestamp
"uptime_seconds": number,
"services": [
{
"name": string,
"kind": "owned" | "compose",
"state": "starting" | "healthy" | "initializing" |
"ready" | "stopping" | "stopped" | "failed"
}
],
"primary_url"?: string, // first service with allocated ports
"active_profile"?: string // omitted if no profile was active
}
]
PhaseStatus =
{ "status": "ok" }
| { "status": "not_run" }
| {
"status": "failed",
"failed_index": number, // zero-based
"total": number,
"failed_cmd": string, // truncated to 80 chars + "..."
"log_path": string // per-phase log file
}
Types live in packages/lich/src/state/snapshot.ts:
StackSnapshot, ServiceSnapshot, StackStatus, ServiceState,
LifecyclePhaseStatus, LifecycleSnapshotStatuslich top
Live per-service CPU + memory view (table or JSON).
Usage: lich top [--no-follow] [--json] [--all] [--worktree <id-or-name>]
[--tree <service>] [--sort cpu|mem|name] [--interval N]
Live per-service CPU + memory view. Follows by default, refreshing
every 2s; Ctrl-C exits cleanly. Owned services aggregate the full
process tree (parent + forked workers); compose services pull from
`docker stats`.
Flags:
--no-follow Print one snapshot and exit (default: follow).
--json Machine-readable; implies --no-follow.
--all Every running stack on this machine.
--worktree <id-or-name> Target another worktree's stack.
--tree <service> Expand the process tree for one owned service.
--sort cpu|mem|name Service sort order (default: cpu).
--interval N Refresh interval in seconds (default: 2).
JSON shape:
{
"stack_id": string,
"sampled_at": string (ISO 8601),
"total": { "cpu_pct": number, "mem_bytes": number },
"services": [
{
"name": string,
"kind": "owned" | "compose",
"state": string,
"pid"?: number, // owned only
"container_id"?: string, // compose only
"cpu_pct": number,
"mem_bytes": number,
"mem_limit_bytes"?: number, // compose only
"uptime_seconds": number,
"process_count"?: number // owned only
}
]
}
Note: the first sample of any owned service shows 0% CPU until the
second sample lands (ps's CPU% is cumulative; the daemon diffs across
two samples to derive current).
Exit codes: 0 on success; 1 if the daemon is unreachable; 2 on usage
error.lich nuke
Stop every lich stack on this machine and clean state.
Usage: lich nuke [--yes] [--rescue]
Stop every lich stack on this machine and clean their state
directories. --rescue scans ~/.lich/started.log and runs idempotent
cleanup for resources state.json no longer references. --yes skips
the confirmation prompt.lich validate
Statically analyse a lich.yaml without running anything.
Usage: lich validate [path] [--json]
Statically analyse a lich.yaml without running anything. Catches
schema errors, unknown depends_on references, dependency cycles,
broken regexes, and bad ${...} interpolations.
Exit 0 if clean, 1 otherwise.lich init
Write a starter lich.yaml in the current directory.
Usage: lich init [--force] [--no-gitignore]
Write a starter lich.yaml in the current directory. Also appends
.lich/ to .gitignore unless --no-gitignore is passed. --force
overwrites an existing lich.yaml.lich exec
Run an ad-hoc command with the stack's resolved env loaded.
Usage: lich exec [--env-group=<group>] [--no-preflight] [--worktree <id-or-name>] <cmd> [args...]
Run an ad-hoc command with the resolved env loaded. Defaults to
the built-in `stack` env_group; --env-group=<name> picks another.
Stdio is inherited so output streams live.
If the stack isn't up, a one-line warning is printed to stderr but
the command still runs. Use --no-preflight to suppress the warning
(handy in scripts).
Flags:
--env-group=<group> Resolve env from the named env_group (default: stack).
--no-preflight Suppress the stack-not-up warning.
--worktree <id-or-name> Target a stack by ID or worktree name instead
of the current directory (see `lich stacks`).
The command runs in that worktree's directory.
Example: lich exec sh -c 'echo $DATABASE_URL'
Exit codes: 0 on success; child's exit code on failure; 2 on
usage error; 130 on SIGINT.lich env
Print a named env_group as dotenv-format on stdout.
Usage: lich env <group> [--worktree <id-or-name>]
Print the named env_group as dotenv-format on stdout. Keys are
emitted in sorted order; values are quoted as needed so the
output round-trips through `source <(lich env <group>)`.
Flags:
--worktree <id-or-name> Resolve the env_group against the named stack
instead of the current directory.
Example: source <(lich env stack)
Exit codes: 0 on success; 1 when the group is unknown; 2 on
usage error (no group name given).lich routing
Print the daemon's in-memory routing table (friendly-URL debug).
Usage: lich routing [--worktree <id-or-name>]
Print the daemon's in-memory routing table as JSON. Useful when
a friendly URL (host:port from `lich urls`) 404s — compare what
the daemon has loaded against the routing entries in state.json.
Flags:
--json Emit the table as JSON (default: table form).
--worktree <id-or-name> Filter to entries from the named stack only.
Exit codes: 0 on success; non-zero if the daemon is unreachable.