diff --git a/shortcuts/common/runner.go b/shortcuts/common/runner.go index d6f4c1a5d..55bfd274e 100644 --- a/shortcuts/common/runner.go +++ b/shortcuts/common/runner.go @@ -842,9 +842,7 @@ func newRuntimeContext(cmd *cobra.Command, f *cmdutil.Factory, s *Shortcut, conf } rctx.larkSDK = sdk - if s.HasFormat { - rctx.Format = rctx.Str("format") - } + rctx.Format = rctx.Str("format") rctx.JqExpr, _ = cmd.Flags().GetString("jq") return rctx, nil } @@ -1008,17 +1006,15 @@ func registerShortcutFlagsWithContext(ctx context.Context, cmd *cobra.Command, f } cmd.Flags().Bool("dry-run", false, "print request without executing") - if s.HasFormat { + if cmd.Flags().Lookup("format") == nil { cmd.Flags().String("format", "json", "output format: json (default) | pretty | table | ndjson | csv") + cmdutil.RegisterFlagCompletion(cmd, "format", func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { + return []string{"json", "pretty", "table", "ndjson", "csv"}, cobra.ShellCompDirectiveNoFileComp + }) } if s.Risk == "high-risk-write" { cmd.Flags().Bool("yes", false, "confirm high-risk operation") } cmd.Flags().StringP("jq", "q", "", "jq expression to filter JSON output") cmdutil.AddShortcutIdentityFlag(ctx, cmd, f, s.AuthTypes) - if s.HasFormat { - cmdutil.RegisterFlagCompletion(cmd, "format", func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { - return []string{"json", "pretty", "table", "ndjson", "csv"}, cobra.ShellCompDirectiveNoFileComp - }) - } } diff --git a/shortcuts/common/runner_format_universal_test.go b/shortcuts/common/runner_format_universal_test.go new file mode 100644 index 000000000..777cd2e47 --- /dev/null +++ b/shortcuts/common/runner_format_universal_test.go @@ -0,0 +1,39 @@ +// Copyright (c) 2026 Lark Technologies Pte. Ltd. +// SPDX-License-Identifier: MIT + +package common + +import ( + "context" + "testing" + + "github.com/larksuite/cli/internal/cmdutil" + "github.com/spf13/cobra" +) + +// TestShortcutMount_FormatFlagAlwaysRegistered verifies that --format is +// injected for every shortcut regardless of the HasFormat field value. +func TestShortcutMount_FormatFlagAlwaysRegistered(t *testing.T) { + f, _, _, _ := cmdutil.TestFactory(t, nil) + parent := &cobra.Command{Use: "root"} + shortcut := Shortcut{ + Service: "im", + Command: "+message-send", + Description: "send message", + HasFormat: false, // explicitly false — format must still be registered + Execute: func(context.Context, *RuntimeContext) error { return nil }, + } + shortcut.Mount(parent, f) + + cmd, _, err := parent.Find([]string{"+message-send"}) + if err != nil { + t.Fatalf("Find() error = %v", err) + } + flag := cmd.Flags().Lookup("format") + if flag == nil { + t.Fatal("--format flag not registered; expected it to be injected even when HasFormat is false") + } + if flag.DefValue != "json" { + t.Errorf("--format default = %q, want %q", flag.DefValue, "json") + } +} diff --git a/shortcuts/common/types.go b/shortcuts/common/types.go index 76626c06c..bf3f0307b 100644 --- a/shortcuts/common/types.go +++ b/shortcuts/common/types.go @@ -49,7 +49,7 @@ type Shortcut struct { // Declarative fields (new framework). AuthTypes []string // supported identities: "user", "bot" (default: ["user"]) Flags []Flag // flag definitions; --dry-run is auto-injected - HasFormat bool // auto-inject --format flag (json|pretty|table|ndjson|csv) + HasFormat bool // Deprecated: --format is now always injected; this field has no effect. Tips []string // optional tips shown in --help output Hidden bool // hide from --help / tab completion (still executable); use when deprecating a command in favor of a replacement