@@ -18,6 +18,7 @@ import { getTask, runTaskInCloud } from "@/features/tasks/api";
1818import { FloatingTaskHeader } from "@/features/tasks/components/FloatingTaskHeader" ;
1919import { PrDiffStatsBadge } from "@/features/tasks/components/PrDiffStatsBadge" ;
2020import { PrStatusBadge } from "@/features/tasks/components/PrStatusBadge" ;
21+ import { StopRunButton } from "@/features/tasks/components/StopRunButton" ;
2122import { TaskSessionView } from "@/features/tasks/components/TaskSessionView" ;
2223import { buildCloudPromptBlocks } from "@/features/tasks/composer/attachments/buildCloudPrompt" ;
2324import { serializeCloudPrompt } from "@/features/tasks/composer/attachments/cloudPrompt" ;
@@ -49,7 +50,14 @@ import {
4950import { useTaskSessionStore } from "@/features/tasks/stores/taskSessionStore" ;
5051import { useTaskStore } from "@/features/tasks/stores/taskStore" ;
5152import type { Task } from "@/features/tasks/types" ;
52- import { getSessionActivityPhase } from "@/features/tasks/utils/sessionActivity" ;
53+ import {
54+ confirmStopRun ,
55+ isTaskRunning ,
56+ } from "@/features/tasks/utils/archiveGuard" ;
57+ import {
58+ countUserMessages ,
59+ getSessionActivityPhase ,
60+ } from "@/features/tasks/utils/sessionActivity" ;
5361import { useScreenInsets } from "@/hooks/useScreenInsets" ;
5462import {
5563 ANALYTICS_EVENTS ,
@@ -101,6 +109,7 @@ export default function TaskDetailScreen() {
101109 getSessionForTask,
102110 setFocusedTaskId,
103111 steerQueuedMessage,
112+ stopRun,
104113 } = useTaskSessionStore ( ) ;
105114
106115 useEffect ( ( ) => {
@@ -471,6 +480,37 @@ export default function TaskDetailScreen() {
471480 cancelPrompt ( taskId ) . catch ( ( ) => { } ) ;
472481 } , [ taskId , cancelPrompt ] ) ;
473482
483+ const handleStopRun = useCallback ( ( ) => {
484+ if ( ! taskId ) return ;
485+ confirmStopRun ( ( ) => {
486+ const promptsSent = countUserMessages ( getSessionForTask ( taskId ) ?. events ) ;
487+ stopRun ( taskId )
488+ . then ( ( ok ) => {
489+ if ( ok ) {
490+ analytics . track ( ANALYTICS_EVENTS . TASK_RUN_STOPPED , {
491+ task_id : taskId ,
492+ execution_type : "cloud" ,
493+ prompts_sent : promptsSent ,
494+ } ) ;
495+ } else {
496+ Alert . alert (
497+ "Couldn't stop" ,
498+ "The run could not be stopped. Please try again." ,
499+ ) ;
500+ }
501+ } )
502+ . catch ( ( ) => { } ) ;
503+ } ) ;
504+ } , [ taskId , stopRun , analytics , getSessionForTask ] ) ;
505+
506+ const canStopRun =
507+ ! ! task &&
508+ ! ! session &&
509+ ! session . terminalStatus &&
510+ ! session . stopRequested &&
511+ task . latest_run ?. environment !== "local" &&
512+ isTaskRunning ( task ) ;
513+
474514 const handleRetry = useCallback ( async ( ) => {
475515 if ( ! taskId || ! task ) return ;
476516 try {
@@ -587,7 +627,9 @@ export default function TaskDetailScreen() {
587627 title = { showLoading ? "Loading..." : task ?. title || "Task" }
588628 subtitle = { task ?. repository ?? undefined }
589629 rightSlot = {
590- prUrl ? (
630+ canStopRun ? (
631+ < StopRunButton onPress = { handleStopRun } />
632+ ) : prUrl ? (
591633 < >
592634 < PrDiffStatsBadge prUrl = { prUrl } />
593635 < PrStatusBadge prUrl = { prUrl } />
0 commit comments