Jump to content

Organizing Coder Terminals: Difference between revisions

From MediawikiCIT
Justinaquino (talk | contribs)
Updated: default title is now the command reminder 'title "project"' (2026-05-02)
Justinaquino (talk | contribs)
Added RCA: tmux send-keys broke launchers, fixed with direct exec; ce-char-gen troubleshooting
 
Line 142: Line 142:
| <code>title</code> command not found || <code>.bashrc</code> not loaded || Start an interactive shell, or run <code>source ~/.bashrc</code>
| <code>title</code> command not found || <code>.bashrc</code> not loaded || Start an interactive shell, or run <code>source ~/.bashrc</code>
|-
|-
| Default title shows <code>title "project"</code> || Working as designed — it's the syntax reminder || Type <code>title "your real project"</code> to replace it
| Default title shows <code>title "project"</code> || Working as designed — syntax reminder || Type <code>title "your real project"</code> to replace it
|-
| Tmux status bar shows <b>"ce char gen"</b> || Old <code>~/.tmux.conf</code> on host hardcoded the title || Replace host <code>~/.tmux.conf</code> with container's clean version
|-
|-
| AI agent crashed and pane is dead || Process exited || Press <code>Ctrl+b r</code> to respawn
| AI agent crashed and pane is dead || Process exited || Press <code>Ctrl+b r</code> to respawn
Line 148: Line 150:
| Session already exists || Previous session still running || <code>tmux attach -t &lt;name&gt;</code> or <code>tmux kill-session -t &lt;name&gt;</code>
| Session already exists || Previous session still running || <code>tmux attach -t &lt;name&gt;</code> or <code>tmux kill-session -t &lt;name&gt;</code>
|}
|}
== RCA: Why Tmux Broke the Original Launch Scripts ==
=== What Worked Before (No Tmux) ===
<pre>
distrobox enter agent260411 -- bash -c 'cd /home/justin/opencode260220 && ./csb.sh; exec bash'
</pre>
<code>./csb.sh</code> does <code>exec claude</code>, which replaces the shell with the interactive AI agent. Claude owns the TTY and runs until the user exits.
=== What Broke (First Tmux Attempt) ===
The initial <code>tmux-launcher.sh</code> used <code>tmux send-keys</code> to type commands into a detached session:
<pre>
tmux new-session -s "$SESSION" -n "$WINDOW" -d
tmux send-keys -t "$SESSION:$WINDOW" "./csb.sh" C-m
tmux attach-session -t "$SESSION"
</pre>
=== Why This Failed ===
# '''Race condition''': <code>send-keys</code> types faster than the shell initializes. The command often arrived before bash was ready, causing "command not found" or silent failure.
# '''No TTY guarantee''': Interactive apps (Claude, Kimi) need a controlling terminal. <code>send-keys</code> provides a pane but doesn't guarantee the app receives proper TTY initialization before the keystrokes land.
# '''Exit timing''': If the app started before attach, the user attached to a pane that was already dead or mid-execution.
=== The Fix ===
Replace <code>send-keys</code> with direct command execution via a wrapper script. This gives tmux the full command upfront, so it initializes the TTY properly before the app starts — exactly like the original scripts, just wrapped in tmux.


== See Also ==
== See Also ==

Latest revision as of 08:13, 2 May 2026

Problem

When running multiple AI coding agents (Claude, Kimi, Qwen, OpenCode) in separate GNOME Terminal windows, every tab looks identical — usually titled by the running process name (e.g., "Kimi Code"). After opening 3–4 terminals, it becomes impossible to tell at a glance which terminal belongs to which project without clicking into each one.

GNOME Terminal 3.44+ removed the "Set Title" option from the tab right-click menu, eliminating the old manual workaround.

Solution

Use tmux inside every terminal:

  • One named tmux session per project (e.g., claude, kimi, qwen)
  • A title bash command that renames both the tmux window and the terminal title
  • Persistent panes — if an AI agent crashes, the pane stays alive and can be respawned

Quick Start

Launch All Agents at Once

Run on the Ubuntu desktop:

~/start_dev_env.sh

This opens 5 GNOME Terminal windows:

# Window Title Tmux Session Purpose
1 Claude Code — tmux claude Claude Code AI agent
2 OpenCode Claude — tmux opencode-claude OpenCode (Claude provider)
3 OpenCode Kimi — tmux kimi OpenCode (Kimi provider)
4 OpenCode Qwen — tmux qwen OpenCode (Qwen provider)
5 Tmux — General general Plain bash for git, docker, file ops

Each session survives even if the GNOME Terminal window is closed.

Launch Individual Agents

Double-click any desktop launcher:

  • ~/Desktop/claude.sh
  • ~/Desktop/kimi.sh
  • ~/Desktop/opencode.sh
  • ~/Desktop/Qwen.sh

Each launcher auto-creates or reattaches to its tmux session.

How to Title Your Session

The Default Title Is the Command Itself

Every new terminal opens with the title:

title "project"

This is intentional — the default title is the command reminder. You never forget the syntax because it's staring at you from the tab.

Change It

Inside any terminal, type:

title "ce char gen"

This does two things:

  1. Renames the tmux window (visible in the green status bar at the bottom)
  2. Sets the GNOME Terminal tab/window title

Change it anytime:

title "mneme shipgen"
title "IT-knowledge docs"
title "$(hostname)"   # reset to hostname

The title auto-resets after every shell prompt, so AI agents cannot overwrite it.

Tmux-Only Renaming

tmux rename-window "my project"     # rename current window
tmux rename-session "newname"       # rename entire session

Key Shortcuts

Key Action
Ctrl+b , Rename current window (interactive prompt)
Ctrl+b r Respawn pane (restart AI agent if it crashed)
Ctrl+b d Detach session (keeps it running in background)
Split pane horizontally
Ctrl+b - Split pane vertically
Alt+Arrow Switch panes
Ctrl+b R Reload tmux config

Reattaching to Sessions

If a terminal window is closed, the tmux session keeps running:

tmux list-sessions
tmux attach-session -t claude
tmux attach-session -t kimi

Aliases added to ~/.bashrc:

tls     # list sessions
tas claude    # attach to claude session

Configuration Files

File Purpose
~/.tmux.conf Tmux settings (status bar, mouse, key bindings)
~/.bashrc title() function + auto-reset + tmux aliases
~/.config/tmux-launcher.sh Helper script for desktop launchers

Troubleshooting

Symptom Cause Fix
Title shows "Kimi Code" instead of custom AI resets it via escape sequences PROMPT_COMMAND auto-resets after every prompt
Tab right-click has no "Set Title" GNOME Terminal 3.44+ removed it Use title bash command or Ctrl+b ,
title command not found .bashrc not loaded Start an interactive shell, or run source ~/.bashrc
Default title shows title "project" Working as designed — syntax reminder Type title "your real project" to replace it
Tmux status bar shows "ce char gen" Old ~/.tmux.conf on host hardcoded the title Replace host ~/.tmux.conf with container's clean version
AI agent crashed and pane is dead Process exited Press Ctrl+b r to respawn
Session already exists Previous session still running tmux attach -t <name> or tmux kill-session -t <name>

RCA: Why Tmux Broke the Original Launch Scripts

What Worked Before (No Tmux)

distrobox enter agent260411 -- bash -c 'cd /home/justin/opencode260220 && ./csb.sh; exec bash'

./csb.sh does exec claude, which replaces the shell with the interactive AI agent. Claude owns the TTY and runs until the user exits.

What Broke (First Tmux Attempt)

The initial tmux-launcher.sh used tmux send-keys to type commands into a detached session:

tmux new-session -s "$SESSION" -n "$WINDOW" -d
tmux send-keys -t "$SESSION:$WINDOW" "./csb.sh" C-m
tmux attach-session -t "$SESSION"

Why This Failed

  1. Race condition: send-keys types faster than the shell initializes. The command often arrived before bash was ready, causing "command not found" or silent failure.
  2. No TTY guarantee: Interactive apps (Claude, Kimi) need a controlling terminal. send-keys provides a pane but doesn't guarantee the app receives proper TTY initialization before the keystrokes land.
  3. Exit timing: If the app started before attach, the user attached to a pane that was already dead or mid-execution.

The Fix

Replace send-keys with direct command execution via a wrapper script. This gives tmux the full command upfront, so it initializes the TTY properly before the app starts — exactly like the original scripts, just wrapped in tmux.

See Also