From 40ad935dda97781bd69d11ae695cfed42cc9f7fa Mon Sep 17 00:00:00 2001 From: David Gwilliam Date: Sun, 15 Mar 2026 17:49:15 -0700 Subject: [PATCH] feat(cmdline): improve rich output and add mise tasks - Add box-drawing characters for nicer header - Add response formatting with success/error indicators - Add mise tasks: cmd (interactive) and cmd-stats (monitoring) --- cmdline.py | 50 +++++++++++++++++++++++++++++++++++--------------- mise.toml | 7 +++++++ 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/cmdline.py b/cmdline.py index 3ca0794..691a2b7 100644 --- a/cmdline.py +++ b/cmdline.py @@ -122,9 +122,27 @@ def print_header(): print(CLR, end="") print(CURSOR_OFF, end="") print(f"\033[1;1H", end="") - print(f" \033[1;38;5;231mMAINLINE COMMAND CENTER\033[0m") - print(f" \033[2;38;5;37m{'─' * (w - 4)}\033[0m") - print(f" \033[38;5;245mTopic: {TOPIC}\033[0m") + print(f" \033[1;38;5;231m╔{'═' * (w - 6)}╗\033[0m") + print( + f" \033[1;38;5;231m║\033[0m \033[1;38;5;82mMAINLINE\033[0m \033[3;38;5;245mCommand Center\033[0m \033[1;38;5;231m ║\033[0m" + ) + print(f" \033[1;38;5;231m╚{'═' * (w - 6)}╝\033[0m") + print(f" \033[2;38;5;37mTopic: {TOPIC}\033[0m") + print() + + +def print_response(response: str, is_error: bool = False) -> None: + """Print response with nice formatting.""" + print() + if is_error: + print(f" \033[1;38;5;196m✗ Error\033[0m") + print(f" \033[38;5;196m{'─' * 40}\033[0m") + else: + print(f" \033[1;38;5;82m✓ Response\033[0m") + print(f" \033[38;5;37m{'─' * 40}\033[0m") + + for line in response.split("\n"): + print(f" {line}") print() @@ -135,12 +153,12 @@ def interactive_mode(): print_header() poller = NtfyResponsePoller(TOPIC) - print(f"{G_DIM}Type /help for available commands, /quit to exit{RST}") + print(f" \033[38;5;245mType /help for commands, /quit to exit\033[0m") print() while True: try: - cmd = input(f"{G_HI}> {RST}").strip() + cmd = input(f" \033[1;38;5;82m❯\033[0m {G_HI}").strip() except (EOFError, KeyboardInterrupt): print() break @@ -150,19 +168,18 @@ def interactive_mode(): if cmd.startswith("/"): if cmd == "/quit" or cmd == "/exit": - print(f"{G_DIM}Goodbye!{RST}") + print(f"\n \033[1;38;5;245mGoodbye!{RST}\n") break if cmd == "/help": print(f"\n{AVAILABLE_COMMANDS}\n") continue - print(f"{G_DIM}Sending to mainline...{RST}") + print(f" \033[38;5;245m⟳ Sending to mainline...{RST}") result = poller.send_and_wait(cmd) - print(f"\n{result}\n") - + print_response(result, is_error=result.startswith("Error")) else: - print(f"{G_DIM}Commands must start with / - type /help{RST}\n") + print(f"\n \033[1;38;5;196m⚠ Commands must start with /{RST}\n") print(CURSOR_ON, end="") @@ -196,17 +213,20 @@ def main(): if args.watch and "/effects stats" in args.command: print_header() - print(f"{G_DIM}Watching /effects stats (Ctrl+C to exit)...{RST}\n") + print(f" \033[38;5;245mWatching /effects stats (Ctrl+C to exit)...{RST}\n") try: while True: result = poller.send_and_wait(args.command) print(f"\033[2J\033[1;1H", end="") - print(f"{G_HI}Performance Stats - {time.strftime('%H:%M:%S')}{RST}") - print(f"{G_DIM}{'─' * 40}{RST}") - print(result) + print( + f" \033[1;38;5;82m❯\033[0m Performance Stats - \033[1;38;5;245m{time.strftime('%H:%M:%S')}{RST}" + ) + print(f" \033[38;5;37m{'─' * 44}{RST}") + for line in result.split("\n"): + print(f" {line}") time.sleep(2) except KeyboardInterrupt: - print(f"\n{G_DIM}Stopped watching{RST}") + print(f"\n \033[1;38;5;245mStopped watching{RST}") return result = poller.send_and_wait(args.command) diff --git a/mise.toml b/mise.toml index 32f7c59..a921388 100644 --- a/mise.toml +++ b/mise.toml @@ -25,6 +25,13 @@ run = "uv run mainline.py" run-poetry = "uv run mainline.py --poetry" run-firehose = "uv run mainline.py --firehose" +# ===================== +# Command & Control +# ===================== + +cmd = "uv run cmdline.py" +cmd-stats = "uv run cmdline.py -w /effects stats" + # ===================== # Environment # =====================