| package main |
|
|
| import ( |
| "fmt" |
| "os" |
|
|
| "github.com/pinchtab/pinchtab/internal/cli" |
| "github.com/pinchtab/pinchtab/internal/config" |
| "github.com/pinchtab/pinchtab/internal/server" |
| "github.com/spf13/cobra" |
| ) |
|
|
| var version = "dev" |
|
|
| var rootCmd = &cobra.Command{ |
| Use: "pinchtab", |
| Short: "PinchTab - Browser control for AI agents", |
| Long: `PinchTab provides a lightweight, API-driven way for AI agents to control |
| browsers, manage tabs, and perform interactive tasks.`, |
| Example: ` pinchtab server |
| pinchtab nav https://pinchtab.com`, |
| Run: func(cmd *cobra.Command, args []string) { |
| cfg := config.Load() |
|
|
| |
| maybeRunWizard() |
|
|
| if isInteractiveTerminal() { |
| cli.PrintStartupBanner(cfg, cli.StartupBannerOptions{ |
| Mode: "menu", |
| ListenStatus: menuListenStatus(cfg), |
| }) |
|
|
| picked, err := promptSelect("Main Menu", []menuOption{ |
| {label: "Start server", value: "server"}, |
| {label: "Daemon", value: "daemon"}, |
| {label: "Start bridge", value: "bridge"}, |
| {label: "Start MCP server", value: "mcp"}, |
| {label: "Config", value: "config"}, |
| {label: "Security", value: "security"}, |
| {label: "Help", value: "help"}, |
| {label: "Exit", value: "exit"}, |
| }) |
|
|
| if err != nil || picked == "exit" || picked == "" { |
| return |
| } |
|
|
| switch picked { |
| case "server": |
| server.RunDashboard(cfg, version) |
| case "daemon": |
| handleDaemonCommand(cfg, "") |
| case "bridge": |
| server.RunBridgeServer(cfg) |
| case "mcp": |
| runMCP(cfg) |
| case "config": |
| handleConfigOverview(cfg) |
| case "security": |
| handleSecurityCommand(cfg) |
| case "help": |
| _ = cmd.Help() |
| } |
| return |
| } |
|
|
| |
| server.RunDashboard(cfg, version) |
| }, |
| } |
|
|
| |
| func maybeRunWizard() { |
| fileCfg, configPath, err := config.LoadFileConfig() |
| if err != nil || configPath == "" { |
| return |
| } |
|
|
| if !config.NeedsWizard(fileCfg) { |
| return |
| } |
|
|
| isNew := config.IsFirstRun(fileCfg) |
| runSecurityWizard(fileCfg, configPath, isNew) |
| } |
|
|
| func menuListenStatus(cfg *config.RuntimeConfig) string { |
| dashPort := cfg.Port |
| if dashPort == "" { |
| dashPort = "9870" |
| } |
| if server.CheckPinchTabRunning(dashPort, cfg.Token) { |
| return "running" |
| } |
| return "stopped" |
| } |
|
|
| func Execute() { |
| if err := rootCmd.Execute(); err != nil { |
| fmt.Fprintln(os.Stderr, err) |
| os.Exit(1) |
| } |
| } |
|
|
| |
| var serverURL string |
|
|
| func init() { |
| rootCmd.Version = version |
| rootCmd.SetVersionTemplate("pinchtab {{.Version}}\n") |
|
|
| |
| rootCmd.PersistentFlags().StringVar(&serverURL, "server", "", "PinchTab server URL (default: http://127.0.0.1:{port})") |
|
|
| |
| primaryGroup := &cobra.Group{ID: "primary", Title: "Primary Commands"} |
| browserGroup := &cobra.Group{ID: "browser", Title: "Browser Control"} |
| mgmtGroup := &cobra.Group{ID: "management", Title: "Profiles and Instances"} |
| configGroup := &cobra.Group{ID: "config", Title: "Configuration & Setup"} |
|
|
| rootCmd.AddGroup(primaryGroup, browserGroup, mgmtGroup, configGroup) |
|
|
| cli.SetupUsage(rootCmd) |
| } |
|
|