Skip to content

Commit b433eec

Browse files
TUI /new fixes (#1207)
Co-authored-by: jayhack <jayhack.0@gmail.com>
1 parent 6d7fea0 commit b433eec

File tree

1 file changed

+98
-28
lines changed

1 file changed

+98
-28
lines changed

src/codegen/cli/tui/app.py

Lines changed: 98 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,9 @@ def _display_agent_list(self):
206206

207207
def _display_new_tab(self):
208208
"""Display the new agent creation interface."""
209-
print("Create a new agent run:")
209+
print("Create new background agent (Claude Code):")
210210
print()
211211

212-
# Input prompt label
213-
print("Prompt:")
214-
215212
# Get terminal width, default to 80 if can't determine
216213
try:
217214
import os
@@ -246,11 +243,6 @@ def _display_new_tab(self):
246243
print(border_style + "└" + "─" * (box_width - 2) + "┘" + reset)
247244
print()
248245

249-
if self.input_mode:
250-
print("\033[90mType your prompt • [Enter] create agent • [Esc] cancel\033[0m")
251-
else:
252-
print("\033[90m[Enter] start typing • [Tab] switch tabs • [Q] quit\033[0m")
253-
254246
def _create_background_agent(self, prompt: str):
255247
"""Create a background agent run."""
256248
if not self.token or not self.org_id:
@@ -291,15 +283,58 @@ def _create_background_agent(self, prompt: str):
291283
self.cursor_position = 0
292284
self.input_mode = False
293285

294-
# Optionally refresh the recents tab if we're going back to it
295-
if hasattr(self, "_load_agent_runs"):
296-
print("\n🔄 Refreshing recents...")
297-
self._load_agent_runs()
286+
# Show post-creation menu
287+
self._show_post_creation_menu(web_url)
298288

299289
except Exception as e:
300290
print(f"\n❌ Failed to create agent run: {e}")
291+
input("\nPress Enter to continue...")
301292

302-
input("\nPress Enter to continue...")
293+
def _show_post_creation_menu(self, web_url: str):
294+
"""Show menu after successful agent creation."""
295+
print("\nWhat would you like to do next?")
296+
print()
297+
298+
options = ["open in web preview", "go to recents"]
299+
selected = 0
300+
301+
while True:
302+
# Clear previous menu display and move cursor up
303+
for i in range(len(options) + 2):
304+
print("\033[K") # Clear line
305+
print(f"\033[{len(options) + 2}A", end="") # Move cursor up
306+
307+
for i, option in enumerate(options):
308+
if i == selected:
309+
print(f" \033[34m→ {option}\033[0m")
310+
else:
311+
print(f" \033[90m {option}\033[0m")
312+
313+
print("\n\033[90m[Enter] select • [↑↓] navigate • [Esc] back to new tab\033[0m")
314+
315+
# Get input
316+
key = self._get_char()
317+
318+
if key == "\x1b[A" or key.lower() == "w": # Up arrow or W
319+
selected = max(0, selected - 1)
320+
elif key == "\x1b[B" or key.lower() == "s": # Down arrow or S
321+
selected = min(len(options) - 1, selected + 1)
322+
elif key == "\r" or key == "\n": # Enter - select option
323+
if selected == 0: # open in web preview
324+
try:
325+
import webbrowser
326+
327+
webbrowser.open(web_url)
328+
except Exception as e:
329+
print(f"\n❌ Failed to open browser: {e}")
330+
input("Press Enter to continue...")
331+
elif selected == 1: # go to recents
332+
self.current_tab = 0 # Switch to recents tab
333+
self.input_mode = False
334+
self._load_agent_runs() # Refresh the data
335+
break
336+
elif key == "\x1b": # Esc - back to new tab
337+
break
303338

304339
def _display_web_tab(self):
305340
"""Display the web interface access tab."""
@@ -367,14 +402,14 @@ def _display_inline_action_menu(self, agent_run: dict):
367402
options.append(f"open PR ({pr_display})")
368403

369404
for i, option in enumerate(options):
370-
if i == 0:
371-
# Always highlight first (top) option in blue
405+
if i == self.action_menu_selection:
406+
# Highlight selected option in blue
372407
print(f" \033[34m→ {option}\033[0m")
373408
else:
374409
# All other options in gray
375410
print(f" \033[90m {option}\033[0m")
376411

377-
print("\033[90m [Enter] select, [C] close\033[0m")
412+
print("\033[90m [Enter] select • [↑↓] navigate • [C] close\033[0m")
378413

379414
def _get_char(self):
380415
"""Get a single character from stdin, handling arrow keys."""
@@ -406,18 +441,27 @@ def _get_char(self):
406441

407442
def _handle_keypress(self, key: str):
408443
"""Handle key presses for navigation."""
409-
# Global quit
410-
if key.lower() == "q" or key == "\x03": # q or Ctrl+C
444+
# Global quit (but not when typing in new tab)
445+
if key == "\x03": # Ctrl+C
446+
self.running = False
447+
return
448+
elif key.lower() == "q" and not (self.input_mode and self.current_tab == 1): # q only if not typing in new tab
411449
self.running = False
412450
return
413451

414-
# Tab switching (unless in input mode)
415-
if not self.input_mode and key == "\t": # Tab key
452+
# Tab switching (works even in input mode)
453+
if key == "\t": # Tab key
416454
self.current_tab = (self.current_tab + 1) % len(self.tabs)
417455
# Reset state when switching tabs
418456
self.show_action_menu = False
419457
self.action_menu_selection = 0
420458
self.selected_index = 0
459+
# Auto-focus prompt when switching to new tab
460+
if self.current_tab == 1: # new tab
461+
self.input_mode = True
462+
self.cursor_position = len(self.prompt_input)
463+
else:
464+
self.input_mode = False
421465
return
422466

423467
# Handle based on current context
@@ -434,7 +478,7 @@ def _handle_keypress(self, key: str):
434478

435479
def _handle_input_mode_keypress(self, key: str):
436480
"""Handle keypresses when in text input mode."""
437-
if key.lower() == "c": # 'C' key - exit input mode
481+
if key == "\x1b": # Esc key - exit input mode
438482
self.input_mode = False
439483
elif key == "\r" or key == "\n": # Enter - create agent run
440484
if self.prompt_input.strip(): # Only create if there's actual content
@@ -461,6 +505,30 @@ def _handle_action_menu_keypress(self, key: str):
461505
elif key.lower() == "c" or key == "\x1b[D": # 'C' key or Left arrow to close
462506
self.show_action_menu = False # Close menu
463507
self.action_menu_selection = 0 # Reset selection
508+
elif key == "\x1b[A" or key.lower() == "w": # Up arrow or W
509+
# Get available options count
510+
if 0 <= self.selected_index < len(self.agent_runs):
511+
agent_run = self.agent_runs[self.selected_index]
512+
github_prs = agent_run.get("github_pull_requests", [])
513+
options_count = 1 # Always have "open in web"
514+
if github_prs:
515+
options_count += 1 # "pull locally"
516+
if github_prs and github_prs[0].get("url"):
517+
options_count += 1 # "open PR"
518+
519+
self.action_menu_selection = max(0, self.action_menu_selection - 1)
520+
elif key == "\x1b[B" or key.lower() == "s": # Down arrow or S
521+
# Get available options count
522+
if 0 <= self.selected_index < len(self.agent_runs):
523+
agent_run = self.agent_runs[self.selected_index]
524+
github_prs = agent_run.get("github_pull_requests", [])
525+
options_count = 1 # Always have "open in web"
526+
if github_prs:
527+
options_count += 1 # "pull locally"
528+
if github_prs and github_prs[0].get("url"):
529+
options_count += 1 # "open PR"
530+
531+
self.action_menu_selection = min(options_count - 1, self.action_menu_selection + 1)
464532

465533
def _handle_recents_keypress(self, key: str):
466534
"""Handle keypresses in the recents tab."""
@@ -527,9 +595,9 @@ def _execute_inline_action(self):
527595
if github_prs and github_prs[0].get("url"):
528596
options.append("open PR")
529597

530-
# Always execute the first (top) option
531-
if len(options) > 0:
532-
selected_option = options[0]
598+
# Execute the currently selected option
599+
if len(options) > self.action_menu_selection:
600+
selected_option = options[self.action_menu_selection]
533601

534602
if selected_option == "pull locally":
535603
self._pull_agent_branch(agent_id)
@@ -572,10 +640,12 @@ def _clear_and_redraw(self):
572640
self._display_content()
573641

574642
# Show appropriate instructions based on context
575-
if self.input_mode:
576-
print("\n\033[90mType your prompt • [Enter] create • [C] cancel • [Q] quit\033[0m")
643+
if self.input_mode and self.current_tab == 1: # new tab input mode
644+
print("\n\033[90mType your prompt • [Enter] create • [Esc] cancel • [Tab] switch tabs • [Ctrl+C] quit\033[0m")
645+
elif self.input_mode: # other input modes
646+
print("\n\033[90mType your prompt • [Enter] create • [Esc] cancel • [Ctrl+C] quit\033[0m")
577647
elif self.show_action_menu:
578-
print("\n\033[90m[Enter] select • [C] close • [Q] quit\033[0m")
648+
print("\n\033[90m[Enter] select • [↑↓] navigate • [C] close • [Q] quit\033[0m")
579649
elif self.current_tab == 0: # recents
580650
print("\n\033[90m[Tab] switch tabs • (↑↓) navigate • (←→) open/close • [Enter] actions • [R] refresh • [Q] quit\033[0m")
581651
elif self.current_tab == 1: # new

0 commit comments

Comments
 (0)