Coverage for src / moai_adk / __main__.py: 42.37%

59 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2025-11-20 20:52 +0900

1# type: ignore 

2"""MoAI-ADK CLI Entry Point 

3 

4Implements the CLI entry point: 

5- Click-based CLI framework 

6- Rich console terminal output 

7- ASCII logo rendering 

8- --version and --help options 

9- Five core commands: init, doctor, status, update 

10""" 

11 

12import sys 

13 

14import click 

15import pyfiglet 

16from rich.console import Console 

17 

18from moai_adk import __version__ 

19from moai_adk.cli.commands.doctor import doctor 

20from moai_adk.cli.commands.init import init 

21from moai_adk.cli.commands.status import status 

22from moai_adk.cli.commands.update import update 

23from moai_adk.statusline.main import build_statusline_data 

24 

25console = Console() 

26 

27 

28def show_logo() -> None: 

29 """Render the MoAI-ADK ASCII logo with Pyfiglet""" 

30 # Generate the "MoAI-ADK" banner using the ansi_shadow font 

31 logo = pyfiglet.figlet_format("MoAI-ADK", font="ansi_shadow") 

32 

33 # Print with Rich styling 

34 console.print(logo, style="cyan bold", highlight=False) 

35 console.print( 

36 " Modu-AI's Agentic Development Kit w/ SuperAgent 🎩 Alfred", 

37 style="yellow bold", 

38 ) 

39 console.print() 

40 console.print(" Version: ", style="green", end="") 

41 console.print(__version__, style="cyan bold") 

42 console.print() 

43 console.print(" Tip: Run ", style="yellow", end="") 

44 console.print("uv run moai-adk --help", style="cyan", end="") 

45 console.print(" to see available commands", style="yellow") 

46 

47 

48@click.group(invoke_without_command=True) 

49@click.version_option(version=__version__, prog_name="MoAI-ADK") 

50@click.pass_context 

51def cli(ctx: click.Context) -> None: 

52 """MoAI Agentic Development Kit 

53 

54 SPEC-First TDD Framework with Alfred SuperAgent 

55 """ 

56 # Display the logo when no subcommand is invoked 

57 if ctx.invoked_subcommand is None: 

58 show_logo() 

59 

60 

61cli.add_command(init) 

62cli.add_command(doctor) 

63cli.add_command(status) 

64cli.add_command(update) 

65 

66 

67# statusline command (for Claude Code statusline rendering) 

68@click.command(name="statusline") 

69def statusline() -> None: 

70 """Render Claude Code statusline (internal use only)""" 

71 import json 

72 import sys 

73 

74 try: 

75 # Read JSON context from stdin 

76 input_data = sys.stdin.read() if not sys.stdin.isatty() else "{}" 

77 context = json.loads(input_data) if input_data else {} 

78 except (json.JSONDecodeError, EOFError, ValueError): 

79 context = {} 

80 

81 # Render statusline 

82 output = build_statusline_data(context, mode="extended") 

83 print(output, end="") 

84 

85 

86cli.add_command(statusline) 

87 

88 

89 

90 

91 

92 

93def main() -> int: 

94 """CLI entry point""" 

95 try: 

96 cli(standalone_mode=False) 

97 return 0 

98 except click.Abort: 

99 # User cancelled with Ctrl+C 

100 return 130 

101 except click.ClickException as e: 

102 e.show() 

103 return e.exit_code 

104 except Exception as e: 

105 console.print(f"[red]Error:[/red] {e}") 

106 return 1 

107 finally: 

108 # Flush the output buffer explicitly 

109 console.file.flush() 

110 

111 

112if __name__ == "__main__": 

113 sys.exit(main())