@@ -5,22 +5,20 @@ import (
55 "os/exec"
66
77 "github.com/openbootdotdev/openboot/internal/auth"
8- syncpkg "github.com/openbootdotdev/openboot/internal/sync"
98 "github.com/openbootdotdev/openboot/internal/ui"
109 "github.com/spf13/cobra"
1110)
1211
1312var editCmd = & cobra.Command {
1413 Use : "edit" ,
15- Short : "Open your config on openboot.dev in the browser" ,
16- Long : `Open your remote config on openboot.dev in the default browser.
14+ Short : "Open a config on openboot.dev in the browser" ,
15+ Long : `Pick a config from your openboot.dev account and open it in the browser.
1716
18- Resolves the config slug from the current sync source (set when you last ran
19- 'openboot install' or 'openboot push'). Use --slug to open a specific config.` ,
20- Example : ` # Open your linked config in the browser
17+ Use --slug to skip the picker and open a specific config directly.` ,
18+ Example : ` # Pick a config interactively
2119 openboot edit
2220
23- # Open a specific config
21+ # Open a specific config directly
2422 openboot edit --slug my-config` ,
2523 SilenceUsage : true ,
2624 RunE : func (cmd * cobra.Command , args []string ) error {
@@ -30,7 +28,7 @@ Resolves the config slug from the current sync source (set when you last ran
3028}
3129
3230func init () {
33- editCmd .Flags ().String ("slug" , "" , "config slug to open (default: current sync source )" )
31+ editCmd .Flags ().String ("slug" , "" , "config slug to open (skips the picker )" )
3432 rootCmd .AddCommand (editCmd )
3533}
3634
@@ -49,12 +47,14 @@ func runEdit(slugOverride string) error {
4947
5048 slug := slugOverride
5149 if slug == "" {
52- if source , loadErr := syncpkg .LoadSource (); loadErr == nil && source != nil && source .Slug != "" {
53- slug = source .Slug
50+ slug , err = pickConfig (stored .Token , auth .GetAPIBase ())
51+ if err != nil {
52+ return err
53+ }
54+ if slug == "" {
55+ ui .Info ("No config selected." )
56+ return nil
5457 }
55- }
56- if slug == "" {
57- return fmt .Errorf ("no config slug — use --slug or run 'openboot install <config>' first" )
5858 }
5959
6060 url := fmt .Sprintf ("https://openboot.dev/%s/%s" , stored .Username , slug )
@@ -66,3 +66,41 @@ func runEdit(slugOverride string) error {
6666 ui .Success (fmt .Sprintf ("Opened %s" , url ))
6767 return nil
6868}
69+
70+ // pickConfig fetches the user's configs and shows an interactive select list.
71+ // Returns the chosen slug, or "" if the user has no configs.
72+ func pickConfig (token , apiBase string ) (string , error ) {
73+ configs , _ := fetchUserConfigs (token , apiBase )
74+
75+ if len (configs ) == 0 {
76+ return "" , fmt .Errorf ("no configs found — run 'openboot push' to create one" )
77+ }
78+
79+ options := make ([]string , 0 , len (configs ))
80+ for _ , c := range configs {
81+ label := c .Slug
82+ if c .Name != "" && c .Name != c .Slug {
83+ label = fmt .Sprintf ("%s — %s" , c .Slug , c .Name )
84+ }
85+ options = append (options , label )
86+ }
87+
88+ fmt .Println ()
89+ choice , err := ui .SelectOption ("Which config would you like to edit?" , options )
90+ if err != nil {
91+ return "" , fmt .Errorf ("select config: %w" , err )
92+ }
93+
94+ // Extract slug from "slug — Name" label
95+ slug := splitBefore (choice , " — " )
96+ return slug , nil
97+ }
98+
99+ func splitBefore (s , sep string ) string {
100+ for i := 0 ; i < len (s )- len (sep )+ 1 ; i ++ {
101+ if s [i :i + len (sep )] == sep {
102+ return s [:i ]
103+ }
104+ }
105+ return s
106+ }
0 commit comments