Auto-rename active session to match current git branch (incl. parallel-agent / worktree workflows)

Resolved 💬 2 comments Opened May 27, 2026 by bareimage Closed May 31, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

Problem description

Claude Code lets users name sessions via claude -n <name> at launch or /rename <name> mid-session, and the session picker already displays the current git branch alongside each row (sessions docs). So in principle the user can tell sessions apart from the picker — the branch is right there.

The actual pain is everything that depends on the session name (not the picker's branch column):

  1. claude --resume <name> — resolves by name "across the current repository and its worktrees." If nobody manually renames, half the sessions in a project default to "the first prompt" or a conversation summary, and --resume becomes a guessing game. If two sessions have the same auto-generated default, it gets worse.
  2. Statusline, OS window title, prompt bar — any surface that displays the name shows whatever was set at launch, frozen. The branch shown next to it in the picker isn't carried into those surfaces.
  3. Logs / telemetry / external integration — anything that keys off the session name (file paths under ~/.claude/projects/, custom hooks, IDE integrations) sees stale names indefinitely.

The root cause is structural: the session name is a free-form user-managed string, but the work being done is branch-scoped. The name and the branch are decoupled, so the name needs constant manual maintenance to stay useful. In a single-session workflow nobody bothers (and they don't have to — there's only one session). In a multi-agent / multi-worktree workflow where six Claude CLIs are open in parallel, nobody is going to /rename six times after every checkout. The cost-benefit just doesn't work out for the user, so they stop, and the names rot.

This is the workflow Claude Code seems built for — multiple agents running in parallel, often in git worktrees, each on a different branch of the same repo. The session model supports it; the naming UX fights it.

Who this affects

Anyone running more than one Claude CLI against the same repo, or one CLI across multiple branches in sequence:

  • Solo devs with parallel feature work via git worktree.
  • Teams using Claude Code as a per-agent assistant where each branch has a dedicated session.
  • Anyone scripting claude --resume (e.g. wrapping it in editor shortcuts or shell scripts) — needs deterministic, predictable names.

Proposed Solution

Proposed solution

Auto-update the session name to track the current git branch, by default in git repos.

Specifically:

  • At session launch: if cwd is a git repo, set name to $(git branch --show-current).
  • After any Bash command containing git checkout, git switch, or git branch -m: re-read and update.
  • Detached HEAD: (detached) <short-sha>.
  • Non-git directory: don't auto-name; leave whatever default Claude already does.
  • Manual /rename takes precedence: an explicit user rename freezes the auto-track until they clear the override (e.g. /rename --auto to resume tracking, or until they restart the session). Protects intentional names like prod-incident-2026-05-26.

Configurable in ~/.claude/settings.json:

{
  "session": {
    "autoNameFromGitBranch": true,        // default true in git repos
    "freezeOnManualRename": true          // explicit /rename pins the name
  }
}

This makes the name mean "what branch is this session working on right now" by default, which is what users already assume when they go to claude --resume <branch>.

Alternative Solutions

Alternative solutions (in order of decreasing scope)

Option A — full auto-tracking (the proposed solution above)

Best UX, removes the manual step entirely. Requires Claude Code to observe checkouts (post-Bash inspection or .git/HEAD watcher).

Option B — expose sessionTitle on the SessionStart hook

UserPromptSubmit hooks already support a sessionTitle field in their stdout JSON (hooks docs). SessionStart does not — its supported output fields are additionalContext, initialUserMessage, watchPaths only.

Add sessionTitle to SessionStart's supported fields and the community can implement auto-naming via a one-liner:

# ~/.claude/hooks/session-start.sh
#!/usr/bin/env bash
echo "{\"hookSpecificOutput\":{\"sessionTitle\":\"$(git branch --show-current 2>/dev/null || echo session)\"}}"

This is the smallest possible change — one JSON field — and unblocks the launch-time half of the problem without any core auto-tracking. Wouldn't handle in-session checkouts, but it'd cover the parallel-agent / worktree spawn case which is the most painful one.

Option C — /rename --git one-shot

A discoverable manual re-sync command. Cheaper to implement than full auto-tracking and gives users a low-friction way to fix names without retyping the branch. Still requires the user to remember to run it — the multi-agent friction remains.

Option D — surface the branch in places that currently only show the name

Window title, statusline default, --resume listing: show <name> [<branch>] when they differ. Doesn't fix the underlying decoupling but at least makes the drift visible everywhere, not just in the picker.

Of these, B is the lowest-cost intervention that unblocks the most-painful use case (parallel agents in worktrees, all defaulting to branch names without anyone thinking about it). A is the right destination; B is the right next step.

Priority

Medium - Would be very helpful

Feature Category

CLI commands and flags

Use Case Example

Use cases

1. Parallel agents on the same repo

Claude #1 on CustomLFO, Claude #2 on main, Claude #3 on a hotfix. The picker shows three rows, each with its branch column — fine for the picker. But:

  • claude --resume CustomLFO from another shell: nobody renamed any of them, so this either fails or resolves ambiguously to whichever has a matching default summary.
  • Statusline / window title show whatever-the-launch-named-them. After a few checkouts none of those are accurate.

If each session had been auto-named to its current branch, --resume <branch> is the obvious deterministic command.

2. Worktrees of the same repo

git worktree add ../repo-branchB branchB. The picker entry for the branchB worktree session has a different cwd from the main worktree session, but the session name default is still a free-form string. --resume doesn't help disambiguate without manual naming.

3. In-session checkout

Start a session on feature-A. Halfway through, git checkout feature-B to fix something. Don't run /rename. Now the picker's branch column says feature-B (great) but the session name still says feature-A (or whatever the launch default was). Anything that keys off the name has wrong data.

4. --resume ergonomics

After a week of work in a repo, claude --resume shows N sessions. The picker UX (Ctrl+B to filter by branch) is documented and helps inside the picker. But scripting / muscle-memory wants claude --resume <branch> from the shell. That requires the title to be the branch name. Today that only happens if the user manually maintains it.

Why the existing affordances aren't enough

| Existing affordance | Why it's insufficient |
|---|---|
| Picker shows branch column | Only inside the interactive picker. Doesn't help --resume <name>, statusline, window title, scripting, hooks. |
| Ctrl+B filters picker by current branch | Same scope limit — picker only. Also requires the user to be using the picker UI, not a quick shell command. |
| /rename <branch> after every checkout | Friction. Nobody does it consistently, especially in parallel-agent workflows. The user already told Claude the info via git checkout; requiring a second redundant command means paying the same tax twice. |
| claude -n "$(git branch --show-current)" alias | Only fires at launch. In-session checkouts don't update. --resume ignores the alias. |

Additional Context

Edge cases

  • Submodules: cwd inside a submodule has its own branch. Default to the outermost repo's branch (most users think at parent-repo level); configurable override.
  • External branch change: a different terminal does git checkout while Claude is idle. A .git/HEAD watcher catches this; a one-shot at session start doesn't.
  • Branch names with / (feature/foo): valid title, /rename already accepts them.
  • Very long branch names: truncate for display, keep full string for --resume matching.
  • Detached HEAD via bisect: a single session may go through many short-SHA detached states. Auto-renaming every iteration would spam the picker. Could be opted out of, or coalesced (don't auto-rename while a bisect is in progress).

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗