File size: 1,544 Bytes
60e40a4
 
 
54bf49f
 
 
60e40a4
54bf49f
 
 
 
 
60e40a4
 
 
 
082a73e
 
 
 
 
60e40a4
 
 
 
 
 
54bf49f
 
60e40a4
54bf49f
60e40a4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// What an agent is called when it is shown on its own: `[Group] name`.
//
// The sidebar and the Overview already draw the group as a frame around its
// agents, so they say it once and leave the rows bare. A pane header has no
// such frame — four tiles named `claude-code-N` are indistinguishable — so it
// spells the group out.
//
// The prefix is context and the name is the thing you are looking for. Fitting
// the two into a narrow header is CSS's job (`.ph-group` shrinks and then hides
// before `.ph-name` gives up a pixel); what this module owns is the plain
// string, which goes in the header's tooltip and is deliberately NOT shortened
// — the tooltip is where you go when the header ran out of room.

/**
 * The group's display name, or null when the session sits loose in the tree.
 *
 * Ungrouped is an absence here, not a word: `/api/tree` gives the app groups
 * with their `sessionIds`, so a loose session is simply one no group lists and
 * the caller has nothing to pass. Every empty shape collapses to the same bare
 * name — there is no `[None] foo`. (The roster that agents read, `/api/agents`,
 * spells the same absence as `group: null`.)
 */
export function groupLabel(name?: string | null): string | null {
  const trimmed = (name ?? '').trim();
  return trimmed ? trimmed : null;
}

/** `[Group] name`, whole; a bare name when the session has no group. */
export function sessionTitle(name: string, group?: string | null): string {
  const g = groupLabel(group);
  return g ? `[${g}] ${name}` : name;
}