"""CLI entry point — argparse routing and context creation.""" import argparse import subprocess import sys from flow import __version__ from flow.commands import bootstrap, completion, container, dotfiles, enter, package, sync from flow.core.config import FlowContext, load_config, load_manifest from flow.core.console import ConsoleLogger from flow.core.paths import ensure_dirs from flow.core.platform import detect_platform COMMAND_MODULES = [enter, container, dotfiles, bootstrap, package, sync, completion] def main(): parser = argparse.ArgumentParser( prog="flow", description="DevFlow - A unified toolkit for managing development instances, containers, and profiles", ) parser.add_argument( "-v", "--version", action="version", version=f"flow {__version__}" ) subparsers = parser.add_subparsers(dest="command") for module in COMMAND_MODULES: module.register(subparsers) args = parser.parse_args() if not args.command: parser.print_help() sys.exit(0) if args.command == "completion": handler = getattr(args, "handler", None) if handler: handler(None, args) return parser.print_help() return ensure_dirs() console = ConsoleLogger() try: platform_info = detect_platform() except RuntimeError as e: console.error(str(e)) sys.exit(1) try: config = load_config() manifest = load_manifest() except Exception as e: console.error(f"Failed to load configuration: {e}") sys.exit(1) ctx = FlowContext( config=config, manifest=manifest, platform=platform_info, console=console, ) handler = getattr(args, "handler", None) if handler: try: handler(ctx, args) except KeyboardInterrupt: console.error("Interrupted") sys.exit(130) except subprocess.CalledProcessError as e: detail = (e.stderr or "").strip() or (e.stdout or "").strip() if detail: console.error(detail.splitlines()[-1]) else: console.error(f"Command failed with exit code {e.returncode}") sys.exit(e.returncode or 1) except RuntimeError as e: console.error(str(e)) sys.exit(1) except OSError as e: console.error(str(e)) sys.exit(1) except Exception as e: console.error(f"Unexpected error: {e}") sys.exit(1) else: parser.print_help()