All Lounge tutorials
Lounge Pro · Tutorial

Wire Gemini CLI into your menu bar

Gemini CLI does not expose a first-class turn-complete hook today, so we use a thin shell wrapper instead. The wrapper runs the real gemini binary and POSTs a Lounge notification when it exits.

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.

Heads up: this is a wrapper pattern, not a native hook. If Google ships a first-party hook API, we'll update this page.

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 — Add the shell wrapper

Drop this into ~/.zshrc (or ~/.bashrc). It shadows the real gemini with a function that forwards every argument, captures the exit code, and fires a notification when the process ends.

bash
# ~/.zshrc  (or ~/.bashrc)
# Wraps the real `gemini` binary and fires a Lounge notification on exit.

gemini() {
  local start=$EPOCHSECONDS
  local real
  real=$(command -v gemini.real 2>/dev/null || command which -a gemini | tail -1)

  command "$real" "$@"
  local rc=$?
  local elapsed=$(( EPOCHSECONDS - start ))

  local status="complete"
  local level="info"
  local title="Gemini finished"
  if [ $rc -ne 0 ]; then
    status="failed"
    level="error"
    title="Gemini exited $rc"
  fi

  jq -nc \
    --arg title "$title" \
    --arg body "Session ran for ${elapsed}s" \
    --arg level "$level" \
    --arg project "$(basename "$PWD")" \
    --arg status "$status" \
    '{title:$title, body:$body, source:"gemini-cli",
      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 || true

  return $rc
}

Step 4 — Optional: per-prompt pings

If you mostly run one-shot prompts, this alias posts a fresh row per invocation with a preview of Gemini's answer as the body.

bash
# Optional: alias a one-shot prompt so each invocation posts its own row.
# Assumes you run Gemini non-interactively via `gemini -p "..."`.

gemini-notify() {
  local prompt="${1:-}"
  local result
  result=$(command gemini -p "$prompt")
  echo "$result"

  jq -nc \
    --arg title "Gemini answered" \
    --arg body "${result:0:240}" \
    --arg project "$(basename "$PWD")" \
    '{title:$title, body:$body, source:"gemini-cli",
      level:"info", project:$project, status:"complete"}' \
    | curl -s -X POST http://127.0.0.1:8866/notify \
        -H 'Content-Type: application/json' -d @- >/dev/null || true
}

Usage: gemini-notify "summarize README"

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.

My wrapper is recursing

Your shell function is named `gemini` and is calling `gemini` again. Use `command "$real"` with an absolute path to the real binary, or rename the real binary to `gemini.real` on PATH. `which -a gemini | tail -1` is a decent fallback but can still bite if your wrapper is the only entry on PATH.

Notifications fire mid-session

The wrapper only posts on process exit. If you leave `gemini` running in interactive mode, you will not see a turn-complete ping until you quit. Use the `gemini-notify` one-shot alias for per-turn visibility.

Don't have Lounge Pro yet?

Start a 7-day free trial — no credit card required.

See pricing