#7600·superset

[bug] cursor-agent hangs at "Composing" in Superset terminals because TERM_PROGRAM is hardcoded to kitty

Author: crypticpyCreated Sep 16, 2026Updated Sep 16, 2026

Where did this happen?

Desktop app (macOS), terminals spawned by the host service. The same env is built for app-pane terminals, so it applies everywhere Superset spawns a shell.

Version

  • Superset desktop 1.29.0 (desktop-v1.29.0)
  • cursor-agent 2026.09.10-fd3934a and 2026.09.15-d2fe57e (both affected)
  • macOS 26.6 (Darwin 25.6.0), zsh

What happened?

Launching cursor-agent in any Superset terminal and sending a prompt leaves the TUI spinning on "Composing" forever. The prompt never leaves the machine: the process opens no TCP connection, no Cursor hook fires (not even sessionStart), and ~/.cursor/chats/<project>/<id>/meta.json stays at "hasConversation": false with no store.db. Superset's own terminal-agent binding stays at Attached and never sees a Start/Stop.

Root cause: Superset sets TERM_PROGRAM=kitty and TERM_PROGRAM_VERSION=0.42.0 on every terminal it spawns (TERMINAL_TERM_PROGRAM / TERMINAL_TERM_PROGRAM_VERSION in the shared constants chunk, applied in the host-service terminal env builder and in the app terminal env builder) without any of the real KITTY_* variables. cursor-agent takes the kitty code path when it sees that and waits on something the xterm.js pane never answers.

Setting only that one variable in a plain pty outside Superset reproduces the hang exactly; removing it inside Superset fixes it end-to-end.

Steps to reproduce

Minimal, no Superset needed:

# any non-kitty terminal (Terminal.app, iTerm, a bare pty)
TERM_PROGRAM=kitty cursor-agent
# type any prompt, press Enter -> stuck on "Composing", no hooks, no network

Inside Superset (what a user actually hits):

  1. Open a workspace, add a Cursor Agent terminal (or agents.run with agent: "cursor-agent" via the host-service tRPC).
  2. Send any prompt (typed, or terminal.send).
  3. Observe "Composing" forever; ps -Eww on the cursor-agent process shows TERM_PROGRAM=kitty and no KITTY_PID; lsof -p shows no TCP sockets.

Control: same terminal, same prompt, with TERM_PROGRAM removed before exec -> replies within seconds, hasConversation: true, and Superset records Stop with the agent session id.

Logs, screenshots, or recordings

Env of the stuck process (trimmed):

TERM=xterm-256color
TERM_PROGRAM=kitty
TERM_PROGRAM_VERSION=0.42.0
TERM_THEME=dark
SUPERSET_AGENT_ID=cursor-agent
CURSOR_INVOKED_AS=cursor-agent

Screen after terminal.send:

  microphone check
 ⠘⠤ Composing

User-side workaround that survives app restarts (Superset rewrites ~/.superset/bin/* and ~/.superset/hooks/*, so it has to live in the user's rc file):

cursor-agent() {
  if [[ "$TERM_PROGRAM" == kitty && -z "$KITTY_PID" ]]; then
    env -u TERM_PROGRAM -u TERM_PROGRAM_VERSION cursor-agent "$@"
  else
    command cursor-agent "$@"
  fi
}

Suggested fix: stop impersonating kitty (e.g. TERM_PROGRAM=superset), or scope the impersonation to agents that need it for the kitty keyboard protocol (#2470 context). Any TUI that gates a blocking kitty capability query on TERM_PROGRAM will hit this.

Unrelated to, but worth noting alongside: ~/.superset/hooks/cursor-hook.sh v8 prints nothing for beforeSubmitPrompt and {"continue":true} for beforeShellExecution/beforeMCPExecution, which does not match Cursor's documented hook output schema ({"continue":true} and {"permission":"allow|deny|ask"} respectively). Tested: cursor-agent currently tolerates it, so it is not the cause here, but it is one Cursor release away from being one.