@@ -14,6 +14,7 @@ import { GearIcon, GlobeIcon } from "@radix-ui/react-icons";
1414import {
1515 Box ,
1616 Button ,
17+ Callout ,
1718 Code ,
1819 DataList ,
1920 Flex ,
@@ -24,7 +25,9 @@ import {
2425 Tooltip ,
2526} from "@radix-ui/themes" ;
2627import type { Task } from "@shared/types" ;
28+ import { cloneStore } from "@stores/cloneStore" ;
2729import { useLayoutStore } from "@stores/layoutStore" ;
30+ import { repositoryWorkspaceStore } from "@stores/repositoryWorkspaceStore" ;
2831import { useTabStore } from "@stores/tabStore" ;
2932import { expandTildePath } from "@utils/path" ;
3033import { format , formatDistanceToNow } from "date-fns" ;
@@ -63,12 +66,13 @@ export function TaskDetail({ task: initialTask }: TaskDetailProps) {
6366
6467 const task = tasks . find ( ( t ) => t . id === initialTask . id ) || initialTask ;
6568
66- const taskState = getTaskState ( task . id ) ;
69+ const taskState = getTaskState ( task . id , task ) ;
6770
6871 const {
6972 isRunning,
7073 logs,
7174 repoPath,
75+ repoExists,
7276 runMode,
7377 progress,
7478 planModePhase,
@@ -96,6 +100,15 @@ export function TaskDetail({ task: initialTask }: TaskDetailProps) {
96100 return `${ expandedWorkspace } /${ task . repository_config . repository } ` ;
97101 } , [ task . repository_config , defaultWorkspace ] ) ;
98102
103+ // Check if repository is being cloned using existing cloneStore method
104+ const isCloningRepo = cloneStore ( ( state ) =>
105+ task . repository_config
106+ ? state . isCloning (
107+ `${ task . repository_config . organization } /${ task . repository_config . repository } ` ,
108+ )
109+ : false ,
110+ ) ;
111+
99112 useEffect ( ( ) => {
100113 resetForm ( {
101114 title : task . title ,
@@ -136,6 +149,21 @@ export function TaskDetail({ task: initialTask }: TaskDetailProps) {
136149 clearTaskLogs ( task . id ) ;
137150 } ;
138151
152+ const handleCloneRepository = async ( ) => {
153+ if ( ! task . repository_config ) return ;
154+ await repositoryWorkspaceStore
155+ . getState ( )
156+ . selectRepository ( task . repository_config ) ;
157+ } ;
158+
159+ const getRunButtonLabel = ( ) => {
160+ if ( isRunning ) return "Running..." ;
161+ if ( isCloningRepo ) return "Cloning..." ;
162+ if ( runMode === "cloud" ) return "Run (Cloud)" ;
163+ if ( repoExists === false ) return "Clone repository" ;
164+ return "Run (Local)" ;
165+ } ;
166+
139167 const handleAnswersComplete = async (
140168 answers : Array < {
141169 questionId : string ;
@@ -361,6 +389,17 @@ export function TaskDetail({ task: initialTask }: TaskDetailProps) {
361389 </ Flex >
362390
363391 < Flex direction = "column" gap = "3" mt = "4" >
392+ { /* Repository status */ }
393+ { repoExists === false &&
394+ task . repository_config &&
395+ runMode === "local" && (
396+ < Callout . Root color = "gray" size = "2" >
397+ < Callout . Text size = "1" >
398+ Repository not in workspace. Clone to run agent locally.
399+ </ Callout . Text >
400+ </ Callout . Root >
401+ ) }
402+
364403 { /* Task Artifacts */ }
365404 { repoPath && (
366405 < TaskArtifacts
@@ -374,23 +413,23 @@ export function TaskDetail({ task: initialTask }: TaskDetailProps) {
374413 < Flex gap = "2" >
375414 < Button
376415 variant = "classic"
377- onClick = { handleRunTask }
378- disabled = { isRunning }
416+ onClick = {
417+ runMode === "local" && repoExists === false
418+ ? handleCloneRepository
419+ : handleRunTask
420+ }
421+ disabled = { isRunning || isCloningRepo }
379422 size = "2"
380423 style = { { flex : 1 } }
381424 >
382- { isRunning
383- ? "Running..."
384- : runMode === "cloud"
385- ? "Run (Cloud)"
386- : "Run (Local)" }
425+ { getRunButtonLabel ( ) }
387426 </ Button >
388427 < Tooltip content = "Toggle between Local or Cloud Agent" >
389428 < IconButton
390429 size = "2"
391430 variant = "classic"
392431 color = { runMode === "cloud" ? "blue" : "gray" }
393- disabled = { isRunning }
432+ disabled = { isRunning || isCloningRepo }
394433 onClick = { ( ) =>
395434 handleRunModeChange (
396435 runMode === "local" ? "cloud" : "local" ,
0 commit comments