feat: add CLI with start/stop/status commands

Made-with: Cursor
This commit is contained in:
cottongin
2026-03-10 02:46:38 -04:00
parent bcd8d4da1a
commit bce6ec39f8

103
src/cursor_flasher/cli.py Normal file
View File

@@ -0,0 +1,103 @@
"""CLI for starting/stopping the cursor-flasher daemon."""
import argparse
import os
import signal
import sys
from pathlib import Path
from cursor_flasher.daemon import run_daemon
PID_FILE = Path.home() / ".cursor-flasher" / "daemon.pid"
def _write_pid() -> None:
PID_FILE.parent.mkdir(parents=True, exist_ok=True)
PID_FILE.write_text(str(os.getpid()))
def _read_pid() -> int | None:
if not PID_FILE.exists():
return None
try:
pid = int(PID_FILE.read_text().strip())
os.kill(pid, 0)
return pid
except (ValueError, ProcessLookupError, PermissionError):
PID_FILE.unlink(missing_ok=True)
return None
def _remove_pid() -> None:
PID_FILE.unlink(missing_ok=True)
def cmd_start(args: argparse.Namespace) -> None:
existing = _read_pid()
if existing is not None:
print(f"Daemon already running (PID {existing})")
sys.exit(1)
if args.foreground:
_write_pid()
try:
run_daemon()
finally:
_remove_pid()
else:
pid = os.fork()
if pid > 0:
print(f"Daemon started (PID {pid})")
return
os.setsid()
_write_pid()
try:
run_daemon()
finally:
_remove_pid()
def cmd_stop(args: argparse.Namespace) -> None:
pid = _read_pid()
if pid is None:
print("Daemon is not running")
sys.exit(1)
os.kill(pid, signal.SIGTERM)
_remove_pid()
print(f"Daemon stopped (PID {pid})")
def cmd_status(args: argparse.Namespace) -> None:
pid = _read_pid()
if pid is None:
print("Daemon is not running")
else:
print(f"Daemon is running (PID {pid})")
def main() -> None:
parser = argparse.ArgumentParser(
prog="cursor-flasher",
description="Flash the Cursor window when the AI agent is waiting for input",
)
sub = parser.add_subparsers(dest="command")
start_parser = sub.add_parser("start", help="Start the daemon")
start_parser.add_argument(
"--foreground", "-f", action="store_true",
help="Run in the foreground (don't daemonize)",
)
start_parser.set_defaults(func=cmd_start)
stop_parser = sub.add_parser("stop", help="Stop the daemon")
stop_parser.set_defaults(func=cmd_stop)
status_parser = sub.add_parser("status", help="Check daemon status")
status_parser.set_defaults(func=cmd_status)
args = parser.parse_args()
if not hasattr(args, "func"):
parser.print_help()
sys.exit(1)
args.func(args)