Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- The Pulls screen shows a changed image in a pull request's Files tab, before and after side by side, as the Review tab does, where it used to say only "Binary file". An edited Markdown file there has the preview button too, where only an added one had it. lich reads the file from your clone when it holds the commit and from GitHub otherwise.
- `lich mcp` answers MCP clients on protocol revision 2026-07-28, which name the version on each request instead of opening with `initialize`, and serves their `server/discover`. Clients that open with `initialize` are answered exactly as before.
- A Cursor CLI card takes the name Cursor gives the conversation, once the first turn ends, where it kept the name lich gave it.

### Changed

Expand All @@ -21,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Resolve conflicts, Fix CI errors and a worktree started from an issue send their message to a new Claude Code session as soon as it is at its prompt, where it could sit unsent for up to a minute, until you pressed Enter. lich read the terminal's own answers to Claude Code's startup questions as you typing at that prompt, and held the message back for you.
- A long Markdown file, such as lich's own CHANGELOG.md, previews in the Code and Review tabs without freezing the window: the preview draws only the part on screen, where it used to lay out the whole file on every frame.
- A Markdown preview keeps the words apart where the source wraps a line, where they used to run together, and a table no longer squeezes a narrow column into broken words: each column is at least as wide as its longest word.
- A Claude Code card takes the title Claude Code gives the conversation again, where it kept the name lich gave it. lich now starts a new Claude Code session without `--name`, which stopped Claude Code titling it. The session picks its own name in Claude Code's agent list, a different one from the card's, and `lich sessions`, `lich whoami` and `list_sessions` show no second name for it until a `/rename` gives it one.

## [0.76.0] - 2026-10-21

Expand Down
1 change: 1 addition & 0 deletions README.es.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ porque lee lo que cada CLI deja escrito, y no hay dos que registren lo mismo.
| Cuánto queda de tu plan | sí | sí | sí | solo OpenCode Go | no | no | sí | no |
| Un turno que el límite de uso de tu plan detuvo se reanuda cuando el límite se restablece | sí | sí | no | sus propios reintentos | sus propios reintentos | no | no | no |
| Spinner mientras corre un turno, anillo cuando termina | sí | sí | sí | sí | sí | no | sí | sí |
| La tarjeta toma el nombre de la conversación | sí | por tu primer prompt | por tu primer prompt | sí | sí, desde el segundo turno | no | sí, cuando termina el primer turno | por tu primer prompt, cuando termina el primer turno |
| Un pull request que abre el agente aparece en su tarjeta al terminar el turno | sí | sí | sí | sí | sí | no, cuando la ventana recupera el foco | sí | sí |
| Se repinta con el aspecto nuevo al cambiar lich entre un tema claro y uno oscuro | sí | no | no | sí | sí | no | sí | no |
| Campana cuando el agente está bloqueado esperándote | sí | sí | no | sí | no | no | no | no |
Expand Down
1 change: 1 addition & 0 deletions README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ lich は各 CLI が書き出す情報を読んでいて、何を書き出すか
| プランの残量を表示 | あり | あり | あり | OpenCode Go のみ | なし | なし | あり | なし |
| プランの使用上限で止まったターンが、上限のリセット後に再開する | あり | あり | なし | 独自のリトライ | 独自のリトライ | なし | なし | なし |
| ターン実行中はスピナー、終了時はリングを表示 | あり | あり | あり | あり | あり | なし | あり | あり |
| カードに会話の名前が付く | あり | 最初のプロンプトから | 最初のプロンプトから | あり | あり(2 ターン目から) | なし | あり(最初のターン終了時) | 最初のプロンプトから(最初のターン終了時) |
| エージェントが作成したプルリクエストが、ターン終了時にカードに表示される | あり | あり | あり | あり | あり | なし(ウィンドウがフォーカスを取り戻した時点で表示) | あり | あり |
| lich をライトテーマとダークテーマで切り替えると、新しい配色で再描画される | あり | なし | なし | あり | あり | なし | あり | なし |
| エージェントが入力待ちで止まるとベルが鳴る | あり | あり | なし | あり | なし | なし | なし | なし |
Expand Down
1 change: 1 addition & 0 deletions README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ lich로 할 수 있는 일:
| 남은 플랜 사용량 | 예 | 예 | 예 | OpenCode Go만 | 아니요 | 아니요 | 예 | 아니요 |
| 플랜 사용 한도에 걸려 멈춘 턴이 한도가 초기화되면 다시 이어짐 | 예 | 예 | 아니요 | CLI가 직접 재시도 | CLI가 직접 재시도 | 아니요 | 아니요 | 아니요 |
| 턴이 실행되는 동안 스피너, 끝나면 벨 | 예 | 예 | 예 | 예 | 예 | 아니요 | 예 | 예 |
| 카드 이름이 대화에 맞춰 붙음 | 예 | 첫 프롬프트로 | 첫 프롬프트로 | 예 | 예, 두 번째 턴부터 | 아니요 | 예, 첫 턴이 끝날 때 | 첫 프롬프트로, 첫 턴이 끝날 때 |
| 에이전트가 연 풀 리퀘스트가 턴이 끝나면 카드에 표시됨 | 예 | 예 | 예 | 예 | 예 | 아니요, 창이 다시 포커스를 받을 때 표시됨 | 예 | 예 |
| lich를 라이트/다크 테마로 전환하면 바뀐 모양으로 다시 그려짐 | 예 | 아니요 | 아니요 | 예 | 예 | 아니요 | 예 | 아니요 |
| 에이전트가 내 응답을 기다리며 막혔을 때 벨 | 예 | 예 | 아니요 | 예 | 아니요 | 아니요 | 아니요 | 아니요 |
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ reads what each CLI writes down and no two of them write down the same things.
| 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 |
Expand Down
1 change: 1 addition & 0 deletions README.pt-BR.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ mesmas coisas.
| Quanto ainda resta do seu plano | sim | sim | sim | só OpenCode Go | não | não | sim | não |
| Um turno interrompido pelo limite de uso do plano continua quando o limite renova | sim | sim | não | retenta sozinho | retenta sozinho | não | não | não |
| Spinner enquanto o turno roda, anel quando termina | sim | sim | sim | sim | sim | não | sim | sim |
| O card ganha o nome da conversa | sim | pelo seu primeiro prompt | pelo seu primeiro prompt | sim | sim, a partir do segundo turno | não | sim, quando o primeiro turno termina | pelo seu primeiro prompt, quando o primeiro turno termina |
| Um pull request aberto pelo agente aparece no card quando o turno termina | sim | sim | sim | sim | sim | não, só quando a janela volta ao foco | sim | sim |
| Se redesenha com o novo visual quando você troca o lich entre tema claro e escuro | sim | não | não | sim | sim | não | sim | não |
| Sino quando o agente depende de você para continuar | sim | sim | não | sim | não | não | não | não |
Expand Down
1 change: 1 addition & 0 deletions README.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
| Сколько осталось от лимитов подписки | да | да | да | только OpenCode Go | нет | нет | да | нет |
| Ход, который остановился на лимите подписки, продолжается сам, когда лимит сбросится | да | да | нет | свои повторные попытки | свои повторные попытки | нет | нет | нет |
| Индикатор, пока идёт ход, и кольцо, когда он закончился | да | да | да | да | да | нет | да | да |
| Карточка получает название разговора | да | по первому запросу | по первому запросу | да | да, со второго хода | нет | да, когда закончится первый ход | по первому запросу, когда закончится первый ход |
| Pull request, открытый агентом, появляется на его карточке по окончании хода | да | да | да | да | да | нет, только когда окно снова получит фокус | да | да |
| Перерисовывается в новом виде, когда вы переключаете lich между светлой и тёмной темой | да | нет | нет | да | да | нет | да | нет |
| Колокольчик, когда агент не может продолжить без вас | да | да | нет | да | нет | нет | нет | нет |
Expand Down
1 change: 1 addition & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
| 套餐剩余额度 | 有 | 有 | 有 | 仅 OpenCode Go | 无 | 无 | 有 | 无 |
| 因套餐用量上限中断的一轮,在额度重置后自动继续 | 有 | 有 | 无 | 由其自身重试 | 由其自身重试 | 无 | 无 | 无 |
| 一轮运行中显示转圈,结束时显示圆环 | 有 | 有 | 有 | 有 | 有 | 无 | 有 | 有 |
| 卡片以对话命名 | 有 | 取自你的第一条提示 | 取自你的第一条提示 | 有 | 有,从第二轮起 | 无 | 有,第一轮结束时 | 取自你的第一条提示,第一轮结束时 |
| 智能体开的 PR 在一轮结束时显示在卡片上 | 有 | 有 | 有 | 有 | 有 | 无,等窗口重新获得焦点时显示 | 有 | 有 |
| lich 在浅色和深色主题间切换时,按新主题重绘 | 有 | 无 | 无 | 有 | 有 | 无 | 有 | 无 |
| 智能体等你处理时响铃 | 有 | 有 | 无 | 有 | 无 | 无 | 无 | 无 |
Expand Down
16 changes: 14 additions & 2 deletions docs/ceilings.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,11 @@ work when nobody knows it and that the call site never shows. The mechanism and
on the first tool call, so a turn that calls no tool has nothing to read, and the asker hears nothing until the
ticket's deadline. A pull request a Crush session opens reaches its card only when the window regains focus
(`native/cmd/lich-native/gitstate.go` `recheckMissingPR`, `cardstate.go` `setFocused`): `gh pr create` moves
neither branch nor HEAD, so a card showing no pull request asks gh again when its session's turn ends. The day
Crush ships `Stop`, the existing `report-state.sh done` closes both.
neither branch nor HEAD, so a card showing no pull request asks gh again when its session's turn ends. A Crush
card is never named after its conversation either: Crush files a title in that same database, and nothing tells
lich when to read it (`docs/hooks/session-title.md`). The day Crush ships `Stop`, the existing
`report-state.sh done` closes the first two, and a read like Kiro's and Cursor's (`internal/terminal`,
`title_filed.go`) the third.
- **A CLI run as a tool inside a session is told apart by conversation id, and Kiro has none to tell by**
(`internal/terminal/nested.go`, docs/hooks/session-state.md "Nested agent CLIs"): a `claude -p` the agent runs
inherits the card's `LICH_*` env and reports as it. A state report naming another conversation is dropped, and a
Expand Down Expand Up @@ -242,6 +245,15 @@ work when nobody knows it and that the call site never shows. The mechanism and

## Relay, errands and subagents

- **A new Claude Code session's roster name is its own, and lich does not know it** (`internal/terminal`,
`nameArgs`; `internal/relay`, `RosterNameOf`): lich spawns it without `--name`, because a name passed there is
the user's to Claude Code and a session holding one never writes the `ai-title` its card is titled from
(measured on 2.1.306). It names itself after its directory and a random suffix, which keeps the roster
unambiguous, but writes that name only into `~/.claude/sessions/<pid>.json`, keyed by a pid a confined
session's namespace hides. So `list_sessions`, `lich sessions` and `lich whoami` show no second name for it,
and a name an agent read off Claude Code's own `/list-agents` is not one lich resolves: that agent reaches the
session through its own messaging or by the card's label. A `/rename` or a fork puts a name on record, and from
then on lich answers to it; a fork pays for it with its `ai-title`.
- **A prompt in use is recognised from the bytes going in, never from the line itself**
(`internal/terminal/draft.go`; typed deliveries only, a Claude Code session with its mod is handed the message, see below): a relayed message pastes at the prompt and sends an Enter behind it, so lich
holds the delivery back while the user has unsent input there. What it counts is printable input since the last
Expand Down
8 changes: 5 additions & 3 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,9 @@ prompt is left alone and the task does not wait for them to finish it. A task th
collected is typed as usual.

- `<session>` is the label on the card, **or** the roster name that session
answers to (`myrepo-a1b2`, the one lich passes as `--name` and a mention
writes at a prompt). Both name the same session and both are accepted, because
answers to (`myrepo-a1b2`, lich's own for most providers; for Claude Code the
one a `/rename` or a fork put on record, which a mention writes at a prompt,
and none at all for a new session that named itself). Both name the same session and both are accepted, because
an agent holding one of them should never have to know which door it is
standing at — offering one name and accepting the other is what once made an
agent treat a single session as two and use both channels at once. The label
Expand Down Expand Up @@ -1366,7 +1367,8 @@ Three things keep that from repeating, and none of them asks the user to choose:
1. **One address space.** The relay answers to the card label *and* to the peer
roster name — the one the session's own record carries, read back per lookup
(`internal/terminal.AgentName`) and falling back to lich's derivation when
there is nothing to read (`internal/relay/rostername.go`). A mention that
there is nothing to read, except for Claude Code, whose new sessions name
themselves where lich cannot read it (`internal/relay/rostername.go`). A mention that
slips into lich's tool works instead of erroring, and goes on working after a
`/rename`.
2. **Both names travel.** `list_sessions` and every miss report the label and
Expand Down
Loading
Loading