@@ -12,6 +12,7 @@ import (
1212 "github.com/opencode-ai/opencode/internal/app"
1313 "github.com/opencode-ai/opencode/internal/config"
1414 "github.com/opencode-ai/opencode/internal/db"
15+ "github.com/opencode-ai/opencode/internal/format"
1516 "github.com/opencode-ai/opencode/internal/llm/agent"
1617 "github.com/opencode-ai/opencode/internal/logging"
1718 "github.com/opencode-ai/opencode/internal/pubsub"
@@ -21,11 +22,30 @@ import (
2122)
2223
2324var rootCmd = &cobra.Command{
24− Use: "OpenCode",
25− Short: "A terminal AI assistant for software development",
25+ Use: "opencode",
26+ Short: "Terminal-based AI assistant for software development",
2627 Long: `OpenCode is a powerful terminal-based AI assistant that helps with software development tasks.
2728It provides an interactive chat interface with AI capabilities, code analysis, and LSP integration
2829to assist developers in writing, debugging, and understanding code directly from the terminal.`,
30+ Example: `
31+ # Run in interactive mode
32+ opencode
33+
34+ # Run with debug logging
35+ opencode -d
36+
37+ # Run with debug logging in a specific directory
38+ opencode -d -c /path/to/project
39+
40+ # Print version
41+ opencode -v
42+
43+ # Run a single non-interactive prompt
44+ opencode -p "Explain the use of context in Go"
45+
46+ # Run a single non-interactive prompt with JSON output format
47+ opencode -p "Explain the use of context in Go" -f json
48+ `,
2949 RunE: func(cmd *cobra.Command, args []string) error {
3050 // If the help flag is set, show the help message
3151 if cmd.Flag("help").Changed {
@@ -40,6 +60,15 @@ to assist developers in writing, debugging, and understanding code directly from
4060 // Load the config
4161 debug, _ := cmd.Flags().GetBool("debug")
4262 cwd, _ := cmd.Flags().GetString("cwd")
63+ prompt, _ := cmd.Flags().GetString("prompt")
64+ outputFormat, _ := cmd.Flags().GetString("output-format")
65+ quiet, _ := cmd.Flags().GetBool("quiet")
66+
67+ // Validate format option
68+ if !format.IsValid(outputFormat) {
69+ return fmt.Errorf("invalid format option: %s\n%s", outputFormat, format.GetHelpText())
70+ }
71+
4372 if cwd != "" {
4473 err := os.Chdir(cwd)
4574 if err != nil {
@@ -73,7 +102,19 @@ to assist developers in writing, debugging, and understanding code directly from
73102 logging.Error("Failed to create app: %v", err)
74103 return err
75104 }
105+ // Defer shutdown here so it runs for both interactive and non-interactive modes
106+ defer app.Shutdown()
76107
108+ // Initialize MCP tools early for both modes
109+ initMCPTools(ctx, app)
110+
111+ // Non-interactive mode
112+ if prompt != "" {
113+ // Run non-interactive flow using the App method
114+ return app.RunNonInteractive(ctx, prompt, outputFormat, quiet)
115+ }
116+
117+ // Interactive mode
77118 // Set up the TUI
78119 zone.NewGlobal()
79120 program := tea.NewProgram(
@@ -81,9 +122,6 @@ to assist developers in writing, debugging, and understanding code directly from
81122 tea.WithAltScreen(),
82123 )
83124
84− // Initialize MCP tools in the background
85− initMCPTools(ctx, app)
86−
87125 // Setup the subscriptions, this will send services events to the TUI
88126 ch, cancelSubs := setupSubscriptions(app, ctx)
89127
@@ -255,4 +293,17 @@ func init() {
255293 rootCmd.Flags().BoolP("version", "v", false, "Version")
256294 rootCmd.Flags().BoolP("debug", "d", false, "Debug")
257295 rootCmd.Flags().StringP("cwd", "c", "", "Current working directory")
296+ rootCmd.Flags().StringP("prompt", "p", "", "Prompt to run in non-interactive mode")
297+
298+ // Add format flag with validation logic
299+ rootCmd.Flags().StringP("output-format", "f", format.Text.String(),
300+ "Output format for non-interactive mode (text, json)")
301+
302+ // Add quiet flag to hide spinner in non-interactive mode
303+ rootCmd.Flags().BoolP("quiet", "q", false, "Hide spinner in non-interactive mode")
304+
305+ // Register custom validation for the format flag
306+ rootCmd.RegisterFlagCompletionFunc("output-format", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
307+ return format.SupportedFormats, cobra.ShellCompDirectiveNoFileComp
308+ })
258309}