feat: Add --new flag to UI with prefill options for title, template, participants, context

Opens new discussion dialog on launch with optional pre-filled values.
Enables integration with development-hub for launching discussions from todos.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
rob 2026-01-07 17:26:37 -04:00
parent 8d8958ff79
commit d71b837c16
2 changed files with 79 additions and 11 deletions

View File

@ -372,6 +372,15 @@ def cmd_ui(args) -> int:
else:
directory = path
# Parse prefill options
show_new = getattr(args, 'new', False)
prefill_title = getattr(args, 'title', None)
prefill_template = getattr(args, 'template', None)
prefill_context = getattr(args, 'context', None)
prefill_participants = None
if getattr(args, 'participants', None):
prefill_participants = [p.strip().lstrip('@') for p in args.participants.split(',')]
if args.tui:
# Launch TUI (urwid-based)
try:
@ -380,6 +389,7 @@ def cmd_ui(args) -> int:
print("Error: TUI requires urwid. Install with: pip install urwid")
print(f"Details: {e}")
return 1
# TUI doesn't support --new yet, just launch normally
tui_main(directory, open_file=open_file)
else:
# Launch GUI (Dear PyGui-based)
@ -395,7 +405,15 @@ def cmd_ui(args) -> int:
print(f"TUI also unavailable: {e2}")
return 1
return 0
gui_main(directory, open_file=open_file)
gui_main(
directory,
open_file=open_file,
show_new_dialog=show_new,
prefill_title=prefill_title,
prefill_template=prefill_template,
prefill_participants=prefill_participants,
prefill_context=prefill_context,
)
return 0
@ -461,6 +479,11 @@ def main(argv: list[str] = None) -> int:
p_ui = subparsers.add_parser("ui", help="Launch interactive UI")
p_ui.add_argument("path", nargs="?", help="Discussion file (.md) or directory to browse")
p_ui.add_argument("--tui", action="store_true", help="Use terminal UI instead of graphical UI")
p_ui.add_argument("--new", "-n", action="store_true", help="Open new discussion dialog on launch")
p_ui.add_argument("--title", help="Pre-fill title in new discussion dialog (requires --new)")
p_ui.add_argument("--template", help="Pre-select template in new discussion dialog (requires --new)")
p_ui.add_argument("--participants", help="Pre-select participants, comma-separated (requires --new)")
p_ui.add_argument("--context", help="Pre-fill context/description in new discussion dialog (requires --new)")
p_ui.set_defaults(func=cmd_ui)
args = parser.parse_args(argv)

View File

@ -2454,8 +2454,16 @@ class DiscussionGUI:
("pragmatist", "AI-Pragmatist")
]
def _show_new_discussion_dialog(self):
"""Show dialog for creating a new discussion."""
def _show_new_discussion_dialog(self, prefill_title: str = None, prefill_template: str = None,
prefill_participants: list[str] = None, prefill_context: str = None):
"""Show dialog for creating a new discussion.
Args:
prefill_title: Pre-fill title field
prefill_template: Pre-select template
prefill_participants: Pre-select participants (list of aliases)
prefill_context: Pre-fill context/description field
"""
window_tag = "new_discussion_dialog"
if dpg.does_item_exist(window_tag):
dpg.delete_item(window_tag)
@ -2463,9 +2471,10 @@ class DiscussionGUI:
templates = self._get_templates()
participants = self._get_participants()
# State for the dialog
# State for the dialog - use prefill if provided, otherwise defaults
default_participants = prefill_participants if prefill_participants else ["architect", "security", "pragmatist"]
dialog_state = {
'selected_participants': ["architect", "security", "pragmatist"],
'selected_participants': list(default_participants),
}
def toggle_participant(sender, app_data, user_data):
@ -2545,7 +2554,8 @@ class DiscussionGUI:
width=550, height=550, pos=[400, 150], no_collapse=True):
dpg.add_text("Title:", color=(150, 200, 255))
dpg.add_input_text(tag="new_disc_title", width=-1, hint="Enter discussion title")
dpg.add_input_text(tag="new_disc_title", width=-1, hint="Enter discussion title",
default_value=prefill_title or "")
dpg.add_spacer(height=5)
dpg.add_text("Location:", color=(150, 200, 255))
@ -2561,10 +2571,15 @@ class DiscussionGUI:
dpg.add_spacer(height=10)
dpg.add_text("Template:", color=(150, 200, 255))
template_items = templates + ["+ Create New Template..."]
# Use prefill template if valid, otherwise first template or 'feature'
if prefill_template and prefill_template in templates:
default_template = prefill_template
else:
default_template = templates[0] if templates else "feature"
dpg.add_combo(
items=template_items,
tag="new_disc_template",
default_value=templates[0] if templates else "feature",
default_value=default_template,
width=-1,
callback=on_template_change
)
@ -2582,10 +2597,10 @@ class DiscussionGUI:
with dpg.child_window(height=150, border=True):
for alias, display_name in participants:
is_default = alias in ["architect", "security", "pragmatist"]
is_selected = alias in dialog_state['selected_participants']
dpg.add_checkbox(
label=f"@{alias} ({display_name})",
default_value=is_default,
default_value=is_selected,
callback=toggle_participant,
user_data=alias
)
@ -2597,7 +2612,8 @@ class DiscussionGUI:
multiline=True,
width=-1,
height=100,
hint="Describe what this discussion is about..."
hint="Describe what this discussion is about...",
default_value=prefill_context or ""
)
dpg.add_spacer(height=15)
@ -4139,6 +4155,17 @@ final = json.dumps(parsed)''',
self._open_discussion(self._pending_open_file)
self._pending_open_file = None
# Show new discussion dialog if requested
if getattr(self, '_pending_new_dialog', None):
prefill = self._pending_new_dialog
self._show_new_discussion_dialog(
prefill_title=prefill.get('title'),
prefill_template=prefill.get('template'),
prefill_participants=prefill.get('participants'),
prefill_context=prefill.get('context'),
)
self._pending_new_dialog = None
# Manual render loop with background task polling
while dpg.is_dearpygui_running():
# Poll for updates from background threads (output, turn completion)
@ -4150,12 +4177,19 @@ final = json.dumps(parsed)''',
dpg.destroy_context()
def main(discussions_dir: str = None, open_file: str = None):
def main(discussions_dir: str = None, open_file: str = None, show_new_dialog: bool = False,
prefill_title: str = None, prefill_template: str = None,
prefill_participants: list[str] = None, prefill_context: str = None):
"""Entry point for GUI.
Args:
discussions_dir: Directory to browse for discussions
open_file: Specific discussion file to open immediately
show_new_dialog: Show new discussion dialog on launch
prefill_title: Pre-fill title in new discussion dialog
prefill_template: Pre-select template in new discussion dialog
prefill_participants: Pre-select participants in new discussion dialog
prefill_context: Pre-fill context in new discussion dialog
"""
dir_path = Path(discussions_dir) if discussions_dir else None
app = DiscussionGUI(dir_path)
@ -4166,6 +4200,17 @@ def main(discussions_dir: str = None, open_file: str = None):
else:
app._pending_open_file = None
# If new dialog was requested, store prefill data
if show_new_dialog:
app._pending_new_dialog = {
'title': prefill_title,
'template': prefill_template,
'participants': prefill_participants,
'context': prefill_context,
}
else:
app._pending_new_dialog = None
app.run()