Coverage for src / moai_adk / cli / prompts / init_prompts.py: 15.56%
45 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-20 20:52 +0900
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-20 20:52 +0900
1"""Project initialization prompts
3Collect interactive project settings
4"""
6from pathlib import Path
7from typing import TypedDict
9import questionary
10from rich.console import Console
12console = Console()
15class ProjectSetupAnswers(TypedDict):
16 """Project setup answers"""
18 project_name: str
19 mode: str # personal | team (default from init)
20 locale: str # ko | en | ja | zh | other (default from init)
21 language: str | None # Will be set in /alfred:0-project
22 author: str # Will be set in /alfred:0-project
23 custom_language: str | None # User input for "other" language option
26def prompt_project_setup(
27 project_name: str | None = None,
28 is_current_dir: bool = False,
29 project_path: Path | None = None,
30 initial_locale: str | None = None,
31) -> ProjectSetupAnswers:
32 """Project setup prompt
34 Args:
35 project_name: Project name (asks when None)
36 is_current_dir: Whether the current directory is being used
37 project_path: Project path (used to derive the name)
38 initial_locale: Preferred locale provided via CLI (optional)
40 Returns:
41 Project setup answers
43 Raises:
44 KeyboardInterrupt: When user cancels the prompt (Ctrl+C)
45 """
46 answers: ProjectSetupAnswers = {
47 "project_name": "",
48 "mode": "personal", # Default: will be configurable in /alfred:0-project
49 "locale": "en", # Default: will be configurable in /alfred:0-project
50 "language": None, # Will be detected in /alfred:0-project
51 "author": "", # Will be set in /alfred:0-project
52 "custom_language": None, # User input for other language
53 }
55 try:
56 # SIMPLIFIED: Only ask for project name
57 # All other settings (mode, locale, language, author) are now configured in /alfred:0-project
59 # 1. Project name (only when not using the current directory)
60 if not is_current_dir:
61 if project_name:
62 answers["project_name"] = project_name
63 console.print(f"[cyan]📦 Project Name:[/cyan] {project_name}")
64 else:
65 result = questionary.text(
66 "📦 Project Name:",
67 default="my-moai-project",
68 validate=lambda text: len(text) > 0 or "Project name is required",
69 ).ask()
70 if result is None:
71 raise KeyboardInterrupt
72 answers["project_name"] = result
73 else:
74 # Use the current directory name
75 # Note: Path.cwd() reflects the process working directory (Codex CLI cwd)
76 # Prefer project_path when provided (user execution location)
77 if project_path:
78 answers["project_name"] = project_path.name
79 else:
80 answers["project_name"] = Path.cwd().name # fallback
81 console.print(
82 f"[cyan]📦 Project Name:[/cyan] {answers['project_name']} [dim](current directory)[/dim]"
83 )
85 # 2. Language selection - Korean, English, Japanese, Chinese, Other
86 console.print("\n[blue]🌐 Language Selection[/blue]")
88 # Build choices list
89 language_choices = [
90 "Korean (한국어)",
91 "English",
92 "Japanese (日本語)",
93 "Chinese (中文)",
94 "Other - Manual input",
95 ]
97 # Determine default choice index
98 language_values = ["ko", "en", "ja", "zh", "other"]
99 default_locale = initial_locale or "en"
100 default_index = language_values.index(default_locale) if default_locale in language_values else 1
102 language_choice_name = questionary.select(
103 "Select your conversation language:",
104 choices=language_choices,
105 default=language_choices[default_index],
106 ).ask()
108 # Map choice name back to value
109 choice_mapping = {
110 "Korean (한국어)": "ko",
111 "English": "en",
112 "Japanese (日本語)": "ja",
113 "Chinese (中文)": "zh",
114 "Other - Manual input": "other",
115 }
116 language_choice = choice_mapping.get(language_choice_name)
118 if language_choice is None:
119 raise KeyboardInterrupt
121 if language_choice == "other":
122 # Prompt for manual input
123 custom_lang = questionary.text(
124 "Enter your language:",
125 validate=lambda text: len(text) > 0 or "Language is required",
126 ).ask()
128 if custom_lang is None:
129 raise KeyboardInterrupt
131 answers["custom_language"] = custom_lang
132 answers["locale"] = "other" # When ISO code is not available
133 console.print(f"[cyan]🌐 Selected Language:[/cyan] {custom_lang}")
134 else:
135 answers["locale"] = language_choice
136 language_names = {
137 "ko": "Korean (한국어)",
138 "en": "English",
139 "ja": "Japanese (日本語)",
140 "zh": "Chinese (中文)",
141 }
142 console.print(
143 f"[cyan]🌐 Selected Language:[/cyan] {language_names.get(language_choice, language_choice)}"
144 )
146 return answers
148 except KeyboardInterrupt:
149 console.print("\n[yellow]Setup cancelled by user[/yellow]")
150 raise