# Wire Claude Code into your menu bar

Lounge Pro ships with a local HTTP listener on `127.0.0.1:8866`. In about five minutes you'll have Claude Code firing rich notifications into your menu bar every time it finishes a task or needs your attention.

## One-click setup

### Skip the manual steps

Copy a ready-made prompt and paste it into any AI coding agent — Claude Code, Codex, Gemini, Cursor, or Aider. It detects your CLI and wires Lounge up for you.

## What you'll see

lounge_project · Stop  
Claude finished  
Task complete in lounge_project  
claude-code · just now

## Step 1 — Enable the Monitor in Lounge

1. Right-click the Lounge icon in the menu bar and pick **Settings**.  
2. Open the **Monitor** tab.  
3. Toggle **HTTP listener** on. Optionally enable the unread badge and auto-open.

The Monitor tab and the listener itself only become active with a valid Lounge Pro license. The toggle is a no-op until you activate one in Settings → License.

## Step 2 — Smoke-test the listener

Before touching your AI agent, confirm the listener accepts a request. Run this in any terminal — you should see a new row appear in the LoungePanel.

```bash
curl -X POST http://127.0.0.1:8866/notify \
  -H 'Content-Type: application/json' \
  -d '{"title":"Hello from curl","body":"Lounge is listening","source":"smoke-test","level":"info","project":"setup","event":"smoke-test","status":"complete"}'
```

## Step 3 — The `Stop` hook

Fires every time Claude finishes a turn — the canonical "Task complete" notification. The hook reads the event JSON from stdin, uses `jq` to extract the project name from `cwd`, and forwards it as the `project` field so the panel chip shows which project just finished.

Append to `~/.claude/settings.json` (merge with your existing `hooks` block if you have one):

```json
{
  "hooks": {
    "Stop": [\
      {\
        "matcher": "",\
        "hooks": [\
          {\
            "type": "command",\
            "command": "jq -c '{title:\"Claude finished\",body:(\"Task complete in \" + (.cwd | split(\"/\") | last)),source:\"claude-code\",level:\"info\",project:(.cwd | split(\"/\") | last),event:.hook_event_name,status:\"complete\"}' | curl -s -X POST http://127.0.0.1:8866/notify -H 'Content-Type: application/json' -d @- >/dev/null"\
          }\
        ]\
      }\
    ]
  }
}
```

## Step 4 — The `Notification` hook

Fires when Claude is waiting on a permission decision or input — the "come back, I need you" signal. The event payload includes a `message` field that we forward as the body, and we tag the row as `status: blocked` so it gets a yellow accent dot.

```json
{
  "hooks": {
    "Notification": [\
      {\
        "matcher": "",\
        "hooks": [\
          {\
            "type": "command",\
            "command": "jq -c '{title:\"Claude needs you\",body:(.message // \"Awaiting input\"),source:\"claude-code\",level:\"warn\",project:(.cwd | split(\"/\") | last),event:.hook_event_name,status:\"blocked\"}' | curl -s -X POST http://127.0.0.1:8866/notify -H 'Content-Type: application/json' -d @- >/dev/null"\
          }\
        ]\
      }\
    ]
  }
}
```

## Step 5 — Optional shell helper

If you want to fire notifications from arbitrary shell scripts (CI runners, build steps, custom slash commands), drop this into `~/.zshrc` or `~/.bashrc`. It auto-fills the project name from `$PWD`.

```bash
notify-claude() {
  local title="${1:-Claude}"
  local body="${2:-}"
  local status="${3:-complete}"     # complete | failed | blocked
  local level="${4:-info}"          # info | warn | error

jq -nc \
    --arg title "$title" --arg body "$body" \
    --arg level "$level" --arg status "$status" \
    --arg project "$(basename "$PWD")" \
    '{title:$title, body:$body, source:"claude-code",
      level:$level, project:$project, status:$status}' \
    | curl -s -X POST http://127.0.0.1:8866/notify \
        -H 'Content-Type: application/json' -d @- >/dev/null
}
```

Usage: `notify-claude "Build done" "passed in 2.3s" complete`

## Troubleshooting

### Nothing shows up in Lounge

Confirm Settings → Monitor is enabled and your license is active. The listener silently refuses to start without a valid license, even if the toggle is on.

### Port 8866 already in use

Another process is bound to 8866. Find it with `lsof -iTCP:8866 -sTCP:LISTEN` and stop it. The port is fixed in the current build.

### Connection refused from the CLI

The listener only binds to 127.0.0.1. If your agent runs in a container or VM, forward the port or use `host.docker.internal:8866` instead of localhost.

### Hook fires but no notification

Run `claude --debug` and watch hook stderr. The most common cause is a JSON-escaping error in the inline command. Use `jq -c` to build the payload instead of hand-quoting it.

### Notifications appear but the chip is empty

Your hook is sending the legacy schema. Make sure `project`, `event`, and `status` are at the top level of the JSON body — not nested under `metadata`.
