import { artifacts } from '../artifacts.svelte'; import { place } from '../format'; import { SvelteMap } from 'svelte/reactivity'; import { sessions } from '../sessions.svelte'; import { childrenOf, windows, type Tile } from './tree'; type Shown = { type: string; data: Record }; /** Where each live shell says it is, by terminal id: the window title and its tab read the same of it. */ export const shells = new SvelteMap(); /** What a tab calls a window, from its record alone: an inactive tab's window is not mounted to ask. */ export function windowTitle(window: Shown): string { const data = window.data; const session = typeof data.sessionId === 'string' ? sessions.byId.get(data.sessionId) : undefined; const name = session?.name || 'untitled session'; switch (window.type) { case 'session': return name; case 'artifact': return (typeof data.artifact === 'string' && artifacts.get(data.artifact)?.title) || 'artifact'; case 'pty': { const live = typeof data.terminalId === 'string' ? shells.get(data.terminalId) : undefined; const cwd = live?.cwd || (typeof data.cwd === 'string' ? data.cwd : ''); return `terminal · ${data.title || (cwd ? place(cwd) : live?.shell || 'shell')}`; } case 'chip': return data.chip === 'model' ? 'context' : String(data.chip); case 'note': return 'note'; default: return `${window.type} · ${name}`; } } /** What a tab calls window `id` of `records`, which may have closed. */ export function windowName(id: string, records: Record): string { return records[id] ? windowTitle(records[id]) : 'window'; } /** What a tab or a section is called: its name, else its window's title, else what it holds. */ export function tileTitle(tile: Tile, records: Record): string { if (tile.name) return tile.name; if (tile.kind === 'leaf') return windowName(tile.window, records); if (tile.kind !== 'canvas') return childrenOf(tile).map((child) => tileTitle(child, records)).join(', '); const count = windows(tile).length; return count ? `canvas · ${count} ${count === 1 ? 'window' : 'windows'}` : 'empty canvas'; }