@@ -16,6 +16,17 @@ enum ClaudePermissionMode: String, CaseIterable {
1616 }
1717 }
1818
19+ var description : String {
20+ switch self {
21+ case . default: " Ask before each action "
22+ case . acceptEdits: " Auto-approve file edits, ask for other actions "
23+ case . plan: " Read-only mode, no file changes allowed "
24+ case . bypassPermissions: " Auto-approve everything (fastest, no interruptions) "
25+ case . dontAsk: " Auto-approve everything (alternative mode) "
26+ case . auto: " Let Claude decide when to ask "
27+ }
28+ }
29+
1930 var cliValue : String { rawValue }
2031}
2132
@@ -82,6 +93,7 @@ struct ClaudeConfig {
8293 var effort : ClaudeEffort ? = nil
8394 var systemPrompt : String = " "
8495 var verbose : Bool = false
96+ var remoteControl : Bool = false
8597}
8698
8799struct CodexConfig {
@@ -130,6 +142,8 @@ func parseClaudeLaunchArgs(_ args: [String]) -> ClaudeConfig {
130142 }
131143 case " --verbose " :
132144 config. verbose = true
145+ case " --remote-control " , " --rc " :
146+ config. remoteControl = true
133147 default :
134148 break
135149 }
@@ -159,6 +173,9 @@ func composeClaudeLaunchArgs(_ config: ClaudeConfig) -> [String] {
159173 if config. verbose {
160174 args. append ( " --verbose " )
161175 }
176+ if config. remoteControl {
177+ args. append ( " --remote-control " )
178+ }
162179 return args
163180}
164181
@@ -326,91 +343,143 @@ struct ClaudeAgentGroupBox: View {
326343 var body : some View {
327344 GroupBox {
328345 VStack ( alignment: . leading, spacing: 10 ) {
329- Toggle ( " Use Defaults " , isOn: $useDefaults)
330- . toggleStyle ( . switch)
331- . controlSize ( . small)
332- . onChange ( of: useDefaults) {
333- if useDefaults {
334- Task {
335- await state. updateLaunchArgs (
336- projectRoot: projectRoot, agentName: " claude " , launchArgs: nil )
346+ Toggle (
347+ " Customize Launch Settings " ,
348+ isOn: Binding (
349+ get: { !useDefaults } ,
350+ set: { useDefaults = !$0 }
351+ )
352+ )
353+ . toggleStyle ( . switch)
354+ . controlSize ( . small)
355+ . onChange ( of: useDefaults) {
356+ if useDefaults {
357+ Task {
358+ await state. updateLaunchArgs (
359+ projectRoot: projectRoot, agentName: " claude " , launchArgs: nil )
360+ }
361+ } else {
362+ commitChanges ( )
363+ }
364+ }
365+
366+ if useDefaults {
367+ Text ( " Using recommended settings: auto-approve everything, no interruptions " )
368+ . font ( . system( size: 11 ) )
369+ . foregroundStyle ( . tertiary)
370+ }
371+
372+ VStack ( alignment: . leading, spacing: 2 ) {
373+ Toggle ( " Remote Control " , isOn: $config. remoteControl)
374+ . toggleStyle ( . switch)
375+ . controlSize ( . small)
376+ . onChange ( of: config. remoteControl) {
377+ if config. remoteControl && useDefaults {
378+ useDefaults = false
337379 }
338- } else {
339380 commitChanges ( )
340381 }
341- }
382+ Text ( " Continue this session from your phone or browser via claude.ai/code " )
383+ . font ( . system( size: 11 ) )
384+ . foregroundStyle ( . tertiary)
385+ }
342386
343387 if useDefaults {
344388 resolvedArgsView ( payload. resolvedLaunchArgs)
345389 } else {
346- LabeledContent ( " Permission Mode " ) {
347- Picker ( " " , selection: $config. permissionMode) {
348- ForEach ( ClaudePermissionMode . allCases, id: \. self) { mode in
349- Text ( mode. displayName) . tag ( mode)
390+ VStack ( alignment: . leading, spacing: 2 ) {
391+ LabeledContent ( " Permission Mode " ) {
392+ Picker ( " " , selection: $config. permissionMode) {
393+ ForEach ( ClaudePermissionMode . allCases, id: \. self) { mode in
394+ Text ( mode. displayName) . tag ( mode)
395+ }
350396 }
397+ . labelsHidden ( )
398+ . frame ( width: 180 )
399+ . onChange ( of: config. permissionMode) { commitChanges ( ) }
351400 }
352- . labelsHidden ( )
353- . frame ( width : 180 )
354- . onChange ( of : config . permissionMode ) { commitChanges ( ) }
401+ Text ( config . permissionMode . description )
402+ . font ( . system ( size : 11 ) )
403+ . foregroundStyle ( . tertiary )
355404 }
356405
357- LabeledContent ( " Model " ) {
358- HStack ( spacing: 8 ) {
406+ VStack ( alignment: . leading, spacing: 2 ) {
407+ LabeledContent ( " Model " ) {
408+ HStack ( spacing: 8 ) {
409+ Picker (
410+ " " ,
411+ selection: Binding (
412+ get: { config. model ?? . sonnet } ,
413+ set: {
414+ config. model = $0; config. customModel = " "
415+ }
416+ )
417+ ) {
418+ ForEach ( ClaudeModel . allCases, id: \. self) { m in
419+ Text ( m. displayName) . tag ( m)
420+ }
421+ }
422+ . labelsHidden ( )
423+ . frame ( width: 100 )
424+ . onChange ( of: config. model) { commitChanges ( ) }
425+
426+ TextField ( " Custom " , text: $config. customModel)
427+ . textFieldStyle ( . roundedBorder)
428+ . frame ( width: 120 )
429+ . onSubmit {
430+ if !config. customModel. isEmpty { config. model = nil }
431+ commitChanges ( )
432+ }
433+ }
434+ }
435+ Text ( " Which AI model to use " )
436+ . font ( . system( size: 11 ) )
437+ . foregroundStyle ( . tertiary)
438+ }
439+
440+ VStack ( alignment: . leading, spacing: 2 ) {
441+ LabeledContent ( " Effort " ) {
359442 Picker (
360443 " " ,
361444 selection: Binding (
362- get: { config. model ?? . sonnet } ,
363- set: {
364- config. model = $0; config. customModel = " "
365- }
445+ get: { config. effort ?? . high } ,
446+ set: { config. effort = $0 }
366447 )
367448 ) {
368- ForEach ( ClaudeModel . allCases, id: \. self) { m in
369- Text ( m . displayName) . tag ( m )
449+ ForEach ( ClaudeEffort . allCases, id: \. self) { e in
450+ Text ( e . displayName) . tag ( e )
370451 }
371452 }
372- . labelsHidden ( )
373- . frame ( width: 100 )
374- . onChange ( of: config. model) { commitChanges ( ) }
375-
376- TextField ( " Custom " , text: $config. customModel)
377- . textFieldStyle ( . roundedBorder)
378- . frame ( width: 120 )
379- . onSubmit {
380- if !config. customModel. isEmpty { config. model = nil }
381- commitChanges ( )
382- }
453+ . pickerStyle ( . segmented)
454+ . frame ( width: 200 )
455+ . onChange ( of: config. effort) { commitChanges ( ) }
383456 }
457+ Text ( " How much compute the model uses per response " )
458+ . font ( . system( size: 11 ) )
459+ . foregroundStyle ( . tertiary)
384460 }
385461
386- LabeledContent ( " Effort " ) {
387- Picker (
388- " " ,
389- selection: Binding (
390- get: { config. effort ?? . high } ,
391- set: { config. effort = $0 }
392- )
393- ) {
394- ForEach ( ClaudeEffort . allCases, id: \. self) { e in
395- Text ( e. displayName) . tag ( e)
396- }
462+ VStack ( alignment: . leading, spacing: 2 ) {
463+ LabeledContent ( " System Prompt " ) {
464+ TextField ( " Optional " , text: $config. systemPrompt)
465+ . textFieldStyle ( . roundedBorder)
466+ . onSubmit { commitChanges ( ) }
397467 }
398- . pickerStyle ( . segmented )
399- . frame ( width : 200 )
400- . onChange ( of : config . effort ) { commitChanges ( ) }
468+ Text ( " Additional instructions appended to the agent's system prompt " )
469+ . font ( . system ( size : 11 ) )
470+ . foregroundStyle ( . tertiary )
401471 }
402472
403- LabeledContent ( " System Prompt " ) {
404- TextField ( " Optional " , text: $config. systemPrompt)
405- . textFieldStyle ( . roundedBorder)
406- . onSubmit { commitChanges ( ) }
473+ VStack ( alignment: . leading, spacing: 2 ) {
474+ Toggle ( " Verbose " , isOn: $config. verbose)
475+ . toggleStyle ( . switch)
476+ . controlSize ( . small)
477+ . onChange ( of: config. verbose) { commitChanges ( ) }
478+ Text ( " Show detailed logging output in the terminal " )
479+ . font ( . system( size: 11 ) )
480+ . foregroundStyle ( . tertiary)
407481 }
408482
409- Toggle ( " Verbose " , isOn: $config. verbose)
410- . toggleStyle ( . switch)
411- . controlSize ( . small)
412- . onChange ( of: config. verbose) { commitChanges ( ) }
413-
414483 resolvedArgsView ( composeClaudeLaunchArgs ( config) )
415484 }
416485 }
@@ -450,21 +519,30 @@ struct CodexAgentGroupBox: View {
450519 var body : some View {
451520 GroupBox {
452521 VStack ( alignment: . leading, spacing: 10 ) {
453- Toggle ( " Use Defaults " , isOn: $useDefaults)
454- . toggleStyle ( . switch)
455- . controlSize ( . small)
456- . onChange ( of: useDefaults) {
457- if useDefaults {
458- Task {
459- await state. updateLaunchArgs (
460- projectRoot: projectRoot, agentName: " codex " , launchArgs: nil )
461- }
462- } else {
463- commitChanges ( )
522+ Toggle (
523+ " Customize Launch Settings " ,
524+ isOn: Binding (
525+ get: { !useDefaults } ,
526+ set: { useDefaults = !$0 }
527+ )
528+ )
529+ . toggleStyle ( . switch)
530+ . controlSize ( . small)
531+ . onChange ( of: useDefaults) {
532+ if useDefaults {
533+ Task {
534+ await state. updateLaunchArgs (
535+ projectRoot: projectRoot, agentName: " codex " , launchArgs: nil )
464536 }
537+ } else {
538+ commitChanges ( )
465539 }
540+ }
466541
467542 if useDefaults {
543+ Text ( " Using recommended settings: full-auto mode with workspace sandbox " )
544+ . font ( . system( size: 11 ) )
545+ . foregroundStyle ( . tertiary)
468546 resolvedArgsView ( payload. resolvedLaunchArgs)
469547 } else {
470548 LabeledContent ( " Approval Mode " ) {
@@ -539,21 +617,30 @@ struct OpenCodeAgentGroupBox: View {
539617 var body : some View {
540618 GroupBox {
541619 VStack ( alignment: . leading, spacing: 10 ) {
542- Toggle ( " Use Defaults " , isOn: $useDefaults)
543- . toggleStyle ( . switch)
544- . controlSize ( . small)
545- . onChange ( of: useDefaults) {
546- if useDefaults {
547- Task {
548- await state. updateLaunchArgs (
549- projectRoot: projectRoot, agentName: " opencode " , launchArgs: nil )
550- }
551- } else {
552- commitChanges ( )
620+ Toggle (
621+ " Customize Launch Settings " ,
622+ isOn: Binding (
623+ get: { !useDefaults } ,
624+ set: { useDefaults = !$0 }
625+ )
626+ )
627+ . toggleStyle ( . switch)
628+ . controlSize ( . small)
629+ . onChange ( of: useDefaults) {
630+ if useDefaults {
631+ Task {
632+ await state. updateLaunchArgs (
633+ projectRoot: projectRoot, agentName: " opencode " , launchArgs: nil )
553634 }
635+ } else {
636+ commitChanges ( )
554637 }
638+ }
555639
556640 if useDefaults {
641+ Text ( " Using recommended settings: default configuration " )
642+ . font ( . system( size: 11 ) )
643+ . foregroundStyle ( . tertiary)
557644 resolvedArgsView ( payload. resolvedLaunchArgs)
558645 } else {
559646 LabeledContent ( " Model " ) {
0 commit comments