feat(sessions): launch every Claude session with --name set to its tab name

This commit is contained in:
Devvyn committed 2026-10-18 13:45:42 +08:00
1 parent 0ab71d61d1
commit 1fefeda0dd
3 files changed
+25 -19

No files matched your search

@@ -0,0 +1,5 @@
---
'aicodeman': minor
---
A Claude session is now launched with `--name <tab name>` for every tab, not only for ones you renamed. Claude Code's prompt-box label, `/resume` entry and its remote session list used to show Claude's own generated title (for example "Git indicator guard test and teardown flake") for a tab that Codeman called `w4-Codeman`; they now read the same as the tab. A rename or an auto-name reaches the CLI at its next spawn.
+11 -8
View File
@@ -1806,16 +1806,19 @@ export class Session extends EventEmitter {
}
/**
* The name to pin on the Claude CLI as `--name`, or undefined to let Claude
* title the conversation itself. `--name` is the prompt-box label, the
* `/resume` picker entry and the terminal title all at once, and a pinned
* title stops Claude generating its own, so only a name the user chose is
* worth pinning. Pinning the `w1-myapp` placeholder gave every conversation
* in a case the same `/resume` entry; an auto name is a cut of the first
* prompt, which Claude's own generated title already beats.
* The name to pin on the Claude CLI as `--name`: the tab's own name, whatever its source,
* so the CLI's prompt-box label, `/resume` entry and terminal title (and Claude Code's
* remote session list) read the same as the tab. Leaving a placeholder or auto-named tab
* unpinned let Claude generate its own title, which then differed from the tab it was
* running in (`w4-myapp` in Codeman, "Fix the flaky teardown" in Claude).
*
* The cost is that every conversation of a case starts with the same `/resume` entry shape
* (`w1-myapp`, `w2-myapp`); the tab number keeps those distinct per tab. A rename or an
* auto-name reaches the CLI at the next spawn: a process started with `--name` re-appends its
* in-memory title after each turn (see claude-session-title.ts).
*/
get cliPinnedName(): string | undefined {
return this._nameSource === 'manual' ? this._name : undefined;
return this._name.trim() ? this._name : undefined;
}
setAutoClear(enabled: boolean, threshold?: number): void {
+9 -11
View File
@@ -1,11 +1,10 @@
/**
* @fileoverview Claude's `/resume` title belongs to Claude unless the user chose one.
* @fileoverview The CLI's session name is the tab's name.
*
* `--name` sets the prompt-box label, the `/resume` picker entry and the terminal
* title, and a pinned title stops Claude generating its own. Pinning the
* `w1-myapp` placeholder therefore listed every conversation of a case under the
* same name in `/resume`. Only a manual name is pinned now (`cliPinnedName`), and
* a rename reaches the transcript as a `custom-title` row.
* title, and a pinned title stops Claude generating its own. Every tab's name is pinned
* (`cliPinnedName`), placeholder and auto names included, so Claude's own session list
* matches the tab. A rename reaches the transcript as a `custom-title` row.
*/
import { mkdtempSync, readFileSync, rmSync, writeFileSync, existsSync } from 'node:fs';
@@ -18,19 +17,18 @@ import { appendClaudeCustomTitle } from '../src/claude-session-title.js';
type RespawnOptionsProbe = { _buildRespawnPaneOptions(): { name?: string; cliName?: string } };
describe('Session.cliPinnedName', () => {
it('pins nothing for a placeholder, so Claude titles the conversation itself', () => {
it('pins the placeholder name, so the CLI session matches the tab', () => {
const session = new Session({ workingDir: '/tmp', name: 'w1-demo' });
expect(session.cliPinnedName).toBeUndefined();
expect(session.cliPinnedName).toBe('w1-demo');
const options = (session as unknown as RespawnOptionsProbe)._buildRespawnPaneOptions();
// The tab keeps its name; only the CLI flag is withheld.
expect(options.name).toBe('w1-demo');
expect(options.cliName).toBeUndefined();
expect(options.cliName).toBe('w1-demo');
});
it('pins nothing for an auto name, whose cut of the prompt Claude beats', () => {
it('pins an auto name too, from the next spawn', () => {
const session = new Session({ workingDir: '/tmp', name: 'w1-demo' });
expect(session.applyAutoName('w1-demo: fix the login redirect')).toBe(true);
expect(session.cliPinnedName).toBeUndefined();
expect(session.cliPinnedName).toBe('w1-demo: fix the login redirect');
});
it('pins a name the user chose, at creation or by a rename', () => {