#!/usr/bin/env python3 """CLI for gsd-openclaw session management.""" from __future__ import annotations import argparse import sys from typing import List from gsd_openclaw.tmux_session import ( TmuxSessionManager, TmuxSessionError, CleanupResult, ) def cmd_create(args): """Create a new session for a project.""" manager = TmuxSessionManager() try: session = manager.create_session( project_name=args.project, display_name=args.display_name ) print(f"Created session: {session.tmux_session_name}") print(f"Session ID: {session.session_id}") print(f"Project: {session.project_name}") except Exception as e: print(f"Error: {e}", file=sys.stderr) sys.exit(1) def cmd_list(args): """List all gsd sessions.""" manager = TmuxSessionManager() sessions = manager.list_gsd_sessions() if not sessions: print("No active sessions.") return print(f"{'Project':<20} {'Session ID':<10} {'Last Active':<20} {'Status'}") print("-" * 70) for s in sessions: status = "ORPHAN" if s.is_orphan else "active" display = s.display_name or s.project_name print(f"{display:<20} {s.session_id:<10} {s.last_active_at:<20} {status}") def cmd_destroy(args): """Destroy a session.""" manager = TmuxSessionManager() result = manager.destroy_session( project_name=args.project, cleanup_workspace=args.cleanup ) if result: print(f"Destroyed session for: {args.project}") else: print(f"No session found for: {args.project}") sys.exit(1) def cmd_resume(args): """Resume an existing session.""" manager = TmuxSessionManager() try: session = manager.resume_session(project_name=args.project) print(f"Resumed session: {session.tmux_session_name}") print(f"Session ID: {session.session_id}") print(f"Project: {session.project_name}") except TmuxSessionError as e: print(f"Error: {e}", file=sys.stderr) sys.exit(1) def cmd_cleanup(args): """Clean up orphan sessions.""" manager = TmuxSessionManager() result = manager.cleanup_orphans() if result.cleaned_sessions: print(f"Cleaned {len(result.cleaned_sessions)} orphan session(s):") for name in result.cleaned_sessions: print(f" - {name}") if result.errors: print(f"Errors ({len(result.errors)}):") for err in result.errors: print(f" - {err}") if not result.cleaned_sessions and not result.errors: print("No orphan sessions found.") def main(): """Main entry point for CLI.""" parser = argparse.ArgumentParser( prog="gsd-ocl", description="GSD-OpenClaw session management" ) subparsers = parser.add_subparsers(dest="command", required=True) # create p_create = subparsers.add_parser("create", help="Create a new session") p_create.add_argument("project", help="Project name") p_create.add_argument("--display-name", "-d", help="Friendly display name") p_create.set_defaults(func=cmd_create) # list p_list = subparsers.add_parser("list", help="List all sessions") p_list.set_defaults(func=cmd_list) # destroy p_destroy = subparsers.add_parser("destroy", help="Destroy a session") p_destroy.add_argument("project", help="Project name") p_destroy.add_argument("--cleanup", "-c", action="store_true", help="Also remove workspace directory") p_destroy.set_defaults(func=cmd_destroy) # resume p_resume = subparsers.add_parser("resume", help="Resume a session") p_resume.add_argument("project", help="Project name") p_resume.set_defaults(func=cmd_resume) # cleanup p_cleanup = subparsers.add_parser("cleanup", help="Clean up orphan sessions") p_cleanup.set_defaults(func=cmd_cleanup) args = parser.parse_args() args.func(args) if __name__ == "__main__": main()