run.go 1.7 KB

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