""" Main CLI coordination and entry point. """ import argparse import sys from .base import NimbusFlowCLI, CLIError from .commands import ( # Member commands cmd_members_list, cmd_members_show, setup_members_parser, # Schedule commands cmd_schedules_list, cmd_schedules_show, cmd_schedules_accept, cmd_schedules_decline, cmd_schedules_schedule, setup_schedules_parser, # Service commands cmd_services_list, setup_services_parser, ) from .interactive import run_interactive_mode def setup_parser() -> argparse.ArgumentParser: """Set up the command-line argument parser.""" parser = argparse.ArgumentParser( prog="python -m backend.cli", description="NimbusFlow CLI - Manage the scheduling system", formatter_class=argparse.RawDescriptionHelpFormatter ) subparsers = parser.add_subparsers(dest="command", help="Available commands") # Set up all command parsers using the modular functions setup_members_parser(subparsers) setup_schedules_parser(subparsers) setup_services_parser(subparsers) return parser def main(): """Main CLI entry point.""" parser = setup_parser() args = parser.parse_args() if not args.command: # Launch interactive mode when no command is provided try: cli = NimbusFlowCLI(create_version=True) # Always create versioned DB for interactive mode # Show versioning info with colors from .base import Colors versions = cli.list_database_versions() if len(versions) > 1: print(f"{Colors.CYAN}Database versions available:{Colors.RESET} {Colors.SUCCESS}{len(versions)}{Colors.RESET}") print(f"{Colors.CYAN}Using:{Colors.RESET} {Colors.CYAN}{cli.db_path.name}{Colors.RESET}") # Auto-cleanup if too many versions if len(versions) > 10: deleted = cli.cleanup_old_versions(keep_latest=5) if deleted > 0: print(f"{Colors.WARNING}Cleaned up {deleted} old database versions{Colors.RESET}") run_interactive_mode(cli) except CLIError as e: print(f"{Colors.ERROR}❌ Error: {e}{Colors.RESET}") return 1 except KeyboardInterrupt: print(f"\n{Colors.WARNING}🛑 Interrupted by user{Colors.RESET}") return 1 except Exception as e: print(f"{Colors.ERROR}❌ Unexpected error: {e}{Colors.RESET}") return 1 finally: if 'cli' in locals(): cli.close() return try: cli = NimbusFlowCLI(create_version=False) # Don't version for regular CLI commands # Show which database is being used for regular commands from .base import Colors print(f"{Colors.CYAN}Using database:{Colors.RESET} {Colors.CYAN}{cli.db_path.name}{Colors.RESET}") # Route commands to their respective handlers if args.command == "members": if args.members_action == "list": cmd_members_list(cli, args) elif args.members_action == "show": cmd_members_show(cli, args) else: print(f"{Colors.ERROR}❌ Unknown members action. Use 'list' or 'show'{Colors.RESET}") elif args.command == "schedules": if args.schedules_action == "list": cmd_schedules_list(cli, args) elif args.schedules_action == "show": cmd_schedules_show(cli, args) elif args.schedules_action == "accept": cmd_schedules_accept(cli, args) elif args.schedules_action == "decline": cmd_schedules_decline(cli, args) elif args.schedules_action == "schedule": cmd_schedules_schedule(cli, args) else: print(f"{Colors.ERROR}❌ Unknown schedules action. Use 'list', 'show', 'accept', 'decline', or 'schedule'{Colors.RESET}") elif args.command == "services": if args.services_action == "list": cmd_services_list(cli, args) else: print(f"{Colors.ERROR}❌ Unknown services action. Use 'list'{Colors.RESET}") else: print(f"{Colors.ERROR}❌ Unknown command: {args.command}{Colors.RESET}") except CLIError as e: print(f"{Colors.ERROR}❌ Error: {e}{Colors.RESET}") return 1 except KeyboardInterrupt: print(f"\n{Colors.WARNING}🛑 Interrupted by user{Colors.RESET}") return 1 except Exception as e: print(f"{Colors.ERROR}❌ Unexpected error: {e}{Colors.RESET}") return 1 finally: if 'cli' in locals(): cli.close() return 0