diff --git a/apps/code/src/renderer/features/code-review/hooks/useEffectiveDiffSource.ts b/apps/code/src/renderer/features/code-review/hooks/useEffectiveDiffSource.ts
index 37a21a86f..70b0ea60a 100644
--- a/apps/code/src/renderer/features/code-review/hooks/useEffectiveDiffSource.ts
+++ b/apps/code/src/renderer/features/code-review/hooks/useEffectiveDiffSource.ts
@@ -72,7 +72,10 @@ export function useEffectiveDiffSource(taskId: string): EffectiveDiffSource {
const hasLocalChanges = diffStats.filesChanged > 0;
const branchSourceAvailable = !!linkedBranch && aheadOfDefault > 0;
- const prUrl = useLinkedBranchPrUrl(taskId);
+ const prUrl = useLinkedBranchPrUrl({
+ linkedBranch,
+ folderPath: workspace?.folderPath ?? null,
+ });
const prSourceAvailable = !!prUrl;
const repoSlug = repoInfo
diff --git a/apps/code/src/renderer/features/command-center/components/CommandCenterPRButton.tsx b/apps/code/src/renderer/features/command-center/components/CommandCenterPRButton.tsx
new file mode 100644
index 000000000..53039e756
--- /dev/null
+++ b/apps/code/src/renderer/features/command-center/components/CommandCenterPRButton.tsx
@@ -0,0 +1,38 @@
+import { PRBadgeLink } from "@features/git-interaction/components/PRBadgeLink";
+import { usePrDetails } from "@features/git-interaction/hooks/usePrDetails";
+import { useTaskPrUrl } from "@features/git-interaction/hooks/useTaskPrUrl";
+import type { WorkspaceMode } from "@main/services/workspace/schemas";
+
+interface CommandCenterPRButtonProps {
+ taskId: string;
+ workspaceMode: WorkspaceMode | null;
+}
+
+/**
+ * PR badge for a task cell in the command center. Same resolution rules as
+ * `TaskActionsMenu` via `useTaskPrUrl`, gated by `usePrDetails` returning a
+ * real PR state.
+ */
+export function CommandCenterPRButton({
+ taskId,
+ workspaceMode,
+}: CommandCenterPRButtonProps) {
+ const isCloud = workspaceMode === "cloud";
+ const prUrl = useTaskPrUrl(taskId, isCloud);
+
+ const {
+ meta: { state, merged, draft },
+ } = usePrDetails(prUrl);
+
+ if (!prUrl || state === null) return null;
+
+ return (
+
+ );
+}
diff --git a/apps/code/src/renderer/features/command-center/components/CommandCenterPanel.tsx b/apps/code/src/renderer/features/command-center/components/CommandCenterPanel.tsx
index 8f9a612ba..6a5fa61aa 100644
--- a/apps/code/src/renderer/features/command-center/components/CommandCenterPanel.tsx
+++ b/apps/code/src/renderer/features/command-center/components/CommandCenterPanel.tsx
@@ -1,10 +1,14 @@
+import { useCloudPrUrl } from "@features/git-interaction/hooks/useCloudPrUrl";
import { useDraftStore } from "@features/message-editor/stores/draftStore";
+import { TaskIcon } from "@features/sidebar/components/items/TaskIcon";
+import { useTaskPrStatus } from "@features/sidebar/hooks/useTaskPrStatus";
import { TaskInput } from "@features/task-detail/components/TaskInput";
import type { WorkspaceMode } from "@main/services/workspace/schemas";
import {
ArrowsOut,
Cloud,
Desktop,
+ Folder,
GitFork,
Plus,
X,
@@ -13,13 +17,16 @@ import { Flex, Text } from "@radix-ui/themes";
import type { Task } from "@shared/types";
import { useNavigationStore } from "@stores/navigationStore";
import { useCallback, useEffect, useRef, useState } from "react";
-import type { CommandCenterCellData } from "../hooks/useCommandCenterData";
+import type {
+ CellStatus,
+ CommandCenterCellData,
+} from "../hooks/useCommandCenterData";
import {
getCellSessionId,
useCommandCenterStore,
} from "../stores/commandCenterStore";
+import { CommandCenterPRButton } from "./CommandCenterPRButton";
import { CommandCenterSessionView } from "./CommandCenterSessionView";
-import { StatusBadge } from "./StatusBadge";
import { TaskSelector } from "./TaskSelector";
interface CommandCenterPanelProps {
@@ -36,12 +43,57 @@ const environmentConfig: Record<
cloud: { label: "Cloud", icon: Cloud },
};
+const STATUS_LABEL: Record = {
+ running: "Running",
+ waiting: "Waiting",
+ idle: "Idle",
+ completed: "Completed",
+ error: null,
+};
+
+function CellStatusBadge({
+ cell,
+}: {
+ cell: CommandCenterCellData & { task: Task };
+}) {
+ const { task, session, workspaceMode, status } = cell;
+ const isCloud = workspaceMode === "cloud";
+ const cloudPrUrl = useCloudPrUrl(task.id);
+ const { prState, hasDiff } = useTaskPrStatus({
+ id: task.id,
+ cloudPrUrl,
+ taskRunEnvironment: task.latest_run?.environment,
+ });
+
+ const label = STATUS_LABEL[status];
+ if (label === null) return null;
+
+ const taskRunStatus = isCloud
+ ? (session?.cloudStatus ?? task.latest_run?.status ?? undefined)
+ : undefined;
+
+ return (
+
+ 0}
+ taskRunStatus={taskRunStatus}
+ prState={prState}
+ hasDiff={hasDiff}
+ size={10}
+ />
+ {label}
+
+ );
+}
+
function EnvironmentBadge({ mode }: { mode: WorkspaceMode | null }) {
if (!mode) return null;
const config = environmentConfig[mode];
const Icon = config.icon;
return (
-
+
{config.label}
@@ -170,13 +222,18 @@ function PopulatedCell({
{cell.task.title}
-
+
{cell.repoName && (
-
+
+
{cell.repoName}
)}
+