a custom shader for ghostty × claude code

Your context window
is a black hole.

Ghostty Blackhole puts a real, ray-traced black hole inside your terminal. It grows as Claude Code's context window fills up, live. A fresh session is a quiet hole in the corner. A full one swallows half your screen. You'll always see /compact coming.

needs Ghostty 1.3+ and Claude Code · macOS & Linux · one shader file, one python script, no daemons
true gravitational lensing · accretion disk · photon ring — simulated live, nothing painted on
in the terminal: text lensing into the photon ring as the context fills
The hole floating in the corner of this page is the same physics, ported to WebGL and ray-traced live — in your terminal it goes further and gravitationally lenses your text. Try the presets in the top-right corner: Gargantua, Quasar, M87* donut, Pure lens, …

# How it works

The hole is your context window's fill level, made ambient — you never read a number, you notice the sky getting heavier. The bottom of the screen (your prompt) is never distorted.

session starts

a tiny seed of a hole appears in the corner

context fills

it grows toward half the terminal, drifts faster, roams further

/compact · /clear

snaps back to the corner seed

session ends

no hole — just your plain terminal

The same script also prints a status line, styled like Claude Code's built-in one — context fill, model, branch, session cost, rate-limit windows:

⚫️ ██████░░░░ 61% · Fable 5 · ⎇ main · $1.27 · 5h 24% · wk 41%

Curious about the physics — the ray-traced shadow, the Einstein ring, the relativistic Doppler colors? It's all in the README.

# Install

Two pieces: point Ghostty at the shader, and wire the script into Claude Code. Requires Ghostty 1.3+ (for the shader clock uniforms) and Claude Code.

  1. Clone the repo

    git clone https://github.com/s0xDk/ghostty-blackhole.git
  2. Point Ghostty at the shader

    Add to your Ghostty config — ~/.config/ghostty/config (or ~/Library/Application Support/com.mitchellh.ghostty/config on macOS) — then reload with cmd+shift+, or open a new window:

    custom-shader = /path/to/ghostty-blackhole/blackhole.glsl
    custom-shader-animation = true
  3. Wire the script into Claude Code

    Add to ~/.claude/settings.json (adjust the path). One script, three wirings — statusline for live fill, hooks for session start/end:

    {
      "statusLine": {
        "type": "command",
        "command": "/path/to/ghostty-blackhole/claude-token.py"
      },
      "hooks": {
        "SessionStart": [{ "hooks": [{ "type": "command", "command": "/path/to/ghostty-blackhole/claude-token.py" }] }],
        "SessionEnd":   [{ "hooks": [{ "type": "command", "command": "/path/to/ghostty-blackhole/claude-token.py" }] }]
      }
    }
    WiringWhen it firesWhat it does
    statusLineevery assistant turn updates the hole with the live context fill and prints the status line shown above
    SessionStart hooksession start / resume / /clear resets the hole to the tiny corner seed
    SessionEnd hooksession exit hides the hole entirely — no session, plain terminal
  4. Start a new Claude Code session

    Watch the top-right corner of your terminal. A tiny hole appears with the session and grows as you burn context. When there's no session running, there's no hole — just a plain terminal.

Notes: the setup is global, so the hole reacts to any Claude Code session; one shader file backs every Ghostty surface, so it's built for a single active session at a time.

# Make it yours

Every physical knob — disk temperature, inclination, Doppler strength, beaming, lens depth, drift — is a constant at the top of blackhole.glsl. On macOS there's a native SwiftUI tuner app with grouped sliders and presets (Gargantua, Quasar, M87* donut, Blazar, …); every nudge hot-reloads Ghostty instantly.

cd ghostty-blackhole/tuner && swift run   # or ./make-app.sh to bundle the .app

Full list of tunables in the README.