diff --git a/apps/cli/src/commands/thread/list.ts b/apps/cli/src/commands/thread/list.ts index 9b680d9b0..c0e59e258 100644 --- a/apps/cli/src/commands/thread/list.ts +++ b/apps/cli/src/commands/thread/list.ts @@ -66,19 +66,23 @@ export function registerListCommand( ); } +const MAX_TITLE_WIDTH = 60; + function printThreadTable(threads: Thread[]): void { const rows = threads.map((thread) => [ thread.id, + truncate(formatThreadListTitle(thread), MAX_TITLE_WIDTH), thread.projectId === PERSONAL_PROJECT_ID ? "-" : thread.projectId, formatThreadListStatus(thread), ]); const idWidth = Math.max(4, ...rows.map((row) => row[0].length)); - const projectWidth = Math.max(7, ...rows.map((row) => row[1].length)); - const statusWidth = Math.max(12, ...rows.map((row) => row[2].length)); + const titleWidth = Math.max(5, ...rows.map((row) => row[1].length)); + const projectWidth = Math.max(7, ...rows.map((row) => row[2].length)); + const statusWidth = Math.max(12, ...rows.map((row) => row[3].length)); const table = renderBorderlessTable( { - head: ["ID", "Project", "Status"], - colWidths: [idWidth, projectWidth, statusWidth], + head: ["ID", "Title", "Project", "Status"], + colWidths: [idWidth, titleWidth, projectWidth, statusWidth], }, rows, ); @@ -88,6 +92,20 @@ function printThreadTable(threads: Thread[]): void { console.log(""); } +function formatThreadListTitle(thread: Thread): string { + const title = thread.title?.trim(); + if (title) return title; + const fallback = thread.titleFallback?.trim(); + if (fallback) return fallback; + return "-"; +} + +function truncate(value: string, maxWidth: number): string { + const singleLine = value.replace(/\s+/g, " "); + if (singleLine.length <= maxWidth) return singleLine; + return `${singleLine.slice(0, maxWidth - 1)}…`; +} + function formatThreadListStatus(thread: Thread): string { const flags: string[] = []; if (thread.archivedAt !== null) {