stacklok / stacklok/mecatl

mecatui: conversation title never reaches the iTerm2 tab label (OSC 2 only)

Open
#1,460 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug tui
Dominant language
Go
Stars
152
Forks
16
Avg merge
14h 48m
Merged PRs (30d)
536

Description

Bug description

In iTerm2 the terminal tab label does not show the mecatui conversation title, so with
several mecatui tabs open there is no way to tell which tab holds which conversation —
every tab reads the same.

mecatui does implement a dynamic terminal title (cmd/mecatui/ui/wintitle.go
(windowTitle), wired at cmd/mecatui/ui/view.go via v.WindowTitle, opt-out
--terminal-title=off). The session title is seeded set-once from the first genuine
prompt (cmd/mecatui/ui/update.go, provenance first-prompt) and later replaced by a
generated title, so a title value genuinely exists.

The gap is at the terminal boundary. Bubble Tea v2 renders tea.View.WindowTitle
through ansi.SetWindowTitle, which emits OSC 2 ; title ST — the xterm window
title. In iTerm2 the tab label is a separate concept, driven by the profile's
Settings → Profiles → General → Title checkboxes, which default to the job name.
The job name for this process is mecatui, so every tab is labelled mecatui no matter
what title mecatui sets. The window title bar does update; the tab strip does not.

tea.View.WindowTitle's own doc comment says "Support depends on the terminal", and this
is exactly that case: the sequence is sent correctly and the terminal ignores it for the
surface the user is actually looking at.

Steps to reproduce

  1. On macOS, in iTerm2 with a default profile (Title = "Job Name").
  2. Open two or more iTerm2 tabs and run mecatui in each.
  3. Send a distinct first prompt in each tab (e.g. "fix the login bug" / "write release notes").
  4. Look at the tab strip.

Expected behavior

Each tab label carries enough of the conversation title to distinguish the tabs, e.g.
fix the login bug sess-abcd — Working, matching the format windowTitle already
composes.

Actual behavior

Every tab reads mecatui. The composed title reaches the window title bar only, which is
hidden in a maximized/tabbed iTerm2 window, so tab switching is guesswork.

Environment

  • OS/version: macOS 26.5.1 (build 25F80), arm64
  • Terminal: iTerm2, default profile (Title = Job Name), no tmux/screen multiplexer
  • mecatl version or commit: mecatui v0.0.35 @ ebb14c78
  • Deployment shape: mecatui (embedded engine over a UNIX socket)
  • Relevant flags: none — --terminal-title left at its on default
  • Dependency: charm.land/bubbletea/v2 v2.0.8, github.com/charmbracelet/x/ansi v0.11.7

Additional context

Why OSC 2 alone is not enough
Sequence Sets iTerm2 tab strip
OSC 0 ; title window title and icon name honoured when the profile's icon/name component is enabled
OSC 1 ; title icon name only ditto
OSC 2 ; title window title only (what we send today) ignored while Title = Job Name

Terminals that show OSC 2 in the tab (Ghostty, Alacritty, Kitty, WezTerm, GNOME
Terminal) mask this, which is likely why it was not caught during the original work —
cmd/mecatui/ui/wintitle_test.go asserts the composed string, which is correct and
still passes; nothing asserts which sequence carries it.

Candidate directions (not a decision)
  1. Also emit OSC 1 (icon name) alongside the window title so iTerm2's name component
    picks it up. Broadly portable; still depends on the user's profile checkboxes.
  2. Document the iTerm2 profile setting in the --terminal-title flag help and the
    owning user-docs/ page: Settings → Profiles → General → Title, enable the session/app
    name component. Cheapest fix, and worth doing regardless of the code direction.
  3. iTerm2 proprietary OSC 1337 ; setUserVar or an explicit tab-title sequence. Most
    direct, but terminal-specific and needs a detection path — likely the wrong trade.

Direction 2 is worth doing regardless; 1 and 3 need a decision.

Related request: system context in the title

Separately from the iTerm2 problem: when several mecatui sessions run against different
checkouts
, the conversation title alone is still ambiguous. It would help to optionally
include system context in the composed title — working directory basename and/or git
branch — e.g.:

mecatl@main fix the login bug sess-abcd — Working mecatui

This is additive to windowTitle and would need to respect the existing 40-rune
windowTitleRunes budget and the title-leads/status-trails ordering (tab bars truncate
from the right). Flagging it here for scoping — happy to split it into its own issue if
the maintainers prefer to keep this one focused on the iTerm2 sequence problem.

Scope note

Per docs/development-process.md this reads as Routine if it lands as
documentation plus an extra escape sequence, but Bounded if the system-context
addition lands too, since that changes the composed title contract and its rune budget.
Maintainer call.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with cmd/mecatui/ui/wintitle.go, cmd/mecatui/ui/view.go, and cmd/mecatui/ui/update.go, then inspect Bubble Tea v2's ansi.SetWindowTitle behavior. Read cmd/mecatui/ui/wintitle_test.go and docs/development-process.md before resolving whether the fix is an additional terminal sequence, documentation, or both. Done means the selected direction is implemented and tested, with the iTerm2 profile requirement documented if applicable.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.