Show note when command preview may be incomplete

Amolith created

When the confirm screen is shown for a command with no dedicated TUI
screens (e.g. backup), append a note explaining that the preview may be
incomplete and additional prompts may follow. Points the user to
--show-command for the final resolved command.

Change summary

cmd/root.go                         |  7 +++++
internal/ui/screens/confirm.go      | 23 +++++++++++++++++-
internal/ui/screens/confirm_test.go | 38 +++++++++++++++++++++++++++++++
3 files changed, 66 insertions(+), 2 deletions(-)

Detailed changes

cmd/root.go 🔗

@@ -283,6 +283,13 @@ func runInteractive(preselectedCommand string) (command, preset string, override
 		}
 		confirmScreen := screens.NewConfirm(previewFn, flagShowCmd)
 
+		// When the command has no dedicated TUI screens, the
+		// preview may be incomplete — additional prompts can
+		// follow after confirmation.
+		if cmdScreens == nil {
+			confirmScreen.SetPartial(true)
+		}
+
 		var result []ui.Screen
 		if cmdScreens != nil {
 			result = append(result, cmdScreens.list...)

internal/ui/screens/confirm.go 🔗

@@ -27,6 +27,7 @@ type previewMsg struct {
 type Confirm struct {
 	previewFn   PreviewFunc
 	showCommand bool
+	partial     bool
 	preview     string
 	selection   string
 }
@@ -75,11 +76,25 @@ func (c *Confirm) Update(msg tea.Msg) (ui.Screen, tea.Cmd) {
 	return c, nil
 }
 
-// View renders the command preview.
+// View renders the command preview. When partial is set, a note
+// is appended explaining the preview may be incomplete.
 func (c *Confirm) View() string {
-	return c.preview
+	if c.preview == "" {
+		return ""
+	}
+	if !c.partial {
+		return c.preview
+	}
+	return c.preview + "\n" + partialNote
 }
 
+// partialNote is shown below the preview when the command has no
+// dedicated TUI screens, meaning the session could not collect all
+// inputs interactively.
+const partialNote = "Note: this preview may be incomplete. " +
+	"Additional prompts may follow after confirmation.\n" +
+	"Use --show-command to see the final command after all inputs are collected."
+
 // Title returns the screen's display title.
 func (c *Confirm) Title() string { return "Confirm execution" }
 
@@ -90,6 +105,10 @@ func (c *Confirm) KeyBindings() []key.Binding {
 	}
 }
 
+// SetPartial marks the preview as potentially incomplete because
+// the command has no dedicated TUI screens to collect all inputs.
+func (c *Confirm) SetPartial(partial bool) { c.partial = partial }
+
 // Selection returns "confirmed" after the user presses Enter, or ""
 // if the screen has not been confirmed yet.
 func (c *Confirm) Selection() string { return c.selection }

internal/ui/screens/confirm_test.go 🔗

@@ -182,6 +182,44 @@ func TestConfirmViewEmptyBeforeInit(t *testing.T) {
 	}
 }
 
+func TestConfirmPartialShowsNote(t *testing.T) {
+	t.Parallel()
+
+	c := NewConfirm(func() string { return "command: restic backup\n" }, false)
+	c.SetPartial(true)
+
+	cmd := c.Init()
+	if cmd != nil {
+		msg := cmd()
+		c.Update(msg)
+	}
+
+	view := c.View()
+	if !strings.Contains(view, "may be incomplete") {
+		t.Errorf("partial View() missing incomplete note; got:\n%s", view)
+	}
+	if !strings.Contains(view, "--show-command") {
+		t.Errorf("partial View() missing --show-command hint; got:\n%s", view)
+	}
+}
+
+func TestConfirmNonPartialOmitsNote(t *testing.T) {
+	t.Parallel()
+
+	c := NewConfirm(func() string { return "command: restic backup\n" }, false)
+
+	cmd := c.Init()
+	if cmd != nil {
+		msg := cmd()
+		c.Update(msg)
+	}
+
+	view := c.View()
+	if strings.Contains(view, "may be incomplete") {
+		t.Errorf("non-partial View() should not contain incomplete note; got:\n%s", view)
+	}
+}
+
 func TestConfirmReinitAfterBack(t *testing.T) {
 	t.Parallel()