@@ -17,6 +17,12 @@ type confirmAction struct {
1717 label string
1818}
1919
20+ // deltaConfirmAction holds state while waiting for the user to confirm a delta action.
21+ type deltaConfirmAction struct {
22+ action branchDeltaAction
23+ label string
24+ }
25+
2026type detailModel struct {
2127 item * commons.WantedItem
2228 completion * commons.CompletionRecord
@@ -31,10 +37,12 @@ type detailModel struct {
3137 dbDir string
3238 rigHandle string
3339 mode string
34- branch string // non-empty when showing branch state
35- confirming * confirmAction // non-nil → showing confirmation prompt
36- executing bool // true → showing spinner
37- executingLabel string // e.g. "Claiming..."
40+ branch string // non-empty when showing branch state
41+ mainStatus string // status on main when showing branch state
42+ confirming * confirmAction // non-nil → showing confirmation prompt
43+ deltaConfirm * deltaConfirmAction // non-nil → showing delta confirmation prompt
44+ executing bool // true → showing spinner
45+ executingLabel string // e.g. "Claiming..."
3846 spinner spinner.Model
3947 result string // brief success/error message
4048}
@@ -70,8 +78,10 @@ func (m *detailModel) setData(msg detailDataMsg) {
7078 m .completion = msg .completion
7179 m .stamp = msg .stamp
7280 m .branch = msg .branch
81+ m .mainStatus = msg .mainStatus
7382 // Clear mutation state so stale results don't mask action hints.
7483 m .confirming = nil
84+ m .deltaConfirm = nil
7585 m .executing = false
7686 m .executingLabel = ""
7787 m .result = ""
@@ -113,6 +123,22 @@ func (m detailModel) update(msg bubbletea.Msg) (detailModel, bubbletea.Cmd) {
113123 return m , nil
114124 }
115125
126+ // Delta confirmation prompt active: handle y/n/esc only.
127+ if m .deltaConfirm != nil {
128+ switch {
129+ case key .Matches (msg , keys .Confirm ):
130+ a := m .deltaConfirm .action
131+ m .deltaConfirm = nil
132+ return m , func () bubbletea.Msg {
133+ return deltaConfirmedMsg {action : a }
134+ }
135+ case key .Matches (msg , keys .Cancel ), key .Matches (msg , keys .Back ):
136+ m .deltaConfirm = nil
137+ return m , nil
138+ }
139+ return m , nil
140+ }
141+
116142 // Normal key handling.
117143 switch {
118144 case key .Matches (msg , keys .Back ):
@@ -139,6 +165,12 @@ func (m detailModel) update(msg bubbletea.Msg) (detailModel, bubbletea.Cmd) {
139165 return m .tryAction (commons .TransitionClose )
140166 case key .Matches (msg , keys .Delete ):
141167 return m .tryAction (commons .TransitionDelete )
168+
169+ // Delta resolution keys.
170+ case key .Matches (msg , keys .Apply ):
171+ return m .tryDelta (deltaApply )
172+ case key .Matches (msg , keys .Discard ):
173+ return m .tryDelta (deltaDiscard )
142174 }
143175 }
144176
@@ -187,6 +219,28 @@ func (m detailModel) tryTextAction(t commons.Transition) (detailModel, bubbletea
187219 return m , nil
188220}
189221
222+ // tryDelta validates that a branch exists, computes a label, and returns a deltaRequestMsg.
223+ func (m detailModel ) tryDelta (action branchDeltaAction ) (detailModel , bubbletea.Cmd ) {
224+ if m .branch == "" || m .item == nil {
225+ return m , nil
226+ }
227+ // Apply is not available in PR mode — deltas resolve via upstream PR merge.
228+ if action == deltaApply && m .mode == "pr" {
229+ return m , nil
230+ }
231+ delta := commons .DeltaLabel (m .mainStatus , m .item .Status )
232+ var label string
233+ switch action {
234+ case deltaApply :
235+ label = fmt .Sprintf ("Apply %s to main? Pushes to origin. [y/n]" , delta )
236+ case deltaDiscard :
237+ label = fmt .Sprintf ("Discard %s? Reverts to %s. Deletes local + remote branch. [y/n]" , delta , m .mainStatus )
238+ }
239+ return m , func () bubbletea.Msg {
240+ return deltaRequestMsg {action : action , label : label }
241+ }
242+ }
243+
190244func (m detailModel ) view () string {
191245 if m .loading {
192246 return styleDim .Render (" Loading..." )
@@ -207,6 +261,9 @@ func (m detailModel) renderContent() string {
207261 var b strings.Builder
208262
209263 b .WriteString (fmt .Sprintf ("\n Status: %s\n " , colorizeStatus (item .Status )))
264+ if m .branch != "" && m .mainStatus != "" && m .mainStatus != item .Status {
265+ b .WriteString (fmt .Sprintf (" Pending: %s → %s\n " , m .mainStatus , item .Status ))
266+ }
210267 if m .branch != "" {
211268 b .WriteString (styleDim .Render (fmt .Sprintf (" Branch: %s\n " , m .branch )))
212269 }
@@ -278,6 +335,8 @@ func (m detailModel) renderContent() string {
278335 case m .confirming != nil :
279336 b .WriteString (styleConfirm .Render (fmt .Sprintf (
280337 " %s Pushes to upstream. [y/n]" , m .confirming .label )))
338+ case m .deltaConfirm != nil :
339+ b .WriteString (styleConfirm .Render (fmt .Sprintf (" %s" , m .deltaConfirm .label )))
281340 case m .executing :
282341 b .WriteString (fmt .Sprintf (" %s %s" , m .spinner .View (), m .executingLabel ))
283342 case m .result != "" :
@@ -308,9 +367,6 @@ func (m detailModel) actionHints() string {
308367 return ""
309368 }
310369 available := commons .AvailableTransitions (m .item , m .rigHandle )
311- if len (available ) == 0 {
312- return " (no actions available)"
313- }
314370 var hints []string
315371 for _ , t := range available {
316372 k := transitionKeyHint [t ]
@@ -321,5 +377,24 @@ func (m detailModel) actionHints() string {
321377 }
322378 hints = append (hints , hint )
323379 }
380+
381+ // Delta actions: only when a branch exists with a pending delta.
382+ if m .branch != "" && m .mainStatus != "" && m .mainStatus != m .item .Status {
383+ delta := commons .DeltaLabel (m .mainStatus , m .item .Status )
384+ var deltaHints []string
385+ if m .mode != "pr" {
386+ // Apply only in wild-west mode — PR mode resolves via upstream PR.
387+ deltaHints = append (deltaHints , fmt .Sprintf ("M:apply %s" , delta ))
388+ }
389+ deltaHints = append (deltaHints , fmt .Sprintf ("b:discard (→ %s)" , m .mainStatus ))
390+ if len (hints ) > 0 {
391+ hints = append (hints , "|" )
392+ }
393+ hints = append (hints , deltaHints ... )
394+ }
395+
396+ if len (hints ) == 0 {
397+ return " (no actions available)"
398+ }
324399 return " Actions: " + strings .Join (hints , " " )
325400}
0 commit comments