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.11.tar.gz (1.8 MB 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.11-py3-none-any.whl (26.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: hook_my_lichess-0.1.11.tar.gz
  • Upload date:
  • Size: 1.8 MB
  • 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.11.tar.gz
Algorithm Hash digest
SHA256 49d14dc9c6684165780210663d1ec1515a517ed9ae8411e6b6699d76dd887318
MD5 6ac403bd648dc89be27065631ecb1603
BLAKE2b-256 a35b2369fc400f108ebe4ae001100b0272c960fcf05d2973b561ad2ebe01ddc6

See more details on using hashes here.

Provenance

The following attestation bundles were made for hook_my_lichess-0.1.11.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.11-py3-none-any.whl.

File metadata

File hashes

Hashes for hook_my_lichess-0.1.11-py3-none-any.whl
Algorithm Hash digest
SHA256 e697edd44567de6d4169359f2244ac1bd24aa2dd0d8198971bfbb98b2991cae8
MD5 547f733388358240709c919bca9b6542
BLAKE2b-256 170d2407c20247fc587e916124b80c865a19e0ef8975c0ba49af3ab88d13b086

See more details on using hashes here.

Provenance

The following attestation bundles were made for hook_my_lichess-0.1.11-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