package main import ( "context" "fmt" "os" "os/signal" "syscall" "gogs.dmsc.dev/arp/arp_cli/cmd" "github.com/urfave/cli/v3" ) func main() { // Create context with cancellation for graceful shutdown ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Handle interrupt signals sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) go func() { <-sigChan cancel() }() // Build the CLI app app := buildApp() // If no arguments provided (only program name), start REPL mode if len(os.Args) <= 1 { repl := cmd.NewREPL(app) if err := repl.Run(ctx); err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } return } // Otherwise, run single command mode if err := app.Run(ctx, os.Args); err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } } func buildApp() *cli.Command { return &cli.Command{ Name: "arp_cli", Usage: "Command-line interface for ARP (Agent-native ERP)", Description: `ARP CLI is a command-line tool for interacting with ARP GraphQL servers. It provides CRUD operations for Services, Users, Notes, Tasks, Messages, Roles, and Permissions. Real-time updates are available via WebSocket subscriptions for Tasks and Messages. When run without arguments, it starts an interactive REPL mode. Use 'exit' or 'quit' to leave the REPL, or Ctrl+D. First, login to an ARP server using 'login' to store your credentials. Then use the various commands to manage your ARP data.`, Version: "1.0.0", Flags: []cli.Flag{ &cli.StringFlag{ Name: "url", Aliases: []string{"u"}, Usage: "ARP server URL", Sources: cli.EnvVars("ARP_URL"), }, &cli.StringFlag{ Name: "output", Aliases: []string{"o"}, Usage: "Output format (table, json)", Value: "table", }, }, Commands: []*cli.Command{ cmd.LoginCommand(), cmd.ConfigCommand(), cmd.ServiceCommand(), cmd.UserCommand(), cmd.NoteCommand(), cmd.TaskCommand(), cmd.MessageCommand(), cmd.RoleCommand(), cmd.PermissionCommand(), cmd.WorkflowCommand(), }, Before: func(ctx context.Context, command *cli.Command) (context.Context, error) { // Store global flags in context for later use return ctx, nil }, Action: func(ctx context.Context, cmd *cli.Command) error { // Show help when no subcommand is provided return cli.ShowAppHelp(cmd) }, } }