Coverage for src/alprina_cli/utils/welcome.py: 42%

24 statements  

« prev     ^ index     » next       coverage.py v7.11.3, created at 2025-11-14 11:27 +0100

1""" 

2Welcome screen and first-run experience for Alprina CLI. 

3""" 

4 

5from rich.console import Console 

6from rich.panel import Panel 

7from rich import box 

8from typing import Optional 

9from pathlib import Path 

10import os 

11 

12console = Console() 

13 

14 

15def get_auth_status() -> dict: 

16 """ 

17 Check if user is authenticated. 

18  

19 Returns: 

20 dict with is_authenticated, email, tier, scans_remaining 

21 """ 

22 # Check for API key in environment or config 

23 from ..config import get_api_key 

24 

25 api_key = get_api_key() 

26 

27 if not api_key: 

28 return { 

29 "is_authenticated": False, 

30 "email": None, 

31 "tier": None, 

32 "scans_remaining": None, 

33 "api_key": None 

34 } 

35 

36 # TODO: Call API to get user info 

37 # For now, just return that they're authenticated 

38 return { 

39 "is_authenticated": True, 

40 "email": "user@example.com", # TODO: Get from API 

41 "tier": "free", 

42 "scans_remaining": 10, 

43 "api_key": api_key 

44 } 

45 

46 

47def show_welcome(force: bool = False) -> bool: 

48 """ 

49 Show welcome message on first run or if not authenticated. 

50  

51 Args: 

52 force: Force show welcome even if authenticated 

53  

54 Returns: 

55 True if user is authenticated, False otherwise 

56 """ 

57 auth_status = get_auth_status() 

58 

59 if not auth_status["is_authenticated"]: 

60 console.print(Panel.fit( 

61 "[bold cyan]🛡️ Welcome to Alprina![/bold cyan]\n\n" 

62 "Alprina is your AI security testing assistant.\n\n" 

63 "[yellow]You're not signed in yet.[/yellow]\n\n" 

64 "To get started:\n" 

65 " 1. Sign in: [bold]alprina auth login[/bold]\n" 

66 " 2. Run scan: [bold]alprina scan ./[/bold]\n" 

67 " 3. Chat: [bold]alprina chat[/bold]\n\n" 

68 "Need help? Run: [bold]alprina --help[/bold]", 

69 title="🛡️ Alprina Security CLI", 

70 border_style="cyan", 

71 box=box.DOUBLE 

72 )) 

73 return False 

74 

75 elif force: 

76 console.print(Panel.fit( 

77 f"[bold green]✅ Welcome back![/bold green]\n\n" 

78 f"[dim]Tier: {auth_status['tier']} | Scans: {auth_status['scans_remaining']} remaining[/dim]\n\n" 

79 "What would you like to do?\n" 

80 " • [bold]alprina scan ./[/bold] - Scan for vulnerabilities\n" 

81 " • [bold]alprina chat[/bold] - Interactive AI assistant\n" 

82 " • [bold]alprina fix ./[/bold] - Auto-fix vulnerabilities\n\n" 

83 "Type [bold]alprina --help[/bold] for more commands", 

84 title="🛡️ Alprina", 

85 border_style="green", 

86 box=box.ROUNDED 

87 )) 

88 return True 

89 

90 return True 

91 

92 

93def show_not_authenticated_error(): 

94 """Show friendly error when command requires auth.""" 

95 console.print(Panel.fit( 

96 "[bold red]❌ Not signed in[/bold red]\n\n" 

97 "This command requires authentication.\n\n" 

98 "[yellow]💡 Solution:[/yellow]\n" 

99 "Run: [bold]alprina auth login[/bold]\n\n" 

100 "Need help? Visit: https://alprina.com/docs/cli/auth", 

101 title="Authentication Required", 

102 border_style="red", 

103 box=box.ROUNDED 

104 ))