diff --git a/cmd/surf/compat_flags_test.go b/cmd/surf/compat_flags_test.go new file mode 100644 index 0000000..afe802f --- /dev/null +++ b/cmd/surf/compat_flags_test.go @@ -0,0 +1,49 @@ +package main + +import ( + "testing" + + "github.com/spf13/cobra" +) + +func TestHiddenCompatRootFlags(t *testing.T) { + root := &cobra.Command{Use: "surf"} + addHiddenCompatRootFlags(root) + + f := root.PersistentFlags().Lookup("agent-view") + if f == nil { + t.Fatal("expected hidden --agent-view compatibility flag") + } + if !f.Hidden { + t.Fatal("--agent-view should be hidden") + } +} + +func TestSearchWebQueryCompatAlias(t *testing.T) { + cmd := &cobra.Command{ + Use: "search-web", + Run: func(cmd *cobra.Command, args []string) {}, + } + cmd.Flags().String("q", "", "query") + addHiddenCompatOperationFlags(cmd) + + f := cmd.Flags().Lookup("query") + if f == nil { + t.Fatal("expected hidden --query compatibility alias") + } + if !f.Hidden { + t.Fatal("--query should be hidden") + } + + cmd.SetArgs([]string{"--query", "bitcoin"}) + if err := cmd.Execute(); err != nil { + t.Fatalf("execute failed: %v", err) + } + q, err := cmd.Flags().GetString("q") + if err != nil { + t.Fatalf("get q: %v", err) + } + if q != "bitcoin" { + t.Fatalf("expected --query to populate --q, got %q", q) + } +} diff --git a/cmd/surf/main.go b/cmd/surf/main.go index 970ade0..1d3b318 100644 --- a/cmd/surf/main.go +++ b/cmd/surf/main.go @@ -94,6 +94,7 @@ func main() { cli.Root.PersistentFlags().Bool("json", false, "Output result as JSON (alias for -o json)") cli.Root.PersistentFlags().Bool("debug", false, "Enable debug log output") cli.Root.PersistentFlags().Bool("quiet", false, "Suppress non-error diagnostic output") + addHiddenCompatRootFlags(cli.Root) // Add -v as shorthand for --version. Cobra auto-registers --version // (from Root.Version) but without a short flag. @@ -214,6 +215,7 @@ func main() { } cmd := op.Command() cmd.GroupID = "api" + addHiddenCompatOperationFlags(cmd) cli.Root.AddCommand(cmd) } } @@ -245,6 +247,40 @@ func main() { os.Exit(exitCode) } +func addHiddenCompatRootFlags(root *cobra.Command) { + root.PersistentFlags().String("agent-view", "", "Compatibility no-op for legacy instant skill examples") + _ = root.PersistentFlags().MarkHidden("agent-view") +} + +func addHiddenCompatOperationFlags(cmd *cobra.Command) { + if cmd.Name() != "search-web" { + return + } + + var queryAlias string + cmd.Flags().StringVar(&queryAlias, "query", "", "Alias for --q (hidden compatibility)") + _ = cmd.Flags().MarkHidden("query") + + origPreRun := cmd.PreRun + origPreRunE := cmd.PreRunE + cmd.PreRunE = func(c *cobra.Command, args []string) error { + if f := c.Flags().Lookup("query"); f != nil && f.Changed { + if qf := c.Flags().Lookup("q"); qf != nil && !qf.Changed { + if err := c.Flags().Set("q", queryAlias); err != nil { + return err + } + } + } + if origPreRunE != nil { + return origPreRunE(c, args) + } + if origPreRun != nil { + origPreRun(c, args) + } + return nil + } +} + // needsCachedAPI reports whether the current argv invokes a command that // requires the cached OpenAPI spec. Meta commands (auth, sync, help, version, // install, completion, telemetry, feedback, catalog) work without it.