HookStack
Back to catalogue
ContextUserPromptSubmit

Automatic session naming

Each session gets a name, not a hash

Automatically generates a creative one-word name for each session (e.g. Phoenix, Sage, Nova) on the first prompt, for more human-friendly session tracking.

What does the Automatic session naming hook do?

Automatic session naming is a Claude Code UserPromptSubmit hook. It fires automatically at that lifecycle event — outside the model, so it can't be skipped or forgotten. Each session gets a name, not a hash.

As a UserPromptSubmit hook it runs before the action completes, so it can block or adjust what Claude is about to do. Because it is a deterministic Node.js script, it executes on every matching event without relying on the model to remember — the guarantee that makes agentic workflows safe to automate.

Use cases

  • Identify sessions in logs by a memorable name
  • Personalize subagent TTS announcements

Tags

#session#naming#agent#identity#personalization

settings.json fragment

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/user-prompt-name-agent.mjs",
            "type": "command"
          }
        ]
      }
    ]
  }
}

Script · .claude/hooks/user-prompt-name-agent.mjs

#!/usr/bin/env node
// @hookstack user-prompt-llm-agent-name
// Attribue un nom à l'agent pour la session courante (UserPromptSubmit)
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { homedir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";

const NAMES = [
	"Phoenix",
	"Sage",
	"Nova",
	"Echo",
	"Atlas",
	"Cipher",
	"Nexus",
	"Oracle",
	"Aurora",
	"Vortex",
];

export function run(
	input,
	{
		exists = existsSync,
		readFile = readFileSync,
		writeFile = writeFileSync,
		mkdir = mkdirSync,
		home = homedir(),
		pickName = () => NAMES[Math.floor(Math.random() * NAMES.length)],
	} = {},
) {
	const sessionId = input.session_id ?? "unknown";
	const dir = join(home, ".claude", "data", "sessions");
	mkdir(dir, { recursive: true });

	const file = join(dir, `${sessionId}.json`);
	let data = { session_id: sessionId };
	if (exists(file)) {
		try {
			data = JSON.parse(readFile(file, "utf8"));
		} catch {}
	}

	if (data.agent_name) return null;

	data.agent_name = pickName();
	writeFile(file, JSON.stringify(data, null, 2));
	return `Tu t'appelles **${data.agent_name}** pour cette session.\n`;
}

/* v8 ignore next 5 */
if (process.argv[1] === fileURLToPath(import.meta.url)) {
	const input = JSON.parse(readFileSync(0, "utf8"));
	const result = run(input);
	if (result) process.stdout.write(result);
}

Learn more

Related hooks