@@ -108,6 +108,49 @@ func runInit(cfg *config.Config, opts *initOptions) error {
108108 return ErrInvalidArgs
109109 }
110110
111+ // Prompt for prefix interactively if not provided via flag and we're
112+ // in interactive mode (not adopt, not explicit branches).
113+ if opts .prefix == "" && ! opts .adopt && len (opts .branches ) == 0 && cfg .IsInteractive () {
114+ p := prompter .New (cfg .In , cfg .Out , cfg .Err )
115+ if opts .numbered {
116+ // --numbered requires a prefix; prompt specifically for one
117+ prefixInput , err := p .Input ("Enter a branch prefix (required for --numbered)" , "" )
118+ if err != nil {
119+ if isInterruptError (err ) {
120+ printInterrupt (cfg )
121+ return ErrSilent
122+ }
123+ cfg .Errorf ("failed to read prefix: %s" , err )
124+ return ErrSilent
125+ }
126+ opts .prefix = strings .TrimSpace (prefixInput )
127+ if opts .prefix == "" {
128+ cfg .Errorf ("--numbered requires a prefix" )
129+ return ErrInvalidArgs
130+ }
131+ } else {
132+ prefixInput , err := p .Input ("Set a branch prefix? (leave blank to skip)" , "" )
133+ if err != nil {
134+ if isInterruptError (err ) {
135+ printInterrupt (cfg )
136+ return ErrSilent
137+ }
138+ cfg .Errorf ("failed to read prefix: %s" , err )
139+ return ErrSilent
140+ }
141+ opts .prefix = strings .TrimSpace (prefixInput )
142+ }
143+ }
144+
145+ // Validate prefix, after it has been determined (from flag or prompt),
146+ // before any branch creation.
147+ if opts .prefix != "" {
148+ if err := git .ValidateRefName (opts .prefix ); err != nil {
149+ cfg .Errorf ("invalid prefix %q: must be a valid git ref component" , opts .prefix )
150+ return ErrInvalidArgs
151+ }
152+ }
153+
111154 if opts .adopt {
112155 // Adopt mode: validate all specified branches exist
113156 if len (opts .branches ) == 0 {
@@ -165,46 +208,13 @@ func runInit(cfg *config.Config, opts *initOptions) error {
165208 }
166209 branches = prefixed
167210 } else {
168- // Interactive mode
211+ // Interactive mode — prefix was already prompted for above
169212 if ! cfg .IsInteractive () {
170213 cfg .Errorf ("interactive input required; provide branch names or use --adopt" )
171214 return ErrInvalidArgs
172215 }
173216 p := prompter .New (cfg .In , cfg .Out , cfg .Err )
174217
175- // Step 1: Ask for prefix
176- if opts .prefix == "" {
177- if opts .numbered {
178- // --numbered requires a prefix; prompt specifically for one
179- prefixInput , err := p .Input ("Enter a branch prefix (required for --numbered)" , "" )
180- if err != nil {
181- if isInterruptError (err ) {
182- printInterrupt (cfg )
183- return ErrSilent
184- }
185- cfg .Errorf ("failed to read prefix: %s" , err )
186- return ErrSilent
187- }
188- opts .prefix = strings .TrimSpace (prefixInput )
189- if opts .prefix == "" {
190- cfg .Errorf ("--numbered requires a prefix" )
191- return ErrInvalidArgs
192- }
193- } else {
194- prefixInput , err := p .Input ("Set a branch prefix? (leave blank to skip)" , "" )
195- if err != nil {
196- if isInterruptError (err ) {
197- printInterrupt (cfg )
198- return ErrSilent
199- }
200- cfg .Errorf ("failed to read prefix: %s" , err )
201- return ErrSilent
202- }
203- opts .prefix = strings .TrimSpace (prefixInput )
204- }
205- }
206-
207- // Step 2: Ask for branch name (unless --numbered auto-generates it)
208218 if opts .numbered {
209219 // Auto-generate numbered branch name
210220 branchName := branch .NextNumberedName (opts .prefix , nil )
@@ -283,14 +293,6 @@ func runInit(cfg *config.Config, opts *initOptions) error {
283293 }
284294 }
285295
286- // Validate prefix (from flag or interactive input)
287- if opts .prefix != "" {
288- if err := git .ValidateRefName (opts .prefix ); err != nil {
289- cfg .Errorf ("invalid prefix %q: must be a valid git ref component" , opts .prefix )
290- return ErrInvalidArgs
291- }
292- }
293-
294296 // Build stack
295297 trunkSHA , _ := git .RevParse (trunk )
296298 branchRefs := make ([]stack.BranchRef , len (branches ))
0 commit comments