@@ -211,12 +211,15 @@ type ActionOutcome struct {
211211 // (mutations.go), the apply-updates batch's confirm-time body, populates
212212 // this today - one "✓ <name> <from> → <to>" line per successful update,
213213 // one "✗ <name>: <error>" line per failed one, in the SAME order the
214- // batch was applied. Every other ActionProvider call leaves this nil,
215- // same as ImportedProfile's own "" zero value above - app.go's
216- // actionDoneMsg handler treats a nil/empty ResultLines as "nothing to
217- // show" and opens no overlay for it. This is a TUI-side struct, not part
218- // of the ActionProvider interface itself, so adding it required no
219- // interface/method change on either provider (coreProvider/
214+ // batch was applied, plus (#259) one trailing section - a blank
215+ // separator, then one line per distinct success-emitted warning - when
216+ // any successful update carried Warnings (see applyUpdatesSequentially's
217+ // doc comment for why they must ride here). Every other ActionProvider
218+ // call leaves this nil, same as ImportedProfile's own "" zero value
219+ // above - app.go's actionDoneMsg handler treats a nil/empty ResultLines
220+ // as "nothing to show" and opens no overlay for it. This is a TUI-side
221+ // struct, not part of the ActionProvider interface itself, so adding it
222+ // required no interface/method change on either provider (coreProvider/
220223 // prototypeProvider): renderers besides the update batch's are free to
221224 // ignore it entirely.
222225 ResultLines []string
@@ -450,26 +453,36 @@ func (p *prototypeProvider) UninstallMod(_ context.Context, item ModItem) (Actio
450453 return ActionOutcome {Message : fmt .Sprintf ("Uninstalled %q" , item .Name )}, nil
451454}
452455
456+ // prototypeMergeWarnings returns the canned merge-time diagnostics (#253),
457+ // surfaced on every prototype deploy AND every successful prototype update
458+ // (#259) so --prototype demo mode actually exercises both multi-warning
459+ // paths in actionDoneMsg (app.go): the auto-open warnings overlay (deploy)
460+ // and the update-results overlay's trailing warnings section (update batch -
461+ // applyUpdatesSequentially). Same rationale as prototypeAllSourcesWarning
462+ // (service.go): without these, no prototype mutation ever crosses
463+ // formatOutcomeStatus's "> 1" collapse threshold, leaving those states
464+ // unreachable in the one mode meant to demo every UI state. The strings
465+ // exist purely to exercise the rendering paths; they name assets no canned
466+ // mod actually bundles. Deliberately IDENTICAL on every call - like the real
467+ // profile-level merge diagnostics a per-update recompile re-emits verbatim -
468+ // so a multi-update prototype batch also demos the section's exact-text
469+ // dedupe (one section, not one copy per mod). Returns a fresh slice per
470+ // call so no caller ever aliases another outcome's Warnings.
471+ func prototypeMergeWarnings () []string {
472+ return []string {
473+ `asset "textures/armor/steel.dds" is bundled by both SkyUI and Ordinator - Ordinator wins (last-applied, per profile load order)` ,
474+ `asset "textures/armor/steel_n.dds" is bundled by both SkyUI and Ordinator - Ordinator wins (last-applied, per profile load order)` ,
475+ }
476+ }
477+
453478func (p * prototypeProvider ) DeployProfile (_ context.Context ) (ActionOutcome , error ) {
454479 deployed := 0
455480 for _ , mod := range p .activeMods () {
456481 if mod .Status != "disabled" {
457482 deployed ++
458483 }
459484 }
460- // Canned merge-time diagnostics (#253), surfaced on every prototype
461- // deploy so --prototype demo mode actually exercises the multi-warning
462- // auto-open overlay path (actionDoneMsg, app.go) - the same rationale as
463- // prototypeAllSourcesWarning (service.go): without these, no prototype
464- // mutation ever crosses formatOutcomeStatus's "> 1" collapse threshold,
465- // leaving the overlay unreachable in the one mode meant to demo every UI
466- // state. Like that constant, the strings exist purely to exercise the
467- // rendering path; they name assets no canned mod actually bundles.
468- warnings := []string {
469- `asset "textures/armor/steel.dds" is bundled by both SkyUI and Ordinator - Ordinator wins (last-applied, per profile load order)` ,
470- `asset "textures/armor/steel_n.dds" is bundled by both SkyUI and Ordinator - Ordinator wins (last-applied, per profile load order)` ,
471- }
472- return ActionOutcome {Message : fmt .Sprintf ("Deployed %d mod(s)" , deployed ), Warnings : warnings }, nil
485+ return ActionOutcome {Message : fmt .Sprintf ("Deployed %d mod(s)" , deployed ), Warnings : prototypeMergeWarnings ()}, nil
473486}
474487
475488// activeProfileName returns the canned Profiles entry currently marked
@@ -784,7 +797,9 @@ func (p *prototypeProvider) CheckUpdates(_ context.Context) (UpdatesView, error)
784797// ApplyUpdate emits the brief's own fake progress sequence, then bumps the
785798// matching InstalledMods entry's Version to u.ToVersion and clears its
786799// AvailableVersion - so a repeated CheckUpdates no longer reports it,
787- // mirroring a real update's "already up to date" outcome.
800+ // mirroring a real update's "already up to date" outcome. The canned merge
801+ // warnings demo #259's results-overlay warnings section - see
802+ // prototypeMergeWarnings' doc comment.
788803func (p * prototypeProvider ) ApplyUpdate (_ context.Context , u UpdateItem , progress func (ActionProgress )) (ActionOutcome , error ) {
789804 idx := p .findInstalledIndex (u .Source , u .ID )
790805 if idx < 0 {
@@ -798,7 +813,7 @@ func (p *prototypeProvider) ApplyUpdate(_ context.Context, u UpdateItem, progres
798813 mods [idx ].AvailableVersion = ""
799814 mods [idx ].Status = "installed"
800815
801- return ActionOutcome {Message : fmt .Sprintf ("Updated %q to %s" , u .Name , u .ToVersion )}, nil
816+ return ActionOutcome {Message : fmt .Sprintf ("Updated %q to %s" , u .Name , u .ToVersion ), Warnings : prototypeMergeWarnings () }, nil
802817}
803818
804819// isValidUpdatePolicy reports whether policy is one of the three strings
0 commit comments