lich

command module
v0.84.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 4, 2026 License: AGPL-3.0 Imports: 45 Imported by: 0

README

lich

lich

English · Português (Brasil) · Español · 简体中文 · 日本語 · 한국어 · Русский

Release Platform License Sponsor

Run your coding agents side by side, each on its own branch.
Claude Code, Codex, opencode or the agent you already use, each in its own worktree, all in one window.

Download lich · lichdotdev.github.io/lich

Four Claude Code sessions side by side on one wall, each in its own git worktree. The sidebar lists them with their branch and diff badge, with the project's running services and the profile at its foot, and the footer shows the branch, the model and the plan

Features

Claude Code and Codex sessions on one wall, each on its own branchSessions in the sidebar, each with its own branch and diff badgeA diff with two line comments queued to send to the sessionThe session's browser beside its terminal, with two numbered notes pinned to elements of the pageA pull request open in lich with its file tree, diff and a pending review commentThe Appearance settings with the theme picker, fonts and footer layout

Agents side by side

Put sessions on a wall and lich lays out the panes for you. See at a glance which one is busy, which one is waiting on you and how much context it has left.

A worktree per task, no setup

Branch a session off any base and lich copies your .env files and gives it a free dev-server port. Your uncommitted work can come along.

Review the diff, comment the lines

Read what the agent changed next to its session, comment on the lines that need work and send every note back as one prompt.

Point at the page, tell the agent

The agent drives a browser in a tab beside its session, and you use the same page. Point at what's wrong, leave a note on it and send every note back as one prompt.

Pull requests without the browser

Open a pull request, ask the branch's agent to write it, review it inline and merge it, all from the same window.

Make it yours

Import a theme as JSON or install one from a git repository.

Docs →

And also:

  • Sessions that delegate. One agent hands a task to another session and gets the answer back. The same works from your shell with the lich command (docs).
  • Sandboxed agents. Let an agent skip permission prompts inside a sandbox that can't see your keys, your credentials or your other repositories (limits).
  • Your dev servers in the sidebar. Save what a project keeps running and start or stop it with one click.
  • Find anything. Ctrl/Cmd+K jumps to a session by name or by something said in it.
  • Know when you're needed. A desktop notification when a session is waiting on you.

Install

curl -fsSL https://raw.githubusercontent.com/lichdotdev/lich/main/install.sh | sh

One line: it detects your distro, checks the download and installs lich with your package manager.

Platform Get it
Linux install.sh above, or AUR lich-bin (yay -S lich-bin). Needs zenity and glibc 2.34 or newer (Debian 12, Ubuntu 22.04, RHEL 9 and up).
macOS brew install --cask lichdotdev/tap/lich
Windows Installer or portable zip from Releases, or scoop install https://github.com/lichdotdev/lich/releases/latest/download/lich.json

The macOS and Windows builds are not signed yet, so Gatekeeper and SmartScreen warn on a download from Releases; Homebrew skips the Gatekeeper prompt. Per-distro packages, the Linux tarball, clearing the quarantine flag and upgrading from the old Homebrew formula are in INSTALL.md.

Getting started

  1. Open a project. The + in the tab strip lists what you closed recently and opens a folder picker. Point it at a git repository.
  2. Pick your agent. The first launch lists the agents it found on your machine. Settings › Providers sets the default and each binary's path.
  3. Start a session. New Session opens your agent in the project. The + on a checkout's header opens any agent, or a plain terminal, in that checkout.
  4. Give it a worktree (optional). Create one from any base branch and lich opens a fresh session in it.

Provider support

Every agent runs in a real terminal, resumes its conversation, works in the sandbox and reaches your other sessions. What changes from one to another is what lich can read back out of it, since each CLI records different things.

See what each agent supports
What you get Claude Code Codex Antigravity opencode oh-my-pi Crush Cursor CLI Kiro CLI
Context window in the footer yes yes no no no no no yes
How much of the last turn came from the prompt cache, in the footer yes yes no in the cost tooltip in the cost tooltip no no no
The card's tooltip names the model running, and the one it opened on if it changed yes yes no no no no no yes
Cost in the footer yes yes no yes yes yes no credits
How much of your plan is left yes yes yes OpenCode Go only no no yes no
A turn your plan's usage limit stopped picks up again once the limit resets yes yes no its own retries its own retries no no no
Spinner while a turn runs, ring when it ends yes yes yes yes yes no yes yes
The card names itself after the conversation yes after your first prompt after your first prompt yes yes, from the second turn no yes, once the first turn ends after your first prompt, once the first turn ends
A pull request the agent opens shows on its card when the turn ends yes yes yes yes yes no, once the window regains focus yes yes
Repaints in the new look when you switch lich between a light and a dark theme yes no no yes yes no yes no
Bell when the agent is blocked on you yes yes no yes no no no no
Ctrl+Shift+Y jumps to the next session waiting on you yes yes no yes no no no no
The card says when the conversation is being compacted yes no no no no no no no
Sidebar filter by state: Waiting, Running, Unread yes yes no Waiting yes no Waiting no, always Idle no Waiting no Waiting
Run by your agent inside another session (claude -p, cursor-agent -p), it stays out of that session's card yes yes yes yes yes yes yes no
Machine kept out of idle sleep while a turn runs yes yes yes yes yes no yes yes
Review tab's Last turn, with the agent's recap yes yes yes yes yes no yes yes
Search the conversation from the palette yes yes yes yes yes yes no yes
Resume a conversation started outside lich, from the palette's History tab yes yes yes yes yes Linux; macOS and Windows untested yes yes
A long paste can land as editable text instead of a folded placeholder (Settings › Providers, off by default) yes no no yes not measured no, it becomes a paste_N.txt attachment no yes
Fork a conversation into a new worktree, or in its own checkout yes yes no yes no no no no
A fork hangs from its source session in the sidebar's tree yes yes no yes no no no no
Warned when you resume, from the agent's own app, a conversation another card has open yes on your next prompt on your next prompt, untested no yes at its next tool call no yes
Open a session at a chosen reasoning effort yes yes yes no yes no in the model name yes
Open a session with ultracode on yes no no no no no no no
Several accounts side by side as profiles, each with its own full login, and a session moved to another account carrying on in the same card (Settings › Providers) yes yes, with its own plugins in each profile and Personal's settings shared by all of them no yes, logged in from a terminal card; a session cannot move to another profile, since its conversations sit in the database that holds the login yes, logged in from a terminal card, with its settings shared by every profile not measured Linux and Windows (on macOS its login is in the Keychain), logged in from a terminal card, with mcp.json, hooks and skills shared by every profile Linux only (macOS keeps its login in the Keychain, and on Windows nothing moves it), logged in from a terminal card, with its conversations shared by every profile
A folder you trusted in your main account opens without the "trust this folder?" question in every other profile yes yes no profiles asks nothing asks nothing not measured yes asks nothing
A sandboxed session opens without the "trust this folder?" question yes yes yes asks nothing asks nothing yes, and it no longer asks to initialize the project yes asks nothing
A worktree of a folder you trusted opens without the "trust this folder?" question yes yes yes asks nothing asks nothing yes, and it no longer asks to initialize the project yes asks nothing
Drive a running session from lich control or an agent: prompt, stop, model, effort, slash command yes no no no no no no no
A message from another session arrives without being typed into the terminal yes no no no no no no no
A subagent the agent starts runs as a lich session with its own card, in the asking session's checkout, hands its full report back and closes once done; its own subagents get cards too, one level down yes no no no no no no no
Ask a running session a side question without stopping it (lich ask) yes no no no no no no no
Context, cost and plan usage as the CLI measured them itself yes no no no no no no no
The terminal's status line shows who the session owes an answer, who it is waiting on, and answers ready to collect yes no no no no no no no
Delegate privately from a subagent or workflow step yes yes yes yes yes yes yes yes
A resumed session keeps the model and effort it was on model only yes no model yes no model model; effort untested
A result still waits for you after you interrupt a wait for it yes yes yes yes no yes yes yes
A task you hand another session reports back "unanswered" as soon as that agent ends its turn without replying yes yes yes yes yes no, waits for the deadline yes yes
lich's own messages to the agent (handed tasks, results ready, notices) in the prompt language you pick yes yes yes yes yes yes yes yes
Told at spawn, in the prompt language, to fan work out as lich sessions rather than hidden subagents yes no no no yes no no no
The session card opens a browser its agent drives, in a tab beside the session yes yes yes yes yes yes yes yes

Every gap is deliberate, and docs/ceilings.md says what was measured behind each one.

Configuration

  • Providers. Settings › Providers sets each agent's binary and the default for every project; a project can choose its own. With no path set, lich runs the first binary on your login shell's PATH and lich doctor warns when there is more than one version.
  • Footer. Settings › Appearance: drag its items to choose what it shows. The cost starts hidden, since it only means something when you pay per token.
  • Worktrees. A .worktreeinclude file in the project picks which gitignored files a new worktree gets.
  • Session hooks. Install the lich plugin from Settings and a session names its own card and refreshes git the moment it writes a file.
  • Scripting. docs/stability.md says which parts of lich are safe to script against.

Privacy & updates

Everything runs on your machine: no account, no sign-in, no telemetry. lich only goes to the network for:

  • Updates: a version check against GitHub Releases at startup and hourly, and the lich plugin's release list at startup.
  • Plan usage: each provider's own usage endpoint (Anthropic, OpenAI, Cursor, OpenCode Go), with the login the agent already uses, at most every five minutes. Antigravity's plan is read from agy itself.
  • Prices: LiteLLM's public price table on GitHub, once, for a model the bundled table does not know.

The Windows installer updates in place; Homebrew, Scoop, AUR and the Linux packages update through their package manager, and lich gives you the command. Something broken? lich doctor checks your setup and lich rage packs a bug report into one archive without uploading it. Settings › Help says what the log carries (paths, project and branch names, your gh login, never a session token) before you attach it. Bugs and feature requests go to Issues; what changed in each version is in CHANGELOG.md.

Build from source

lich is two binaries: lich, a static pure-Go backend, and lich-native, the window, built with cgo from native/. You need Go 1.27.0+ and Task; the window also needs a C toolchain, Gio's system packages and a libghostty-vt built from the commit in native/GHOSTTY_COMMIT. native/slice.sh says how, and docs/native-window.md covers the window.

task build          # backend binary -> bin/lich
task build:native   # window -> bin/lich-native
task run            # build + run
task test           # Go suites
task package        # .deb + .rpm + Arch .pkg.tar.zst in bin/ (needs nfpm)

Adding another agent touches a dozen files across two repositories: docs/adding-a-provider.md is the map.

Sponsors

lich is written and maintained by one person. Sponsoring pays for the time that goes into it and keeps the project independent: there is no paid tier of the app and there will not be one.

Become a sponsor

Backers

Nobody yet.

License

AGPL-3.0-only © 2026 omartelo

lich is free software: you can use, study, modify and redistribute it under the terms of the GNU Affero General Public License v3. Any distributed or network-served derivative must be released under the same license. Releases up to and including v0.9.0 remain MIT-licensed.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
Package api is the contract between the lich backend and its clients: the window (native/backend), `lich` and `lich mcp`.
Package api is the contract between the lich backend and its clients: the window (native/backend), `lich` and `lich mcp`.
extension module
internal
agentplugin
Package agentplugin manages the lich companion plugin inside the provider CLIs that can run it: whether it is installed, whether a newer release exists, and installing or updating it.
Package agentplugin manages the lich companion plugin inside the provider CLIs that can run it: whether it is installed, whether a newer release exists, and installing or updating it.
appkit
Package appkit makes lich's backend a macOS application, through purego rather than cgo: it runs AppKit's event loop on the main thread, which AppKit insists on, and the backend beside it.
Package appkit makes lich's backend a macOS application, through purego rather than cgo: it runs AppKit's event loop on the main thread, which AppKit insists on, and the backend beside it.
appupdate
Package appupdate checks GitHub for a newer lich release and, on a Windows install no package manager owns, downloads and runs the release's installer.
Package appupdate checks GitHub for a newer lich release and, on a Windows install no package manager owns, downloads and runs the release's installer.
awake
Package awake keeps the machine from idling into sleep while a session is working, the way a media player does while it plays.
Package awake keeps the machine from idling into sleep while a session is working, the way a media player does while it plays.
claudeprofile
Package claudeprofile keeps more than one Claude Code account on one machine.
Package claudeprofile keeps more than one Claude Code account on one machine.
cli
Package cli is the `lich` command line — the surface a provider CLI running inside a lich session uses to reach the sessions beside it.
Package cli is the `lich` command line — the surface a provider CLI running inside a lich session uses to reach the sessions beside it.
codexprofile
Package codexprofile keeps more than one Codex login on one machine, the way internal/claudeprofile does for Claude Code.
Package codexprofile keeps more than one Codex login on one machine, the way internal/claudeprofile does for Claude Code.
doctor
Package doctor answers "would lich start on this machine, and why not".
Package doctor answers "would lich start on this machine, and why not".
drop
Package drop turns a file dropped on the terminal into a path the session can paste.
Package drop turns a file dropped on the terminal into a path the session can paste.
events
Package events pushes app events (session status, titles, touched — anything the backend pushes to the UI) to the local WebSocket client on /events (see docs/native-window.md).
Package events pushes app events (session status, titles, touched — anything the backend pushes to the UI) to the local WebSocket client on /events (see docs/native-window.md).
ghrelease
Package ghrelease reads the published releases of a GitHub repository — the one piece lich's two update checks (the app in internal/appupdate and the lich plugin in internal/agentplugin) share.
Package ghrelease reads the published releases of a GitHub repository — the one piece lich's two update checks (the app in internal/appupdate and the lich plugin in internal/agentplugin) share.
gitutil
Package gitutil holds the small process rules shared by git callers.
Package gitutil holds the small process rules shared by git callers.
logging
Package logging configures the process-wide slog logger: structured text with source file:line on every record, mirrored to stderr and a persistent file under the lich config dir.
Package logging configures the process-wide slog logger: structured text with source file:line on every record, mirrored to stderr and a persistent file under the lich config dir.
ompprofile
Package ompprofile keeps more than one oh-my-pi login on one machine, the way internal/claudeprofile does for Claude Code.
Package ompprofile keeps more than one oh-my-pi login on one machine, the way internal/claudeprofile does for Claude Code.
patchnotes
Package patchnotes serves the changelog section for the running build so the app can show a "what's new" popup after an update.
Package patchnotes serves the changelog section for the running build so the app can show a "what's new" popup after an update.
preview
Package preview serves a session's checkout over loopback HTTP, so the session's browser can load a local file without a file: URL.
Package preview serves a session's checkout over loopback HTTP, so the session's browser can load a local file without a file: URL.
pricing
Package pricing answers what a model's tokens cost, in US dollars, for the per-session cost readout.
Package pricing answers what a model's tokens cost, in US dollars, for the per-session cost readout.
profilestore
Package profilestore keeps more than one login of a provider on one machine.
Package profilestore keeps more than one login of a provider on one machine.
project
Package project opens project directories through the OS file picker.
Package project opens project directories through the OS file picker.
prompt
Package prompt holds the natural-language text lich types into an agent session, in every language a user can pick for it.
Package prompt holds the natural-language text lich types into an agent session, in every language a user can pick for it.
providers
Package providers is the registry of AI coding CLI harnesses lich can run in a session (Claude Code, Codex, Antigravity, opencode, oh-my-pi, Crush, Cursor CLI, Kiro CLI).
Package providers is the registry of AI coding CLI harnesses lich can run in a session (Claude Code, Codex, Antigravity, opencode, oh-my-pi, Crush, Cursor CLI, Kiro CLI).
quota
Package quota reads the subscription quota a provider's own account API reports: the rolling windows a plan is metered in, and how much of each one is spent.
Package quota reads the subscription quota a provider's own account API reports: the rolling windows a plan is metered in, and how much of each one is spent.
rage
Package rage collects what a lich bug report needs into one archive: the facts that decide whether a report is actionable (version, platform, window, provider and plugin state), the environment lich was launched with, and the log generations — with the loopback token masked wherever it appeared.
Package rage collects what a lich bug report needs into one archive: the facts that decide whether a report is actionable (version, platform, window, provider and plugin state), the environment lich was launched with, and the log generations — with the loopback token masked wherever it appeared.
relay
Package relay lets one lich session hand a prompt to another and get an answer back, for the providers whose own CLI has no cross-session channel of its own.
Package relay lets one lich session hand a prompt to another and get an answer back, for the providers whose own CLI has no cross-session channel of its own.
relpath
Package relpath validates the repo-relative paths lich receives from the page — a file picked in the review panel, a path parsed out of git's diff output — before they are joined onto a work-tree root.
Package relpath validates the repo-relative paths lich receives from the page — a file picked in the review panel, a path parsed out of git's diff output — before they are joined onto a work-tree root.
restart
Package restart owns how a running lich ends.
Package restart owns how a running lich ends.
routes
Package routes exposes the services api declares on an rpc.Handler, one function per service.
Package routes exposes the services api declares on an rpc.Handler, one function per service.
rpc
Package rpc exposes the app's Go services to the window, `lich` and `lich mcp` over plain HTTP on the local transport listener: the window is its own process and never imports internal/ (docs/native-window.md).
Package rpc exposes the app's Go services to the window, `lich` and `lich mcp` over plain HTTP on the local transport listener: the window is its own process and never imports internal/ (docs/native-window.md).
sandbox
Package sandbox confines a session's process tree to the work it was opened for: a private empty home, the rest of the machine read-only, and write access only inside the checkout and the provider's own state directory.
Package sandbox confines a session's process tree to the work it was opened for: a private empty home, the rest of the machine read-only, and write access only inside the checkout and the provider's own state directory.
semver
Package semver compares release versions well enough for lich's update checks: MAJOR.MINOR.PATCH plus the SemVer rule that a pre-release precedes the release it qualifies.
Package semver compares release versions well enough for lich's update checks: MAJOR.MINOR.PATCH plus the SemVer rule that a pre-release precedes the release it qualifies.
services
Package services runs a project's services: commands the user saved once (a container, a tunnel, a dev server) that lich starts on a PTY of their own and shows as up or down, outside the session list.
Package services runs a project's services: commands the user saved once (a container, a tunnel, a dev server) that lich starts on a PTY of their own and shows as up or down, outside the session list.
shellintegration
Package shellintegration marks a shell session's prompt for the terminal with OSC 133, the way Ghostty's shell integration does, so the native window's terminal (libghostty-vt) clears the prompt on a resize instead of leaving the lines a reflow wrapped above the one the shell draws again.
Package shellintegration marks a shell session's prompt for the terminal with OSC 133, the way Ghostty's shell integration does, so the native window's terminal (libghostty-vt) clears the prompt on a resize instead of leaving the lines a reflow wrapped above the one the shell draws again.
shquote
Package shquote quotes a string for a shell command line.
Package shquote quotes a string for a shell command line.
singleton
Package singleton keeps a second lich launch from racing the pinned listener port and dying with a bare error.
Package singleton keeps a second lich launch from racing the pinned listener port and dying with a bare error.
snippet
Package snippet cuts the stretch of text around a search hit that a result row shows.
Package snippet cuts the stretch of text around a search hit that a result row shows.
spawn
Package spawn opens new lich sessions for a caller that is not the window: the `lich` command line and the MCP tools beside it (internal/cli).
Package spawn opens new lich sessions for a caller that is not the window: the `lich` command line and the MCP tools beside it (internal/cli).
store
Package store is lich's persistence layer: a single SQLite database holding open projects, their terminal sessions and the settings scoped globally or to one project — provider binaries and defaults, the permission and sandbox rungs, the gh account.
Package store is lich's persistence layer: a single SQLite database holding open projects, their terminal sessions and the settings scoped globally or to one project — provider binaries and defaults, the permission and sandbox rungs, the gh account.
system
Package system holds the few OS integrations the window needs that are not tied to any domain service — opening a URL in the user's default browser, opening a work-tree file in their editor, raising a desktop notification, and the handful of facts a bug report needs (version, platform, where the log lives).
Package system holds the few OS integrations the window needs that are not tied to any domain service — opening a URL in the user's default browser, opening a work-tree file in their editor, raising a desktop notification, and the handful of facts a bug report needs (version, platform, where the log lives).
terminal
Package terminal spawns PTY-backed shell sessions and bridges their I/O to the window over the local WebSocket transport (transport.go), falling back to the /events channel.
Package terminal spawns PTY-backed shell sessions and bridges their I/O to the window over the local WebSocket transport (transport.go), falling back to the /events channel.
themes
Package themes stores user-imported color themes and exposes them to the UI.
Package themes stores user-imported color themes and exposes them to the UI.
tray
Package tray keeps lich in the system tray: the one thing on screen that says a lich whose window is closed is still running its sessions, and the way back to the window or out of lich from there.
Package tray keeps lich in the system tray: the one thing on screen that says a lich whose window is closed is still running its sessions, and the way back to the window or out of lich from there.
xdgprofile
Package xdgprofile keeps more than one login of opencode, Cursor CLI and Kiro CLI on one machine, the way internal/claudeprofile does for Claude Code.
Package xdgprofile keeps more than one login of opencode, Cursor CLI and Kiro CLI on one machine, the way internal/claudeprofile does for Claude Code.
Package themes owns the canonical bundled theme definitions.
Package themes owns the canonical bundled theme definitions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL