Programmatic session naming — hook-callable rename + Skill tool as hook target
Status Fixed / completed
Maintainer reply None cached
Workaround ✓ Mentioned in thread ↓
Activity 7 comments · opened Apr 7, 2026 · closed Aug 17, 2026
Problem
When running multiple sessions across repos and skills, session titles default to generic names, creating working memory tax when switching between them. Manually renaming is possible but breaks flow.
Two missing pieces block automation:
- No hook-callable rename — \
/rename\exists but is interactive-only. Hooks (shell commands) have no mechanism to set or update the session title. - Skill tool isn't hookable — \
PreToolUse\/\PostToolUse\support named tools (\Bash\, \Edit\, \Agent\, etc.) but \Skill\isn't a matchable target, so there's no hook point when a skill is invoked.
Proposed solution
- Expose session rename via hook output — e.g., a structured JSON field hooks can return: \
{"session_title": "wolf-way goforit"}\ - Add \
Skill\as a matchable tool name in \PreToolUse\/\PostToolUse\hooks, with \tool_input.skill\in the hook payload
Desired behavior
A \PreToolUse\ hook on \Skill\ fires, reads \tool_input.skill\, sets the session title to \{repo} {skill}\ — session is named before the skill even runs. Zero manual steps.
Scope
Applies to Claude Code CLI today. Claude Desktop would benefit from the same platform capability once available.
Showing cached comments. Read the full discussion on GitHub ↗
5 Comments
+1 on this — my use case overlaps the first half (hook-callable rename) and adds a data point on why the obvious DIY workaround doesn't work.
Use case
SessionEndhook that reads a pending title from~/.claude/.rename-pending/<sid>.txt(written by some upstream process — backlog item id, commit subject, etc.) and applies it to the just-ended session.What I tried
Since Claude Code itself writes
{"type":"custom-title", ...}lines into the session JSONL during init //rename, I wrote a hook that does the same. Two iterations:custom-titleline (or insert after line 1) via atomic temp-file + rename — still no sidebar update, even after desktop-app relaunch.So the JSONL isn't authoritative for the sidebar. Corroborated by #37449 ("stat-log index not synced from JSONL") and #39228 (sessions with
custom-titlemid-file disappear from the panel — so the reader is position-sensitive and index-cached).Concrete API suggestion
Matches the proposal in this issue. A
SessionEnd(or newSessionRename) hook returning JSON on stdout:The runtime would:
custom-titleline to the JSONL for continuity with the existing on-disk format.Stdin to the hook already carries
session_idandtranscript_path; returning a title on the same channel means no consumer has to reverse-engineer the index format (which is the thing that burned me — I never found where the sidebar actually reads from).Scope note
Also relevant for #36379 (auto-titles override user renames) and #41378 (desktop app doesn't reflect title changes until reactivation) — a single authoritative write path from hooks would simplify the fix for all three.
human here - I just want the session names to reflect the work, not the first action ('check memory' or whatever)
+1 — adding a concrete use case from a different angle.
As a user with a "prefix session title with
#<num> —whenever a GitHub issue is referenced" convention enforced via memory rules, I have no way to apply this automatically. The model "knows" the rule and can include it in chapter titles viamark_chapter, but the session title in the sidebar stays whatever was inferred from my first prompt — usually something like "Investigate failing test" instead of "#5484 — Investigate failing test".Use cases beyond the original
#1234 — ...,[ABC-42] ...)[acme] ...,[vd] ...for multi-tenant work)API preference
Of the options floated across #44786 / #40496 / #41888, the hook stdout JSON (
{"sessionTitle": "..."}) is the most composable — it works from SessionStart, UserPromptSubmit, and SessionEnd uniformly, and doesn't require new tool plumbing. An MCP toolset_session_titlewould be a nice complement for in-conversation renames driven by the model itself.Current workaround
Manual rename in the sidebar after each session — brittle and easy to forget. Tried writing
custom-titlelines into the JSONL (per this issue's investigation) — sidebar doesn't pick them up.+1 with a Windows Desktop App data point — this confirms the override behaviour is cross-platform, not just CLI/IDE.
Setup
autoUpdatesChannel: "latest"UserPromptSubmithook in~/.claude/settings.jsoncalling a script that emits{"hookSpecificOutput":{"hookEventName":"UserPromptSubmit","sessionTitle":"YYYY.MM.DD MyProject"}}Observed
``
``=== <date> <time> ===
CLAUDE_PROJECT_DIR=<project>/.claude/worktrees/<id>
title=2026.05.01 MyProject
Add tests for core functionalityfor atestprompt). Hook-supplied title is never visibly applied — even after Claude Code restart and full Windows reboot./renamenot available in the Desktop App env (/rename isn't available in this environment.), so no in-app workaround.Why this matters here
The fix proposed in this issue (authoritative hook stdout
{"sessionTitle": "..."}write path that updates the index/sidebar without relaunch) would also resolve the silent override on Desktop App — the auto-titler currently wins the race against the hook output, leaving documentedhookSpecificOutput.sessionTitleeffectively non-functional for end users on Desktop.Happy to share the full hook script + log if useful.
The workaround that I'm currently using:
A UserPromptSubmit hook (in ~/.claude/settings.json) runs a script that reads transcript_path from stdin, extracts your last assistant turn, and greps for a marker like <!--rename: TITLE -->, emitting {"hookSpecificOutput":{"hookEventName":"UserPromptSubmit","sessionTitle":"TITLE"}} — because only SessionStart/UserPromptSubmit (not Stop) can set the title, so the rename lands on your next message.
A CLAUDE.md rule instructs Claude to end replies with that marker when the session name is stale, so naming happens automatically with no /rename copy-pasting — just a one-message delay.