From 09fa7aa6c14bcd927a38ff0491ae5c1f70c68057 Mon Sep 17 00:00:00 2001 From: Christopher Tso Date: Tue, 30 Jun 2026 00:07:46 +0200 Subject: [PATCH] refactor(projects): drop redundant project name field, display id The project registry `name` field duplicated `id` for display purposes and always fell back to `id` when absent. Remove it from the wire schema, core types, dashboard, CLI serve, and docs; the dashboard now displays the project id directly. Deletes the trivial project-display-name helper. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- apps/cli/src/commands/results/serve.ts | 7 +----- apps/cli/test/commands/results/serve.test.ts | 9 -------- apps/dashboard/src/components/Breadcrumbs.tsx | 12 +++------- apps/dashboard/src/components/ProjectCard.tsx | 8 +++---- apps/dashboard/src/lib/api.test.ts | 2 -- apps/dashboard/src/lib/api.ts | 1 - .../src/lib/project-display-name.test.ts | 23 ------------------- .../dashboard/src/lib/project-display-name.ts | 21 ----------------- apps/dashboard/src/lib/types.ts | 4 ---- apps/dashboard/src/routes/index.tsx | 4 ++-- .../src/routes/projects/$projectId.tsx | 5 +--- .../docs/docs/evaluation/running-evals.mdx | 1 - .../src/content/docs/docs/tools/dashboard.mdx | 5 ---- .../evaluation/validation/config-validator.ts | 1 - packages/core/src/projects.ts | 8 +------ .../validation/config-validator.test.ts | 7 ------ .../evaluation/workspace/repo-manager.test.ts | 2 -- packages/core/test/projects.test.ts | 10 ++------ 18 files changed, 14 insertions(+), 116 deletions(-) delete mode 100644 apps/dashboard/src/lib/project-display-name.test.ts delete mode 100644 apps/dashboard/src/lib/project-display-name.ts diff --git a/apps/cli/src/commands/results/serve.ts b/apps/cli/src/commands/results/serve.ts index d35facc6f..23e6370aa 100644 --- a/apps/cli/src/commands/results/serve.ts +++ b/apps/cli/src/commands/results/serve.ts @@ -3213,14 +3213,12 @@ export function createApp( /** Convert a ProjectEntry to snake_case wire format. */ function projectEntryToWire(entry: { id: string; - name: string; path: string; addedAt: string; lastOpenedAt: string; }) { return { id: entry.id, - name: entry.name, path: entry.path, added_at: entry.addedAt, last_opened_at: entry.lastOpenedAt, @@ -3317,7 +3315,6 @@ export function createApp( const summary = await summarizeProjectRunMetas(project); return c.json({ id: project.id, - name: project.name, path: project.path, run_count: summary.runCount, pass_rate: summary.passRate, @@ -3353,7 +3350,6 @@ export function createApp( tag_revision: string; source: 'local' | 'remote'; project_id: string; - project_name: string; }> = []; for (const p of registry.projects) { @@ -3407,7 +3403,6 @@ export function createApp( ...(runtimeSource && { runtime_source: runtimeSource }), ...tagFields, project_id: p.id, - project_name: p.name, }); } } catch { @@ -3783,7 +3778,7 @@ export const resultsServeCommand = command({ if (add) { try { const entry = addProject(add); - console.log(`Registered project: ${entry.name} (${entry.id}) at ${entry.path}`); + console.log(`Registered project: ${entry.id} at ${entry.path}`); } catch (err) { console.error(`Error: ${(err as Error).message}`); process.exit(1); diff --git a/apps/cli/test/commands/results/serve.test.ts b/apps/cli/test/commands/results/serve.test.ts index 04d59df07..c3545cf49 100644 --- a/apps/cli/test/commands/results/serve.test.ts +++ b/apps/cli/test/commands/results/serve.test.ts @@ -673,14 +673,12 @@ describe('serve app', () => { expect(create.status).toBe(201); const created = (await create.json()) as { id: string; - name: string; path: string; added_at: string; last_opened_at: string; }; expect(created).toMatchObject({ id: 'project-to-register', - name: 'project-to-register', path: projectDir, }); expect(created.added_at).toBeTruthy(); @@ -2152,7 +2150,6 @@ describe('serve app', () => { projects: [ { id: 'project-no-publish', - name: 'Project No Publish', path: projectDir, results: { repo: `file://${remoteDir}`, @@ -2276,7 +2273,6 @@ describe('serve app', () => { projects: [ { id: 'agentv', - name: 'AgentV', path: projectDir, results: { repo: 'EntityProcess/agentv-examples-eval-results', @@ -2328,7 +2324,6 @@ describe('serve app', () => { projects: [ { id: 'project-sync-pull', - name: 'Project Sync Pull', path: projectDir, results: { repo: `file://${remoteDir}`, @@ -2405,7 +2400,6 @@ describe('serve app', () => { projects: [ { id: 'project-sync-push', - name: 'Project Sync Push', path: projectDir, results: { repo: `file://${remoteDir}`, @@ -2473,7 +2467,6 @@ describe('serve app', () => { projects: [ { id: 'project-sync-offline', - name: 'Project Sync Offline', path: projectDir, results: { repo: missingRemoteUrl, @@ -2531,7 +2524,6 @@ describe('serve app', () => { projects: [ { id: 'project-sync-conflict', - name: 'Project Sync Conflict', path: projectDir, results: { repo: `file://${remoteDir}`, @@ -2657,7 +2649,6 @@ describe('serve app', () => { projects: [ { id: 'project-confirm-merge', - name: 'Project Confirm Merge', path: projectDir, results: { repo: `file://${remoteDir}`, diff --git a/apps/dashboard/src/components/Breadcrumbs.tsx b/apps/dashboard/src/components/Breadcrumbs.tsx index 13e7f1c8e..f5421a3e6 100644 --- a/apps/dashboard/src/components/Breadcrumbs.tsx +++ b/apps/dashboard/src/components/Breadcrumbs.tsx @@ -7,7 +7,6 @@ import { Link, useMatches } from '@tanstack/react-router'; -import { useProjectList } from '~/lib/api'; import { categoryPath, evalPath, @@ -17,7 +16,6 @@ import { runPath, suitePath, } from '~/lib/navigation'; -import { type ProjectDisplayEntry, resolveProjectDisplayName } from '~/lib/project-display-name'; import { useSidebarContext } from '~/lib/sidebar-context'; interface BreadcrumbSegment { @@ -34,10 +32,7 @@ export function formatBreadcrumbRunLabel(runId: string | undefined): string { return timestamp?.[0] ?? candidate; } -function deriveSegments( - matches: ReturnType, - projects: readonly ProjectDisplayEntry[] = [], -): BreadcrumbSegment[] { +function deriveSegments(matches: ReturnType): BreadcrumbSegment[] { const segments: BreadcrumbSegment[] = []; // Skip the root match (index 0) @@ -49,7 +44,7 @@ function deriveSegments( if (routeId === '/' || routeId === '/_layout') continue; if (routeId.includes('/projects/$projectId') && params.projectId) { - const label = resolveProjectDisplayName(params.projectId, projects); + const label = params.projectId; const to = projectHomePath(params.projectId); if (!segments.some((s) => s.to === to)) { segments.push({ @@ -172,8 +167,7 @@ function deriveSegments( export function Breadcrumbs() { const matches = useMatches(); const { toggle } = useSidebarContext(); - const { data: projectData } = useProjectList(); - const segments = deriveSegments(matches, projectData?.projects); + const segments = deriveSegments(matches); const hasTrail = segments.length > 0; return ( diff --git a/apps/dashboard/src/components/ProjectCard.tsx b/apps/dashboard/src/components/ProjectCard.tsx index 05e5e102f..17921379c 100644 --- a/apps/dashboard/src/components/ProjectCard.tsx +++ b/apps/dashboard/src/components/ProjectCard.tsx @@ -111,7 +111,7 @@ export function ProjectCard({ project, canRemove = false, onRemove }: ProjectCar

- {project.name} + {project.id}

{project.path}

@@ -161,7 +161,7 @@ export function ProjectCard({ project, canRemove = false, onRemove }: ProjectCar aria-haspopup="menu" aria-expanded={menuOpen} aria-controls={menuOpen ? menuId : undefined} - aria-label={`Open ${project.name} project menu`} + aria-label={`Open ${project.id} project menu`} onClick={() => setMenuOpen((open) => !open)} className="flex h-8 w-8 items-center justify-center rounded-md text-lg leading-none text-gray-500 transition-colors hover:bg-gray-800 hover:text-gray-200 focus:outline-none focus:ring-1 focus:ring-cyan-500" > @@ -172,7 +172,7 @@ export function ProjectCard({ project, canRemove = false, onRemove }: ProjectCar ref={menuRef} id={menuId} role="menu" - aria-label={`${project.name} actions`} + aria-label={`${project.id} actions`} className="absolute right-0 top-10 w-44 overflow-hidden rounded-md border border-gray-800 bg-gray-950 py-1 shadow-xl" >