config_cmd.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package cli
  2. import (
  3. "fmt"
  4. "sort"
  5. "github.com/spf13/cobra"
  6. )
  7. func newConfigCmd(app *appState) *cobra.Command {
  8. cmd := &cobra.Command{
  9. Use: "config",
  10. Short: "Inspect or modify global config fields",
  11. }
  12. cmd.AddCommand(
  13. newConfigShowCmd(app),
  14. newConfigSetCmd(app),
  15. newConfigGetCmd(app),
  16. )
  17. return cmd
  18. }
  19. func newConfigShowCmd(app *appState) *cobra.Command {
  20. return &cobra.Command{
  21. Use: "show",
  22. Short: "Print the current config (env values masked)",
  23. RunE: func(cmd *cobra.Command, args []string) error {
  24. fmt.Fprintf(app.stdout, "# %s\n", app.configPath)
  25. // Build a display copy: mask or mark each env value.
  26. type provView struct {
  27. desc string
  28. env map[string]string
  29. }
  30. disp := map[string]provView{}
  31. for n, p := range app.cfg.Providers {
  32. ev := make(map[string]string, len(p.Env))
  33. for k, v := range p.Env {
  34. ev[k] = displayValue(v)
  35. }
  36. disp[n] = provView{desc: p.Description, env: ev}
  37. }
  38. if app.cfg.ClaudePath != "" {
  39. fmt.Fprintf(app.stdout, "claude_path: %s\n", app.cfg.ClaudePath)
  40. }
  41. if app.cfg.DefaultProvider != "" {
  42. fmt.Fprintf(app.stdout, "default_provider: %s\n", app.cfg.DefaultProvider)
  43. }
  44. if len(disp) == 0 {
  45. fmt.Fprintln(app.stdout, "providers: {}")
  46. return nil
  47. }
  48. fmt.Fprintln(app.stdout, "providers:")
  49. names := make([]string, 0, len(disp))
  50. for n := range disp {
  51. names = append(names, n)
  52. }
  53. sort.Strings(names)
  54. for _, n := range names {
  55. v := disp[n]
  56. fmt.Fprintf(app.stdout, " %s:\n", n)
  57. if v.desc != "" {
  58. fmt.Fprintf(app.stdout, " description: %s\n", v.desc)
  59. }
  60. fmt.Fprintln(app.stdout, " env:")
  61. keys := make([]string, 0, len(v.env))
  62. for k := range v.env {
  63. keys = append(keys, k)
  64. }
  65. sort.Strings(keys)
  66. for _, k := range keys {
  67. fmt.Fprintf(app.stdout, " %s: %s\n", k, v.env[k])
  68. }
  69. }
  70. return nil
  71. },
  72. }
  73. }
  74. func newConfigSetCmd(app *appState) *cobra.Command {
  75. cmd := &cobra.Command{
  76. Use: "set <key> <value>",
  77. Short: "Set a top-level config field (claude-path | default)",
  78. Args: cobra.ExactArgs(2),
  79. RunE: func(cmd *cobra.Command, args []string) error {
  80. key, value := args[0], args[1]
  81. switch key {
  82. case "claude-path":
  83. if err := app.cfg.SetClaudePath(value); err != nil {
  84. return err
  85. }
  86. case "default":
  87. if err := app.cfg.SetDefault(value); err != nil {
  88. return err
  89. }
  90. default:
  91. return fmt.Errorf("unknown config key %q (allowed: claude-path, default)", key)
  92. }
  93. if err := app.save(); err != nil {
  94. return err
  95. }
  96. fmt.Fprintf(app.stdout, "set %s\n", key)
  97. return nil
  98. },
  99. }
  100. return cmd
  101. }
  102. func newConfigGetCmd(app *appState) *cobra.Command {
  103. return &cobra.Command{
  104. Use: "get <key>",
  105. Short: "Print a top-level config field (claude-path | default)",
  106. Args: cobra.ExactArgs(1),
  107. RunE: func(cmd *cobra.Command, args []string) error {
  108. switch args[0] {
  109. case "claude-path":
  110. fmt.Fprintln(app.stdout, app.cfg.ClaudePath)
  111. case "default":
  112. fmt.Fprintln(app.stdout, app.cfg.DefaultProvider)
  113. default:
  114. return fmt.Errorf("unknown config key %q (allowed: claude-path, default)", args[0])
  115. }
  116. return nil
  117. },
  118. }
  119. }