11import type { ExecutionMode } from "@features/sessions/stores/sessionStore" ;
22import { useCwd } from "@features/sidebar/hooks/useCwd" ;
33import { LockOpen , Circle , Pause , Pencil , ShieldCheck } from "@phosphor-icons/react" ;
4- import { Flex , Text } from "@radix-ui/themes" ;
54import { trpcVanilla } from "@renderer/trpc" ;
65import { useQuery } from "@tanstack/react-query" ;
6+ import { Flex , Select , Text } from "@radix-ui/themes" ;
7+ import { EXECUTION_MODES } from "@shared/constants" ;
78
89interface ModeIndicatorInputProps {
910 mode : ExecutionMode ;
1011 taskId ?: string ;
12+ onModeChange : ( mode : ExecutionMode ) => void ;
1113}
1214
1315const modeConfig : Record <
@@ -20,27 +22,31 @@ const modeConfig: Record<
2022> = {
2123 plan : {
2224 label : "plan mode on" ,
23- icon : < Pause size = { 12 } weight = "bold" /> ,
25+ icon : < Pause size = { 12 } weight = "bold" color = "var(--amber-11)" /> ,
2426 colorVar : "var(--amber-11)" ,
2527 } ,
2628 default : {
2729 label : "default mode" ,
28- icon : < Pencil size = { 12 } /> ,
30+ icon : < Pencil size = { 12 } color = "var(--gray-11)" /> ,
2931 colorVar : "var(--gray-11)" ,
3032 } ,
3133 acceptEdits : {
3234 label : "auto-accept edits" ,
33- icon : < ShieldCheck size = { 12 } weight = "fill" /> ,
35+ icon : < ShieldCheck size = { 12 } weight = "fill" color = "var(--green-11)" /> ,
3436 colorVar : "var(--green-11)" ,
3537 } ,
3638 bypassPermissions : {
3739 label : "bypass permissions" ,
38- icon : < LockOpen size = { 12 } weight = "bold" /> ,
40+ icon : < LockOpen size = { 12 } weight = "bold" color = "var(--red-11)" /> ,
3941 colorVar : "var(--red-11)" ,
4042 } ,
4143} ;
4244
43- export function ModeIndicatorInput ( { mode, taskId } : ModeIndicatorInputProps ) {
45+ export function ModeIndicatorInput ( {
46+ mode,
47+ onModeChange,
48+ taskId,
49+ } : ModeIndicatorInputProps ) {
4450 const config = modeConfig [ mode ] ;
4551 const repoPath = useCwd ( taskId ?? "" ) ;
4652
@@ -59,30 +65,38 @@ export function ModeIndicatorInput({ mode, taskId }: ModeIndicatorInputProps) {
5965 const hasDiffStats = diffStats && diffStats . filesChanged > 0 ;
6066
6167 return (
62- < Flex align = "center" justify = "between" py = "1" >
63- < Flex align = "center" gap = "1" >
64- < Text
65- size = "1"
66- style = { {
67- color : config . colorVar ,
68- fontFamily : "monospace" ,
69- display : "flex" ,
70- alignItems : "center" ,
71- gap : "4px" ,
72- } }
73- >
68+ < Select . Root
69+ value = { mode }
70+ onValueChange = { onModeChange }
71+ disabled = { disabled }
72+ size = "1"
73+ >
74+ < Select . Trigger
75+ className = "w-fit"
76+ onClick = { ( e ) => {
77+ e . stopPropagation ( ) ;
78+ } }
79+ >
80+ < Flex align = "center" gap = "1" >
7481 { config . icon }
75- { config . label }
76- </ Text >
77- < Text
78- size = "1"
79- style = { {
80- color : "var(--gray-9)" ,
81- fontFamily : "monospace" ,
82- } }
83- >
84- (shift+tab to cycle)
85- </ Text >
82+ < Text
83+ size = "1"
84+ style = { {
85+ color : config . colorVar ,
86+ fontFamily : "monospace" ,
87+ } }
88+ >
89+ { config . label }
90+ </ Text >
91+ < Text
92+ size = "1"
93+ style = { {
94+ color : "var(--gray-9)" ,
95+ fontFamily : "monospace" ,
96+ } }
97+ >
98+ (shift+tab to cycle)
99+ </ Text >
86100 { hasDiffStats && (
87101 < Text
88102 size = "1"
@@ -107,7 +121,55 @@ export function ModeIndicatorInput({ mode, taskId }: ModeIndicatorInputProps) {
107121 </ span >
108122 </ Text >
109123 ) }
110- </ Flex >
111- </ Flex >
124+ </ Flex >
125+ </ Select . Trigger >
126+ < Select . Content >
127+ { EXECUTION_MODES . map ( ( modeOption ) => {
128+ const optionConfig = modeConfig [ modeOption ] ;
129+ const hoverBgClass =
130+ modeOption === "plan"
131+ ? "hover:!bg-[var(--amber-11)]"
132+ : modeOption === "default"
133+ ? "hover:!bg-[var(--gray-11)]"
134+ : modeOption === "acceptEdits"
135+ ? "hover:!bg-[var(--green-11)]"
136+ : "hover:!bg-[var(--red-11)]" ;
137+ return (
138+ < Select . Item
139+ key = { modeOption }
140+ value = { modeOption }
141+ className = { `group transition-colors ${ hoverBgClass } ` }
142+ >
143+ < Flex
144+ align = "center"
145+ gap = "1"
146+ className = "group-hover:!text-[black] [&_svg]:group-hover:!text-[black] [&_svg]:group-hover:!fill-[black] [&_svg_path]:group-hover:!fill-[black] [&_svg_path]:group-hover:!stroke-[black]"
147+ style = { {
148+ color : optionConfig . colorVar ,
149+ fontFamily : "monospace" ,
150+ } }
151+ >
152+ < span className = "group-hover:[&_svg]:!text-[black] group-hover:[&_svg]:!fill-[black] group-hover:[&_svg_path]:!fill-[black] group-hover:[&_svg_path]:!stroke-[black]" >
153+ { optionConfig . icon }
154+ </ span >
155+ < Text size = "1" className = "group-hover:!text-[black]" >
156+ { optionConfig . label }
157+ </ Text >
158+ </ Flex >
159+ </ Select . Item >
160+ ) ;
161+ } ) }
162+ </ Select . Content >
163+ < style > { `
164+ .group:hover svg {
165+ color: black !important;
166+ fill: black !important;
167+ }
168+ .group:hover svg path {
169+ fill: black !important;
170+ stroke: black !important;
171+ }
172+ ` } </ style >
173+ </ Select . Root >
112174 ) ;
113175}
0 commit comments