run.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package cmd
  2. import (
  3. "context"
  4. "fmt"
  5. "log/slog"
  6. "os"
  7. "os/signal"
  8. "strings"
  9. "github.com/charmbracelet/crush/internal/event"
  10. "github.com/spf13/cobra"
  11. )
  12. var runCmd = &cobra.Command{
  13. Use: "run [prompt...]",
  14. Short: "Run a single non-interactive prompt",
  15. Long: `Run a single prompt in non-interactive mode and exit.
  16. The prompt can be provided as arguments or piped from stdin.`,
  17. Example: `
  18. # Run a simple prompt
  19. crush run Explain the use of context in Go
  20. # Pipe input from stdin
  21. curl https://charm.land | crush run "Summarize this website"
  22. # Read from a file
  23. crush run "What is this code doing?" <<< prrr.go
  24. # Run in quiet mode (hide the spinner)
  25. crush run --quiet "Generate a README for this project"
  26. `,
  27. RunE: func(cmd *cobra.Command, args []string) error {
  28. quiet, _ := cmd.Flags().GetBool("quiet")
  29. // Cancel on SIGINT or SIGTERM.
  30. ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
  31. defer cancel()
  32. app, err := setupApp(cmd)
  33. if err != nil {
  34. return err
  35. }
  36. defer app.Shutdown()
  37. if !app.Config().IsConfigured() {
  38. return fmt.Errorf("no providers configured - please run 'crush' to set up a provider interactively")
  39. }
  40. prompt := strings.Join(args, " ")
  41. prompt, err = MaybePrependStdin(prompt)
  42. if err != nil {
  43. slog.Error("Failed to read from stdin", "error", err)
  44. return err
  45. }
  46. if prompt == "" {
  47. return fmt.Errorf("no prompt provided")
  48. }
  49. event.SetNonInteractive(true)
  50. event.AppInitialized()
  51. return app.RunNonInteractive(ctx, os.Stdout, prompt, quiet)
  52. },
  53. PostRun: func(cmd *cobra.Command, args []string) {
  54. event.AppExited()
  55. },
  56. }
  57. func init() {
  58. runCmd.Flags().BoolP("quiet", "q", false, "Hide spinner")
  59. }