diff --git a/ui/src/pages/ProjectDetail.tsx b/ui/src/pages/ProjectDetail.tsx index 5c9b6f54..001e14cd 100644 --- a/ui/src/pages/ProjectDetail.tsx +++ b/ui/src/pages/ProjectDetail.tsx @@ -24,6 +24,13 @@ import { ExecutionWorkspaceCloseDialog } from "../components/ExecutionWorkspaceC import { IssuesList } from "../components/IssuesList"; import { PageSkeleton } from "../components/PageSkeleton"; import { PageTabBar } from "../components/PageTabBar"; +import { BuilderTabStrip, resolveBuilderTab } from "../components/projects/BuilderTabStrip"; +import { OverviewTab } from "../components/projects/tabs/OverviewTab"; +import { AgentsTab } from "../components/projects/tabs/AgentsTab"; +import { GatesTab } from "../components/projects/tabs/GatesTab"; +import { CostsTab } from "../components/projects/tabs/CostsTab"; +import { ActivityTab } from "../components/projects/tabs/ActivityTab"; +import { OrgTab } from "../components/projects/tabs/OrgTab"; import { buildProjectWorkspaceSummaries } from "../lib/project-workspaces-tab"; import { projectRouteRef, projectWorkspaceUrl } from "../lib/utils"; import { timeAgo } from "../lib/timeAgo"; @@ -847,6 +854,63 @@ export function ProjectDetail() { itemClassName="inline-flex" /> + {/* + Phase 11 Builder tab strip. Renders iff the current URL resolves + to one of the new Builder tabs (overview/issues/agents/gates/ + costs/activity/org). Legacy sub-routes (configuration/budget/ + workspaces/plugin) fall through to the existing PageTabBar + below for backwards compat — see plan §Preserving existing + behavior. + */} + {(() => { + const builderTab = resolveBuilderTab(location.pathname, canonicalProjectRef); + if (!builderTab) return null; + // Phase 11: no reliable per-project agent count source yet. Show + // the full (7-tab) strip by default; BuilderTabStrip hides ORG + // when hasMultipleAgents=false. Leaving this true preserves + // access to the Org placeholder tab until the data is wired. + const hasMultipleAgents = true; + return ( +