Skip to content

Commit 606537e

Browse files
committed
Default to running the default agent when no subcommand is given
When invoked without a subcommand (e.g. bare "cagent" or "cagent --debug"), automatically prepend "run" so the default agent is launched. Users can still use "cagent --help" to list available commands. Assisted-By: cagent
1 parent e1e8a8e commit 606537e

2 files changed

Lines changed: 140 additions & 0 deletions

File tree

cmd/root/root.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@ We collect anonymous usage data to help improve cagent. To disable:
147147
}
148148

149149
rootCmd := NewRootCmd()
150+
151+
// When no subcommand is given, default to "run" (which runs the default agent).
152+
// Users can use "cagent --help" to see available commands.
153+
args = defaultToRun(rootCmd, args)
154+
150155
rootCmd.SetArgs(args)
151156
rootCmd.SetIn(stdin)
152157
rootCmd.SetOut(stdout)
@@ -182,6 +187,42 @@ We collect anonymous usage data to help improve cagent. To disable:
182187
return nil
183188
}
184189

190+
// defaultToRun prepends "run" to the argument list when no subcommand is
191+
// specified so that bare "cagent" (or "cagent --debug", etc.) launches the
192+
// default agent. Help flags (--help / -h) are left alone.
193+
func defaultToRun(rootCmd *cobra.Command, args []string) []string {
194+
for _, arg := range args {
195+
switch {
196+
case arg == "--":
197+
// End of flags – no subcommand found.
198+
return append([]string{"run"}, args...)
199+
case arg == "--help" || arg == "-h":
200+
return args
201+
case strings.HasPrefix(arg, "-"):
202+
continue
203+
case isSubcommand(rootCmd, arg):
204+
return args
205+
default:
206+
return append([]string{"run"}, args...)
207+
}
208+
}
209+
210+
return append([]string{"run"}, args...)
211+
}
212+
213+
// isSubcommand reports whether name matches a registered subcommand or alias.
214+
func isSubcommand(cmd *cobra.Command, name string) bool {
215+
if name == "help" {
216+
return true
217+
}
218+
for _, sub := range cmd.Commands() {
219+
if sub.Name() == name || sub.HasAlias(name) {
220+
return true
221+
}
222+
}
223+
return false
224+
}
225+
185226
func processErr(ctx context.Context, err error, stderr io.Writer, rootCmd *cobra.Command) error {
186227
if ctx.Err() != nil {
187228
return ctx.Err()

cmd/root/root_test.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package root
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestDefaultToRun(t *testing.T) {
10+
t.Parallel()
11+
12+
rootCmd := NewRootCmd()
13+
14+
tests := []struct {
15+
name string
16+
args []string
17+
want []string
18+
}{
19+
{
20+
name: "no args defaults to run",
21+
args: []string{},
22+
want: []string{"run"},
23+
},
24+
{
25+
name: "nil args defaults to run",
26+
args: nil,
27+
want: []string{"run"},
28+
},
29+
{
30+
name: "known subcommand kept as-is",
31+
args: []string{"version"},
32+
want: []string{"version"},
33+
},
34+
{
35+
name: "run subcommand kept as-is",
36+
args: []string{"run", "./agent.yaml"},
37+
want: []string{"run", "./agent.yaml"},
38+
},
39+
{
40+
name: "help subcommand kept as-is",
41+
args: []string{"help"},
42+
want: []string{"help"},
43+
},
44+
{
45+
name: "--help flag kept as-is",
46+
args: []string{"--help"},
47+
want: []string{"--help"},
48+
},
49+
{
50+
name: "-h flag kept as-is",
51+
args: []string{"-h"},
52+
want: []string{"-h"},
53+
},
54+
{
55+
name: "only flags defaults to run",
56+
args: []string{"--debug"},
57+
want: []string{"run", "--debug"},
58+
},
59+
{
60+
name: "flags with agent file defaults to run",
61+
args: []string{"--debug", "./agent.yaml"},
62+
want: []string{"run", "--debug", "./agent.yaml"},
63+
},
64+
{
65+
name: "agent file without subcommand defaults to run",
66+
args: []string{"./agent.yaml"},
67+
want: []string{"run", "./agent.yaml"},
68+
},
69+
{
70+
name: "new subcommand kept as-is",
71+
args: []string{"new"},
72+
want: []string{"new"},
73+
},
74+
{
75+
name: "serve subcommand kept as-is",
76+
args: []string{"serve", "mcp", "./agent.yaml"},
77+
want: []string{"serve", "mcp", "./agent.yaml"},
78+
},
79+
{
80+
name: "debug and help still shows help",
81+
args: []string{"--debug", "--help"},
82+
want: []string{"--debug", "--help"},
83+
},
84+
{
85+
name: "agent file with flags defaults to run",
86+
args: []string{"./agent.yaml", "--yolo"},
87+
want: []string{"run", "./agent.yaml", "--yolo"},
88+
},
89+
}
90+
91+
for _, tt := range tests {
92+
t.Run(tt.name, func(t *testing.T) {
93+
t.Parallel()
94+
95+
got := defaultToRun(rootCmd, tt.args)
96+
assert.Equal(t, tt.want, got)
97+
})
98+
}
99+
}

0 commit comments

Comments
 (0)