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: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Refresh from omartelo/lich at tests/lich-ref
- name: Refresh from lichdotdev/lich at tests/lich-ref
run: tests/refresh-fixtures.sh
- name: Fail if the vendored copies drifted
run: |
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# lich-plugin

The agent side of the [lich](https://github.com/omartelo/lich) integration. lich is a harness that orchestrates agent CLI sessions; this companion plugin gives it eyes and hands inside each session. It installs on **Claude Code**, **OpenAI Codex**, **Antigravity CLI**, **opencode**, **omp** (oh-my-pi) and **Crush** from this same repository. Every hook implements a contract that is canonical in the lich repository (`docs/hooks/` there); the docs in `docs/` here point at each contract and describe the client side:
The agent side of the [lich](https://github.com/lichdotdev/lich) integration. lich is a harness that orchestrates agent CLI sessions; this companion plugin gives it eyes and hands inside each session. It installs on **Claude Code**, **OpenAI Codex**, **Antigravity CLI**, **opencode**, **omp** (oh-my-pi) and **Crush** from this same repository. Every hook implements a contract that is canonical in the lich repository (`docs/hooks/` there); the docs in `docs/` here point at each contract and describe the client side:

- **session state** — `busy`/`done` on the session card (`UserPromptSubmit`/`PreInvocation`/`Stop`)
- **session start** — persists the agent's session id on the lich session (`SessionStart`/`PreInvocation`)
Expand Down Expand Up @@ -193,4 +193,4 @@ claude --plugin-dir .
node --test tests/*.test.mjs
```

Every hook script runs as a real subprocess, from the command line its registration spells, against a stub HTTP server — and the body it POSTs is asserted against [lich's contract fixtures](https://github.com/omartelo/lich/tree/main/docs/hooks/fixtures): an accepted shape, never a rejected one, the right endpoint, token and `X-Lich-Plugin` header, plus the client rules (no lich environment → no report; exit 0 when lich answers 500 or refuses the connection). The opencode and omp modules and the Claude Code mod are imported instead of spawned and fed the events a real run of each emits, against the same fixtures. All of them share `tests/contract.mjs`. The fixtures are vendored in `tests/fixtures/` by `tests/refresh-fixtures.sh`, at the lich release named in `tests/lich-ref`; CI diffs them against that release so a contract that moves in lich goes red here.
Every hook script runs as a real subprocess, from the command line its registration spells, against a stub HTTP server — and the body it POSTs is asserted against [lich's contract fixtures](https://github.com/lichdotdev/lich/tree/main/docs/hooks/fixtures): an accepted shape, never a rejected one, the right endpoint, token and `X-Lich-Plugin` header, plus the client rules (no lich environment → no report; exit 0 when lich answers 500 or refuses the connection). The opencode and omp modules and the Claude Code mod are imported instead of spawned and fed the events a real run of each emits, against the same fixtures. All of them share `tests/contract.mjs`. The fixtures are vendored in `tests/fixtures/` by `tests/refresh-fixtures.sh`, at the lich release named in `tests/lich-ref`; CI diffs them against that release so a contract that moves in lich goes red here.
2 changes: 1 addition & 1 deletion docs/mod-answer.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Mod: worker answer

Client side of the [mod-answer contract](https://github.com/omartelo/lich/blob/main/docs/hooks/mod-answer.md)
Client side of the [mod-answer contract](https://github.com/lichdotdev/lich/blob/main/docs/hooks/mod-answer.md)
(the endpoint and the payload are defined in the lich repository; this plugin
only implements them).

Expand Down
2 changes: 1 addition & 1 deletion docs/mod-control.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Mod: control

Client side of the [mod-control contract](https://github.com/omartelo/lich/blob/main/docs/hooks/mod-control.md)
Client side of the [mod-control contract](https://github.com/lichdotdev/lich/blob/main/docs/hooks/mod-control.md)
(the endpoints, the commands and the ack are defined in the lich repository;
this plugin only implements them).

Expand Down
2 changes: 1 addition & 1 deletion docs/mod-status.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Mod: status

Client side of the [mod-status contract](https://github.com/omartelo/lich/blob/main/docs/hooks/mod-status.md)
Client side of the [mod-status contract](https://github.com/lichdotdev/lich/blob/main/docs/hooks/mod-status.md)
(the endpoint and the response are defined in the lich repository; this plugin
only implements them).

Expand Down
2 changes: 1 addition & 1 deletion docs/mod-usage.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Mod: usage

Client side of the [mod-usage contract](https://github.com/omartelo/lich/blob/main/docs/hooks/mod-usage.md)
Client side of the [mod-usage contract](https://github.com/lichdotdev/lich/blob/main/docs/hooks/mod-usage.md)
(the endpoint and the payload are defined in the lich repository; this plugin
only implements them).

Expand Down
2 changes: 1 addition & 1 deletion docs/opencode-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ new one, rename one, close one, drive or ask one, look at the worktrees, file
them into folders.

lich exposes those operations twice, and both are documented in
[`docs/cli.md`](https://github.com/omartelo/lich/blob/main/docs/cli.md) there:
[`docs/cli.md`](https://github.com/lichdotdev/lich/blob/main/docs/cli.md) there:
as the `lich` command line, and as MCP tools it registers at spawn for the
harnesses that can be told on their own command line — Claude Code and Codex.
**opencode cannot be**, and a plugin there cannot register an MCP server either.
Expand Down
2 changes: 1 addition & 1 deletion docs/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

lich drives an agent CLI inside a PTY and injects the same three variables
(`LICH_PORT`, `LICH_TOKEN`, `LICH_SESSION_ID`) into every one it spawns. The
[hook contracts](https://github.com/omartelo/lich/blob/main/docs/hooks/README.md)
[hook contracts](https://github.com/lichdotdev/lich/blob/main/docs/hooks/README.md)
are therefore provider-agnostic: what changes per provider is only *how the
harness registers hooks* and *what its lifecycle events are called*. A Claude
Code session also carries `LICH_BIN`; `LICH_SUBAGENT_DEPTH`, how many
Expand Down
2 changes: 1 addition & 1 deletion docs/session-start.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Hook: session start

Client side of the [session-start contract](https://github.com/omartelo/lich/blob/main/docs/hooks/session-start.md)
Client side of the [session-start contract](https://github.com/lichdotdev/lich/blob/main/docs/hooks/session-start.md)
— the contract (transport, endpoint, payload, accepted values) is defined in
the lich repository; this plugin only implements it.

Expand Down
4 changes: 2 additions & 2 deletions docs/session-state.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Hook: session state

Client side of the [session-state contract](https://github.com/omartelo/lich/blob/main/docs/hooks/session-state.md)
Client side of the [session-state contract](https://github.com/lichdotdev/lich/blob/main/docs/hooks/session-state.md)
— the contract (transport, endpoint, payload, accepted values) is defined in
the lich repository; this plugin only implements it.

Expand Down Expand Up @@ -50,7 +50,7 @@ an approval prompt.

The endpoint, the accepted states and the optional fields (`tool` / `detail`
on the pre-tool report, `reason` on the waiting one) are spelled out once, in
[lich's contract](https://github.com/omartelo/lich/blob/main/docs/hooks/session-state.md).
[lich's contract](https://github.com/lichdotdev/lich/blob/main/docs/hooks/session-state.md).
What is below is only what each harness gives this plugin to fill them with.

`Notification` fires when Claude needs a permission decision or has been idle
Expand Down
2 changes: 1 addition & 1 deletion docs/session-title.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Hook: session title

Client side of the [session-title contract](https://github.com/omartelo/lich/blob/main/docs/hooks/session-title.md)
Client side of the [session-title contract](https://github.com/lichdotdev/lich/blob/main/docs/hooks/session-title.md)
— the contract (transport, endpoint, payload, accepted values) is defined in
the lich repository; this plugin only implements it.

Expand Down
2 changes: 1 addition & 1 deletion docs/session-touched.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Hook: session touched

Client side of the [session-touched contract](https://github.com/omartelo/lich/blob/main/docs/hooks/session-touched.md)
Client side of the [session-touched contract](https://github.com/lichdotdev/lich/blob/main/docs/hooks/session-touched.md)
— the contract (transport, endpoint, payload, accepted values) is defined in
the lich repository; this plugin only implements it.

Expand Down
2 changes: 1 addition & 1 deletion hooks/mod-compacting.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Reports a Claude Code conversation being compacted to lich, as the
// session-state contract's `compacting`. Contract: ../docs/session-state.md,
// canonical in https://github.com/omartelo/lich/blob/main/docs/hooks/session-state.md
// canonical in https://github.com/lichdotdev/lich/blob/main/docs/hooks/session-state.md
//
// A Claude Code mod, registered by hooks/lich.js. It brackets `session.compact`:
// `compacting` before the compaction runs, and the state the session goes back
Expand Down
2 changes: 1 addition & 1 deletion hooks/mod-control.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Lets lich drive a Claude Code session (`lich control`, the `control_session`
// MCP tool). Contract: ../docs/mod-control.md,
// canonical in https://github.com/omartelo/lich/blob/main/docs/hooks/mod-control.md
// canonical in https://github.com/lichdotdev/lich/blob/main/docs/hooks/mod-control.md
//
// A Claude Code mod, not a hook script: hooks/hooks.json names this file under
// `modules`, and Claude Code runs it inside its own process. It reports nothing.
Expand Down
2 changes: 1 addition & 1 deletion hooks/mod-status.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Shows the relay errands a Claude Code session is part of in its status line:
// who it owes an answer, the tasks it handed out that are still running, and
// the answers waiting to be collected. Contract: ../docs/mod-status.md,
// canonical in https://github.com/omartelo/lich/blob/main/docs/hooks/mod-status.md
// canonical in https://github.com/lichdotdev/lich/blob/main/docs/hooks/mod-status.md
//
// The one contract that reads rather than reports, and reading never collects:
// an answer listed as ready stays in the inbox for the agent.
Expand Down
2 changes: 1 addition & 1 deletion hooks/mod-usage.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Reports what a Claude Code session measured about itself to lich. Contract:
// ../docs/mod-usage.md, canonical in
// https://github.com/omartelo/lich/blob/main/docs/hooks/mod-usage.md
// https://github.com/lichdotdev/lich/blob/main/docs/hooks/mod-usage.md
//
// A Claude Code mod, not a hook script: hooks/hooks.json names this file under
// `modules`, beside mod-control.js. It hooks `session.measure`, which fires at
Expand Down
2 changes: 1 addition & 1 deletion hooks/worker-answer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Answers the task a lich subagent worker was handed with the worker's own last
// message, the way a native subagent's final message is its result. Contract:
// ../docs/mod-answer.md, canonical in
// https://github.com/omartelo/lich/blob/main/docs/hooks/mod-answer.md
// https://github.com/lichdotdev/lich/blob/main/docs/hooks/mod-answer.md
//
// A Claude Code mod, registered by hooks/lich.js beside mod-control.js. Only a
// worker reports: lich sets LICH_SUBAGENT_DEPTH on every Claude Code session it
Expand Down
2 changes: 1 addition & 1 deletion omp/lich.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Reports an omp (oh-my-pi) session to lich. Contracts: ../docs/, canonical in
// https://github.com/omartelo/lich/tree/main/docs/hooks
// https://github.com/lichdotdev/lich/tree/main/docs/hooks
//
// omp runs no hook commands. `--hook` and `--extension` are the same list — it
// merges both into one set of extension paths and loads every entry as a module
Expand Down
2 changes: 1 addition & 1 deletion opencode/lich.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Reports an opencode session to lich. Contracts: ../docs/, canonical in
// https://github.com/omartelo/lich/tree/main/docs/hooks
// https://github.com/lichdotdev/lich/tree/main/docs/hooks
//
// opencode loads a module rather than running a script, so this one file plays
// the part the four hooks/*.sh scripts play on the other harnesses. Same
Expand Down
2 changes: 1 addition & 1 deletion tests/refresh-fixtures.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ set -eu

here=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
ref=$(tr -d '[:space:]' <"$here/lich-ref")
raw=https://raw.githubusercontent.com/omartelo/lich/$ref
raw=https://raw.githubusercontent.com/lichdotdev/lich/$ref
base=$raw/docs/hooks/fixtures

for file in session-start.jsonl session-state.jsonl session-title.jsonl \
Expand Down
2 changes: 1 addition & 1 deletion tests/theme-validate.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const template = JSON.parse(
readFileSync(new URL('../skills/theme/template.json', import.meta.url), 'utf8'),
)

// The status tones lich 0.53.0 made required (omartelo/lich#617), with the
// The status tones lich 0.53.0 made required (lichdotdev/lich#617), with the
// bundled Dark theme's values.
const tones = {
'tone-pass': 'oklch(0.696 0.17 162.48)',
Expand Down
Loading