wizard.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. # 快速启动向导
  2. # 交互式项目初始化工具
  3. #!/usr/bin/env python3
  4. """
  5. AceFlow 快速启动向导
  6. 帮助用户快速初始化新项目
  7. """
  8. import os
  9. import yaml
  10. import json
  11. from pathlib import Path
  12. from datetime import datetime
  13. class AceFlowWizard:
  14. def __init__(self):
  15. self.aceflow_dir = Path(".aceflow")
  16. self.templates_dir = self.aceflow_dir / "templates"
  17. self.project_config = {}
  18. def run(self):
  19. """运行快速启动向导"""
  20. print("🚀 欢迎使用 AceFlow 快速启动向导")
  21. print("=" * 50)
  22. # 1. 项目基本信息
  23. self.collect_basic_info()
  24. # 2. 选择项目模板
  25. template = self.select_template()
  26. # 3. 配置项目参数
  27. self.configure_project(template)
  28. # 4. 初始化项目
  29. self.initialize_project(template)
  30. print("\n🎉 项目初始化完成!")
  31. self.show_next_steps()
  32. def collect_basic_info(self):
  33. """收集项目基本信息"""
  34. print("\n📋 项目基本信息")
  35. print("-" * 20)
  36. self.project_config['name'] = input("项目名称: ").strip()
  37. self.project_config['description'] = input("项目描述 (可选): ").strip()
  38. # 团队规模
  39. print("\n团队规模:")
  40. print("1. 1-3人 (个人/小团队)")
  41. print("2. 4-10人 (中型团队)")
  42. print("3. 10+人 (大型团队)")
  43. team_choice = input("请选择 (1-3): ").strip()
  44. team_sizes = {
  45. '1': '1-3人',
  46. '2': '4-10人',
  47. '3': '10+人'
  48. }
  49. self.project_config['team_size'] = team_sizes.get(team_choice, '1-3人')
  50. # 项目周期
  51. print("\n预期开发周期:")
  52. print("1. <1周 (快速原型/小功能)")
  53. print("2. 1-4周 (中型功能)")
  54. print("3. 1-3月 (完整应用)")
  55. print("4. >3月 (大型系统)")
  56. duration_choice = input("请选择 (1-4): ").strip()
  57. durations = {
  58. '1': '<1周',
  59. '2': '1-4周',
  60. '3': '1-3月',
  61. '4': '>3月'
  62. }
  63. self.project_config['duration'] = durations.get(duration_choice, '1-4周')
  64. def select_template(self):
  65. """选择项目模板"""
  66. print("\n🎯 选择流程模式")
  67. print("-" * 20)
  68. # 智能推荐
  69. recommended = self.recommend_template()
  70. print(f"💡 AI推荐: {recommended['name']} ({recommended['reason']})")
  71. print("\n可用模式:")
  72. templates = {
  73. '1': {
  74. 'id': 'minimal',
  75. 'name': '轻量级模式',
  76. 'stages': 'P→D→R (3阶段)',
  77. 'duration': '2-7天',
  78. 'suitable': '小型项目、快速迭代、原型验证'
  79. },
  80. '2': {
  81. 'id': 'standard',
  82. 'name': '标准模式',
  83. 'stages': 'P1→P2→D1→D2→R1 (5阶段)',
  84. 'duration': '1-2周',
  85. 'suitable': '中型项目、敏捷团队、企业应用'
  86. },
  87. '3': {
  88. 'id': 'complete',
  89. 'name': '完整模式',
  90. 'stages': 'S1→...→S8 (8阶段)',
  91. 'duration': '2-4周',
  92. 'suitable': '大型项目、关键系统、严格质量控制'
  93. }
  94. }
  95. for key, template in templates.items():
  96. print(f"{key}. {template['name']}")
  97. print(f" 流程: {template['stages']}")
  98. print(f" 周期: {template['duration']}")
  99. print(f" 适用: {template['suitable']}")
  100. print()
  101. choice = input(f"请选择模式 (1-3, 推荐: {recommended['choice']}): ").strip()
  102. if not choice:
  103. choice = recommended['choice']
  104. selected_template = templates.get(choice, templates['1'])
  105. print(f"✅ 已选择: {selected_template['name']}")
  106. return selected_template
  107. def recommend_template(self):
  108. """智能推荐模板"""
  109. team_size = self.project_config['team_size']
  110. duration = self.project_config['duration']
  111. # 简单的推荐逻辑
  112. if '1-3人' in team_size and ('<1周' in duration or '1-4周' in duration):
  113. return {
  114. 'choice': '1',
  115. 'name': '轻量级模式',
  116. 'reason': '小团队短周期项目,适合快速迭代'
  117. }
  118. elif '4-10人' in team_size and '1-4周' in duration:
  119. return {
  120. 'choice': '2',
  121. 'name': '标准模式',
  122. 'reason': '中型团队,需要平衡效率和质量'
  123. }
  124. elif '10+人' in team_size or '>3月' in duration:
  125. return {
  126. 'choice': '3',
  127. 'name': '完整模式',
  128. 'reason': '大型团队或长周期项目,需要严格质量控制'
  129. }
  130. else:
  131. return {
  132. 'choice': '2',
  133. 'name': '标准模式',
  134. 'reason': '通用选择,适合大部分项目'
  135. }
  136. def configure_project(self, template):
  137. """配置项目参数"""
  138. print(f"\n⚙️ 配置 {template['name']}")
  139. print("-" * 20)
  140. # 加载模板配置
  141. template_file = self.templates_dir / template['id'] / "template.yaml"
  142. if template_file.exists():
  143. with open(template_file, 'r', encoding='utf-8') as f:
  144. template_config = yaml.safe_load(f)
  145. # 根据模板提示收集额外信息
  146. if 'initialization' in template_config and 'prompts' in template_config['initialization']:
  147. for prompt in template_config['initialization']['prompts']:
  148. if prompt.get('required', False) or input(f"配置 {prompt['question']}? (y/n): ").lower().startswith('y'):
  149. if prompt['type'] == 'select':
  150. print(f"{prompt['question']}:")
  151. for i, option in enumerate(prompt['options'], 1):
  152. print(f" {i}. {option}")
  153. choice = input("请选择: ").strip()
  154. try:
  155. self.project_config[prompt['key']] = prompt['options'][int(choice)-1]
  156. except (ValueError, IndexError):
  157. self.project_config[prompt['key']] = prompt['options'][0]
  158. else:
  159. self.project_config[prompt['key']] = input(f"{prompt['question']}: ").strip()
  160. # 敏捷集成选项
  161. print("\n🔄 敏捷集成:")
  162. print("1. Scrum")
  163. print("2. Kanban")
  164. print("3. 不使用")
  165. agile_choice = input("选择敏捷框架 (1-3): ").strip()
  166. agile_frameworks = {'1': 'scrum', '2': 'kanban', '3': 'none'}
  167. self.project_config['agile_framework'] = agile_frameworks.get(agile_choice, 'none')
  168. if self.project_config['agile_framework'] != 'none':
  169. self.project_config['iteration_length'] = input("迭代周期 (如: 2weeks): ").strip() or "2weeks"
  170. def initialize_project(self, template):
  171. """初始化项目"""
  172. print(f"\n🔨 初始化项目...")
  173. # 创建配置文件
  174. config = {
  175. 'project': {
  176. 'name': self.project_config.get('name', 'Untitled Project'),
  177. 'description': self.project_config.get('description', ''),
  178. 'team_size': self.project_config.get('team_size', '1-3人'),
  179. 'created_at': datetime.now().isoformat(),
  180. 'template': template['id']
  181. },
  182. 'flow': {
  183. 'mode': template['id'],
  184. 'current_stage': None
  185. },
  186. 'agile': {
  187. 'enabled': self.project_config['agile_framework'] != 'none',
  188. 'framework': self.project_config.get('agile_framework', 'none'),
  189. 'iteration_length': self.project_config.get('iteration_length', '2weeks')
  190. },
  191. 'ai': {
  192. 'enabled': True,
  193. 'auto_recommendations': True
  194. }
  195. }
  196. # 保存配置
  197. config_file = self.aceflow_dir / "config.yaml"
  198. with open(config_file, 'w', encoding='utf-8') as f:
  199. yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
  200. # 初始化状态
  201. state = {
  202. 'project_id': self.project_config.get('name', 'untitled').lower().replace(' ', '-'),
  203. 'flow_mode': template['id'],
  204. 'current_stage': None,
  205. 'stage_states': {},
  206. 'created_at': datetime.now().isoformat(),
  207. 'version': '2.0.0',
  208. 'progress': {'overall': 0, 'stages': {}},
  209. 'deliverables': {},
  210. 'memory_pool': {'requirements': [], 'decisions': [], 'issues': []}
  211. }
  212. state_file = self.aceflow_dir / "state" / "project_state.json"
  213. with open(state_file, 'w', encoding='utf-8') as f:
  214. json.dump(state, f, indent=2, ensure_ascii=False)
  215. print("✅ 配置文件已创建")
  216. print("✅ 项目状态已初始化")
  217. # 复制模板文件
  218. self.copy_template_files(template)
  219. def copy_template_files(self, template):
  220. """复制模板文件到项目"""
  221. template_dir = self.templates_dir / template['id']
  222. if not template_dir.exists():
  223. print("⚠️ 模板文件不存在,跳过文件复制")
  224. return
  225. # 创建文档目录
  226. docs_dir = Path("docs")
  227. docs_dir.mkdir(exist_ok=True)
  228. # 复制markdown模板文件
  229. for template_file in template_dir.glob("*.md"):
  230. target_file = docs_dir / template_file.name
  231. # 读取模板内容并替换变量
  232. with open(template_file, 'r', encoding='utf-8') as f:
  233. content = f.read()
  234. # 简单的变量替换
  235. for key, value in self.project_config.items():
  236. content = content.replace(f"{{{{{key}}}}}", str(value))
  237. # 写入目标文件
  238. with open(target_file, 'w', encoding='utf-8') as f:
  239. f.write(content)
  240. print("✅ 模板文件已复制到 docs/ 目录")
  241. def show_next_steps(self):
  242. """显示下一步操作建议"""
  243. print("\n🎯 下一步操作:")
  244. print("1. python .aceflow/scripts/aceflow status # 查看项目状态")
  245. print("2. python .aceflow/scripts/aceflow start # 开始第一个阶段")
  246. print("3. python .aceflow/scripts/aceflow web # 打开Web界面")
  247. print("\n📚 文档位置:")
  248. print("- 项目文档: docs/ 目录")
  249. print("- 配置文件: .aceflow/config.yaml")
  250. print("- 状态文件: .aceflow/state/project_state.json")
  251. def main():
  252. """主函数"""
  253. wizard = AceFlowWizard()
  254. try:
  255. wizard.run()
  256. except KeyboardInterrupt:
  257. print("\n\n👋 已取消初始化")
  258. except Exception as e:
  259. print(f"\n❌ 初始化失败: {e}")
  260. if __name__ == "__main__":
  261. main()