Skip to main content

A Claude Code hook that opens a Lichess puzzle in your terminal while Claude is working.

Project description

hook-my-lichess

A Lichess puzzle that floats over the same terminal Claude Code is running in. While Claude works, the board hovers in the top-right; you play by typing p:<move> as a prompt — including while Claude is mid-response. No PTY proxy, no wrapper binary.

Install

Prereqs (one-time): uv and a Lichess personal token (create one here):

curl -LsSf https://astral.sh/uv/install.sh | sh
export LICHESS_TOKEN=lip_xxxxxxxxxxxxxxxx   # add to your shell rc

Then, inside Claude Code:

/plugin marketplace add 0JCRG0/hook-my-lichess
/plugin install hook-my-lichess@jcrg-tooling

Done. Your next prompt fires the hooks; uvx fetches the daemon from PyPI on first run (~2 s) and caches it.

Playing

Submit any prompt — the board appears within ~1 s. Then type puzzle commands as prompts:

Command Effect
p:e2e4 UCI move
p:Nf3 SAN move (piece letters uppercase)
p:hint which square the piece moves from
p:solve give up, reveal the move (shown 10 s)
p:quit close the puzzle
p:size xl resize the overlay (live + persisted)
p:pos center reposition the overlay (live + persisted)

Anything not starting with p: goes to Claude untouched. Mid-turn commands hit the board within ~100 ms — no waiting for Claude to finish. When Claude's turn ends, the banner flips to "✓ Claude is done" and you keep solving at your own pace.

Caveats

  • Kitty graphics protocol required. Works in Ghostty, Kitty, and WezTerm. On anything else (iTerm2, Terminal.app, tmux, VS Code's terminal, plain SSH), the daemon exits silently and Claude works as normal — you just don't get a board.
  • Mid-turn commands are visible to the model. Claude Code has no hook for messages typed while a turn is running, so a mid-turn p:e2e4 reaches Claude's context as plain text (the board still updates — the daemon reads queued input from the session transcript). The plugin injects a standing instruction telling the model to silently ignore p: messages, which works well in practice but costs a few context tokens per prompt. Commands submitted while Claude is idle are properly blocked and never reach the model.
  • macOS / Linux only. The daemon writes Kitty escapes straight to the pty device; there is no Windows support.

Customizing size & position

The quick way — just type it as a prompt, live overlay updates instantly and the change persists:

p:size xl        # small | medium | large | xl | xxl | any number (p:size 1.7)
p:pos center     # top-right | top-left | bottom-right | bottom-left | center | row col (p:pos 3 80)

Or edit the settings file by hand:

uvx --from hook-my-lichess hml-overlay init-config

Then edit ~/.config/hml/settings.json:

{ "size": "xxl", "position": "center" }
  • size"small" | "medium" (default) | "large" | "xl" | "xxl", or any positive number (e.g. 1.7).
  • position"top-right" (default) | "top-left" | "bottom-right" | "bottom-left" | "center", or a 1-indexed [row, col] pair.

Config is read from $HML_CONFIG, then <cwd>/hml.json, then ~/.config/hml/settings.json — first hit wins.

How it works

Claude Code owns its terminal end-to-end; the overlay is a sibling daemon, spawned by a UserPromptSubmit hook:

  • The hook resolves the terminal's pty device by walking the process tree (hook processes have no controlling terminal) and the daemon writes Kitty graphics escapes straight to it, re-placing the image on a 16 ms clock so it snaps back over scrolls immediately.
  • Idle p: prompts are intercepted with decision: "block". Mid-turn p: messages are picked up by tailing the session's JSONL transcript, with an 8-second dedup window against duplicates.
  • One daemon per terminal, keyed by pty name — two Claude sessions in two panes get independent boards.

Full architecture notes and the bugs that drove the sidecar rewrite: docs/v5-wrapper-vs-v6-sidecar.md.

Developing locally

git clone https://github.com/0JCRG0/hook-my-lichess
cd hook-my-lichess
python3 -m venv .venv
.venv/bin/pip install -e .
cp .env.example .env   # put LICHESS_TOKEN here

The hook scripts prefer the sibling .venv/bin/hml-overlay over uvx, so working inside this repo always runs your in-tree code. If the marketplace plugin is also installed, disable it here (/plugin disable hook-my-lichess) to avoid double-firing.

Debugging: HML_FORCE_OVERLAY=1 bypasses terminal detection; HML_DEBUG=1 logs to /tmp/hml-sidecar-debug.log. A standalone stdin-loop version of the puzzle (no Claude, no overlay) runs with .venv/bin/lichess-puzzle.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hook_my_lichess-0.1.9.tar.gz (59.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hook_my_lichess-0.1.9-py3-none-any.whl (25.2 kB view details)

Uploaded Python 3

File details

Details for the file hook_my_lichess-0.1.9.tar.gz.

File metadata

  • Download URL: hook_my_lichess-0.1.9.tar.gz
  • Upload date:
  • Size: 59.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for hook_my_lichess-0.1.9.tar.gz
Algorithm Hash digest
SHA256 71f78ccb41e1bf04d4faa989f684dc92944ec5f309c219e87fbf96527be59368
MD5 847bfbc185efb2ad65dbf4918b5c40fd
BLAKE2b-256 b941d47922f16b3d0a5462bd57d234550d636763793336ff6cf6a23b447bcde1

See more details on using hashes here.

Provenance

The following attestation bundles were made for hook_my_lichess-0.1.9.tar.gz:

Publisher: release.yml on 0JCRG0/hook-my-lichess

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hook_my_lichess-0.1.9-py3-none-any.whl.

File metadata

  • Download URL: hook_my_lichess-0.1.9-py3-none-any.whl
  • Upload date:
  • Size: 25.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for hook_my_lichess-0.1.9-py3-none-any.whl
Algorithm Hash digest
SHA256 944c0a7ba21b6e313ee66db5d9b55057b90a08d9af7a081f2f4664606bffd240
MD5 b0a6539fdf6cf6c7c644f0774d7973da
BLAKE2b-256 ca13432eb250d18ef4b97982bccac9bd276e03ad21580255a2866fe185cb3c24

See more details on using hashes here.

Provenance

The following attestation bundles were made for hook_my_lichess-0.1.9-py3-none-any.whl:

Publisher: release.yml on 0JCRG0/hook-my-lichess

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page