#!/usr/bin/env python3 # SPDX-FileCopyrightText: 2026 Huang # SPDX-License-Identifier: AGPL-3.0-or-later """Top-level launcher for TUI, CLI, and debug modes.""" import sys from typing import List from python_jms_clienter import JMSClient from python_jms_clienter.cli import main as cli_main __all__ = ["JMSClient", "main"] DEFAULT_DEBUG_LOG_FILE = "./jms-client.debug.log" def _print_mode_help(): """Prints top-level mode help for `main.py`.""" print("Usage:") print(" python main.py tui [jms-client global options]") print(" python main.py cli [jms-client global options] [subcommand options]") print(" python main.py debug [jms-client args]") print("") print("Common global options:") print(" --base-url ") print(" --key-id ") print(" --key-secret ") print(" --org-id ") print("") print("Examples:") print(" python main.py cli list-servers") print(" python main.py cli --help") print( " python main.py cli --base-url https://jumpserver.example.com " "--key-id --key-secret list-servers" ) print(" python main.py cli get-token --asset-id --account ") print( " python main.py tui --base-url https://jumpserver.example.com " "--key-id --key-secret " ) print(" python main.py debug tui") print(" python main.py debug cli list-servers") def _inject_debug_args(args: List[str]) -> List[str]: """Ensures debug flags are present before forwarding arguments.""" has_debug = any(item == "--debug" for item in args) has_log_file = any( item == "--log-file" or str(item).startswith("--log-file=") for item in args ) output = [] # type: list if not has_debug: output.append("--debug") if not has_log_file: output.extend(["--log-file", DEFAULT_DEBUG_LOG_FILE]) output.extend(args) return output def _choose_mode_interactive() -> str: """Prompts the user to choose a startup mode.""" while True: print("Select mode:") print(" 1) TUI") print(" 2) CLI") print(" 3) DEBUG") print(" q) Quit") value = input("> ").strip().lower() if value in ("1", "tui"): return "tui" if value in ("2", "cli"): return "cli" if value in ("3", "debug"): return "debug" if value in ("q", "quit", "exit"): return "quit" print("Invalid selection, try again.") def main() -> int: """Executes the top-level dispatcher for TUI and CLI entrypoints.""" args = sys.argv[1:] if not args: mode = _choose_mode_interactive() if mode == "quit": return 0 if mode == "tui": return cli_main(["tui"]) if mode == "debug": print(f"Debug mode enabled, log file: {DEFAULT_DEBUG_LOG_FILE}") return cli_main(_inject_debug_args(["tui"])) _print_mode_help() return 0 mode = args[0].lower() rest = args[1:] if mode in ("-h", "--help", "help"): _print_mode_help() return 0 if mode == "tui": return cli_main(rest + ["tui"]) if mode == "cli": if not rest: return cli_main(["--help"]) return cli_main(rest) if mode == "debug": if not rest: _print_mode_help() return 0 submode = rest[0].lower() subrest = rest[1:] debug_log = DEFAULT_DEBUG_LOG_FILE for idx, item in enumerate(rest): if item.startswith("--log-file="): debug_log = item.split("=", 1)[1] or debug_log break if item == "--log-file" and idx + 1 < len(rest): debug_log = rest[idx + 1] break print(f"Debug mode enabled, log file: {debug_log}") if submode == "tui": return cli_main(_inject_debug_args(subrest + ["tui"])) if submode == "cli": if not subrest: return cli_main(_inject_debug_args(["--help"])) return cli_main(_inject_debug_args(subrest)) return cli_main(_inject_debug_args(rest)) print(f"Unknown mode: {mode}") _print_mode_help() return 2 if __name__ == "__main__": raise SystemExit(main())