Chime when your agent is done

Your agent and this browser share a machine, so there is no cloud and no account: a small relay listens on localhost, your agent’s hooks poke it, and every linked tab chimes, ducks the ambience, and pauses your game.

npx compiling setup

Starts the relay, opens this page to link your browser, and offers to install the hooks. The three steps below are the same thing, by hand.

  1. Start the relay

    npx compiling relay

    Binds 127.0.0.1:8303 — loopback only, nothing leaves your machine — and keeps running while you work. Port 8303, because xkcd #303.

  2. Install the agent hooks

    npx compiling hook claude --install

    Merges two hooks into ~/.claude/settings.json. Stop fires when a turn ends; Notification fires when Claude is blocked on you — a permission prompt or a question — which is the more urgent signal.

    Merge the JSON yourself instead
    {
      "hooks": {
        "Stop": [
          {
            "hooks": [
              {
                "type": "command",
                "command": "curl -s -m 1 -X POST http://127.0.0.1:8303/event -H 'content-type: application/json' -d '{\"type\":\"done\",\"source\":\"claude-code\"}' >/dev/null 2>&1 || true"
              }
            ]
          }
        ],
        "Notification": [
          {
            "hooks": [
              {
                "type": "command",
                "command": "curl -s -m 1 -X POST http://127.0.0.1:8303/event -H 'content-type: application/json' -d '{\"type\":\"waiting\",\"source\":\"claude-code\"}' >/dev/null 2>&1 || true"
              }
            ]
          }
        ],
        "UserPromptSubmit": [
          {
            "hooks": [
              {
                "type": "command",
                "command": "curl -s -m 1 -X POST http://127.0.0.1:8303/event -H 'content-type: application/json' -d '{\"type\":\"started\",\"source\":\"claude-code\"}' >/dev/null 2>&1 || true"
              }
            ]
          }
        ]
      }
    }

    The -m 1 … || true shape matters: fire-and-forget with a one-second cap, so a stopped relay never slows your agent down. Any agent that can run a command when it finishes can curl the relay the same way.

  3. Link this browser

    Opt-in and remembered per browser; a agent linked dot sits in the header while the socket is up. From the keyboard: ⌘Kagent link.

Check it works

curl -s -X POST http://127.0.0.1:8303/event -d '{"type":"done"}'

A soft two-note chime, and the tab title flips. With several tabs linked, only the one you touched most recently chimes — the rest just dip their ambience.

Privacy & security

  • Loopback only. No network calls leave your machine, in either direction, and there is nothing to sign in to.
  • No tokens, deliberately: the worst any local process can do is play you a soft chime. Events carry a type and an optional short label — nothing sensitive.
  • The relay checks WebSocket origins, so other pages you visit can’t listen in. The site never uses browser notifications — the chime, the title, and the dot are the whole surface.
  • If your browser blocks localhost sockets, the site behaves as if no relay exists; nothing breaks. Chromium browsers (Chrome, Edge, Arc, Brave) allow it — the pattern Discord and Figma use for their local helpers.

The rest of the CLI → a chime for any slow command, games in your terminal, and driving the linked tab from the shell.