From 0e533840baeda449464f0b88146c736b7f2a3c53 Mon Sep 17 00:00:00 2001 From: prateek Date: Thu, 19 Feb 2026 07:12:32 +0530 Subject: [PATCH] =?UTF-8?q?fix:=20tab=20title=20followups=20=E2=80=94=20em?= =?UTF-8?q?pty=20name=20guard,=20dedupe=20truncation=20(#121)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Guard against empty project name in getProjectName() and icon.tsx (falls back to config key or "A" initial) - Extract branch truncation into shared `truncate()` helper in session detail page - Addresses bugbot comments from PR #111 Co-authored-by: Claude Opus 4.6 --- packages/web/src/app/icon.tsx | 2 +- packages/web/src/app/sessions/[id]/page.tsx | 17 ++++++----------- packages/web/src/lib/project-name.ts | 3 ++- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/web/src/app/icon.tsx b/packages/web/src/app/icon.tsx index 910438c1c..239c481ea 100644 --- a/packages/web/src/app/icon.tsx +++ b/packages/web/src/app/icon.tsx @@ -15,7 +15,7 @@ function stringToHue(s: string): number { export default function Icon() { const name = getProjectName(); - const initial = name.charAt(0).toUpperCase(); + const initial = (name.charAt(0) || "A").toUpperCase(); const hue = stringToHue(name); return new ImageResponse( diff --git a/packages/web/src/app/sessions/[id]/page.tsx b/packages/web/src/app/sessions/[id]/page.tsx index 6967b9d31..786d72205 100644 --- a/packages/web/src/app/sessions/[id]/page.tsx +++ b/packages/web/src/app/sessions/[id]/page.tsx @@ -6,6 +6,10 @@ import { SessionDetail } from "@/components/SessionDetail"; import type { DashboardSession } from "@/lib/types"; import { activityIcon } from "@/lib/activity-icons"; +function truncate(s: string, max: number): string { + return s.length > max ? s.slice(0, max) + "..." : s; +} + /** Build a descriptive tab title from session data. */ function buildSessionTitle(session: DashboardSession): string { const id = session.id; @@ -17,18 +21,9 @@ function buildSessionTitle(session: DashboardSession): string { if (isOrchestrator) { detail = "Orchestrator Terminal"; } else if (session.pr) { - const prNum = `#${session.pr.number}`; - const branch = session.pr.branch; - const maxBranch = 30; - const truncated = branch.length > maxBranch ? branch.slice(0, maxBranch) + "..." : branch; - detail = `${prNum} ${truncated}`; + detail = `#${session.pr.number} ${truncate(session.pr.branch, 30)}`; } else if (session.branch) { - const maxBranch = 30; - const truncated = - session.branch.length > maxBranch - ? session.branch.slice(0, maxBranch) + "..." - : session.branch; - detail = truncated; + detail = truncate(session.branch, 30); } else { detail = "Session Detail"; } diff --git a/packages/web/src/lib/project-name.ts b/packages/web/src/lib/project-name.ts index b396d7deb..0a08d6e4c 100644 --- a/packages/web/src/lib/project-name.ts +++ b/packages/web/src/lib/project-name.ts @@ -14,7 +14,8 @@ export const getProjectName = cache((): string => { const config = loadConfig(); const firstKey = Object.keys(config.projects)[0]; if (firstKey) { - return config.projects[firstKey].name ?? firstKey; + const name = config.projects[firstKey].name ?? firstKey; + return name || firstKey || "ao"; } } catch { // Config not available