Skip to content

Simplify update notification flow#159

Open
gtsiolis wants to merge 3 commits intomainfrom
george/des-183
Open

Simplify update notification flow#159
gtsiolis wants to merge 3 commits intomainfrom
george/des-183

Conversation

@gtsiolis
Copy link
Copy Markdown
Member

@gtsiolis gtsiolis commented Mar 23, 2026

This PR simplifies the update notification flow and removes the "Never ask again" option.

Users now see a cleaner three-option prompt: Update now [U], Remind me next time [R], Skip this version [S].

The "Skip" option no longer persists - users will be reminded again on next run.

Changes

Update Notification

  • Removed SkippedVersion field from NotifyOptions (no longer persisting skipped versions)
  • Removed PersistSkipVersion callback from NotifyOptions
  • Removed the "Never ask again [N]" option from the prompt
  • Reduced version check timeout from 5s to 2s
  • Simplified skip handling to just emit a note without persisting preference

Config Schema

  • Removed update_skipped_version field from CLIConfig struct
  • Removed SetUpdateSkippedVersion() and GetUpdateSkippedVersion() functions
  • Removed legacy config migration code for old update_prompt and update_skipped_version keys at root level
  • Removed update_prompt = true from default config template (true is already the default via viper)

UI Improvements

  • Added Vertical field to UserInputRequestEvent to explicitly indicate vertical layout
  • Replaced string parsing (strings.Contains(options[0].Label, "[")) with explicit boolean field
  • Extracted handleVerticalPromptKey() method from Update() to reduce complexity
  • Removed update-specific text rendering from generic formatResolvedInput() function
  • UI code no longer contains hard-coded update prompts like "Updating lstk..." or "Won't ask again"
BEFORE AFTER
Screenshot 2026-03-23 at 10 38 51 Screenshot 2026-03-23 at 14 42 39

@gtsiolis
Copy link
Copy Markdown
Member Author

Could you take a look since you added #136, @silv-io?

Comments or commits, welcome!

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 23, 2026

📝 Walkthrough

Walkthrough

The changes reorganize the update prompt config from root level to a new CLI config section with backward-compatibility migration, introduce vertical prompt navigation in the UI with keyboard selection controls, simplify the NotifyOptions struct, and update notification text and available options from u/s/n to u/r/s.

Changes

Cohort / File(s) Summary
Config Restructuring
cmd/root.go, internal/config/config.go, test/integration/update_test.go
Moved UpdatePrompt field from root Config to new CLIConfig struct under cli mapstructure key; added backward-compatibility bridge in Get() to migrate legacy update_prompt values; updated config defaulting and DisableUpdatePrompt() to use new path; integration tests updated to write [cli] section in TOML.
Vertical Prompt UI
internal/ui/components/input_prompt.go, internal/ui/app.go, internal/ui/components/input_prompt_test.go, internal/ui/app_test.go
Added vertical-mode support to InputPrompt with selectedIndex and vertical state; extended Show() signature to accept vertical boolean; new viewVertical() rendering with filled/empty markers; added handleVerticalPromptKey() in App.Update for KeyUp/KeyDown/KeyEnter navigation and selection; added test coverage for vertical selection flow.
Update Notification Flow
internal/update/notify.go, internal/update/notify_test.go, internal/update/github.go
Simplified NotifyOptions by removing PersistDisable field; increased quiet check timeout from 500ms to 2s; updated prompt to show new message, release URL, and options u (update), r (remind), s (skip); added fetchLatestRelease() helper; updated tests to reflect new option keys and prompt assertions.
Event Structure
internal/output/events.go
Added Vertical boolean field to UserInputRequestEvent to signal vertical-mode prompts downstream.
Minor Updates
internal/ui/components/message.go, test/integration/start_test.go
Added blank line formatting in RenderWrappedMessage; strengthened HTTP response body close error handling in integration tests via wrapped defer closure.

Sequence Diagram

sequenceDiagram
    participant User
    participant App as App.Update
    participant InputPrompt as InputPrompt
    participant UI as UI Renderer

    User->>App: Send tea.KeyDown
    App->>InputPrompt: handleVerticalPromptKey() detects KeyDown
    InputPrompt->>InputPrompt: SetSelectedIndex(current + 1)
    InputPrompt->>UI: View() renders with filled marker at new index
    UI-->>User: Display updated vertical prompt

    User->>App: Send tea.KeyEnter
    App->>InputPrompt: handleVerticalPromptKey() detects KeyEnter
    InputPrompt->>InputPrompt: Get option at selectedIndex
    InputPrompt->>App: Send InputResponse with SelectedKey
    App->>InputPrompt: Clear and hide prompt
    UI-->>User: Prompt disappears, selection confirmed
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly Related PRs

Suggested Reviewers

  • silv-io
  • anisaoshafi
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main objective: simplifying the update notification flow, which is the primary change across multiple files in the changeset.
Description check ✅ Passed The description is directly related to the changeset, providing detailed context about the simplification of update notification flow, removal of persistence options, and UI improvements with before/after screenshots.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch george/des-183

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/update/notify_test.go (1)

129-142: ⚠️ Potential issue | 🟠 Major

Exercise the actual skip branch and isolate config writes.

Using "n" here hits config.DisableUpdatePrompt(), not the per-version skip path the test name describes. Because the test doesn't redirect config home/path first, that branch can also mutate the runner's real lstk config. Please set up a temp config like TestNotifyUpdateSkippedVersion, send "s", and assert that update_skipped_version was persisted.

Based on learnings, "Viper uses TOML format and searches in order: ./.lstk/config.toml, $HOME/.config/lstk/config.toml, then OS default. When no config exists, create at $HOME/.config/lstk/config.toml..."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/update/notify_test.go` around lines 129 - 142, Rename the test to
TestNotifyUpdateSkippedVersion, create a temporary config directory and point
the app's config loader there (so writes don't hit the real ~/.config/lstk), use
output.SinkFunc to send the "s" response (not "n") to trigger the per-version
skip branch in notifyUpdateWithVersion with NotifyOptions{UpdatePrompt: true}
and the existing test fetcher/server, then assert the config key
"update_skipped_version" was written and equals the current version (read back
via the same config loader or Viper instance) and finally restore any env/config
state you changed.
🧹 Nitpick comments (3)
internal/ui/components/message.go (1)

17-32: Consider whether the local text variable is necessary.

The introduction of text := e.Text and its usage throughout doesn't provide a clear benefit since e.Text is already a simple, efficient field access. The original code was equally readable and avoided the extra variable. Unless this is preparing for future text transformations (not evident in the current change), reverting to direct e.Text usage would keep the code simpler.

♻️ Optional simplification
 func RenderWrappedMessage(e output.MessageEvent, width int) string {
 	prefixText, prefix := messagePrefix(e)
-	text := e.Text
-
 	if prefixText == "" {
 		style := styles.Message
 		if e.Severity == output.SeveritySecondary {
 			style = styles.SecondaryMessage
 		}
-		return style.Render(strings.Join(wrap.SoftWrap(text, width), "\n"))
+		return style.Render(strings.Join(wrap.SoftWrap(e.Text, width), "\n"))
 	}
 
 	if width <= len([]rune(prefixText))+1 {
-		return prefix + " " + styles.Message.Render(text)
+		return prefix + " " + styles.Message.Render(e.Text)
 	}
 
 	availableWidth := width - len([]rune(prefixText)) - 1
-	lines := wrap.SoftWrap(text, availableWidth)
+	lines := wrap.SoftWrap(e.Text, availableWidth)
 	if len(lines) == 0 {
 		return prefix
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/ui/components/message.go` around lines 17 - 32, The local variable
text := e.Text is unnecessary; replace usages of text with the struct field
e.Text directly (e.g., in calls to wrap.SoftWrap(e.Text, width/availableWidth)
and in styles.Message.Render / styles.SecondaryMessage.Render) and remove the
redundant text declaration, keeping the existing prefixText, availableWidth, and
severity-based style logic intact (functions/identifiers to update: text
variable, e.Text, wrap.SoftWrap, styles.Message.Render,
styles.SecondaryMessage.Render).
internal/ui/app.go (1)

98-117: Avoid deriving prompt behavior from label text.

Both the vertical-navigation path and the resolved confirmation line are now keyed off string checks on the first option label ("[" / "Update now"). That hard-couples the UI to the exact literals emitted by internal/update/notify.go, so a copy tweak or localization will silently break navigation or the post-selection summary. Please make the prompt layout/summary style explicit on the event instead of inferring it from labels.

Also applies to: 318-354

internal/ui/components/input_prompt.go (1)

98-107: Make vertical layout explicit instead of inferring from label text.

Detecting layout from [ / ] in labels is fragile (wording/i18n changes can alter behavior). Prefer an explicit layout flag on InputPrompt set by the caller.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/ui/components/input_prompt.go` around lines 98 - 107, The layout
detection in usesVerticalOptions (which currently inspects input labels for
"["/"]") is fragile; add an explicit boolean field (e.g., VerticalLayout or
UseVerticalOptions) to the InputPrompt struct and change usesVerticalOptions to
read that flag (or add a new function like shouldUseVerticalOptions(prompt
InputPrompt, options []output.InputOption) that checks prompt.VerticalLayout
first); remove the label-based bracket detection and update all callers that
construct InputPrompt to set the new flag where a vertical layout is required so
layout is driven explicitly rather than inferred from opt.Label.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/config/config.go`:
- Around line 135-140: The fallback that maps legacy top-level keys to cfg.CLI
fields is never reached because viper.SetDefault made "cli.update_prompt" and
"cli.update_skipped_version" appear as set; update the conditions in
internal/config/config.go to use viper.InConfig("cli.update_prompt") /
viper.InConfig("cli.update_skipped_version") (or check viper.InConfig for the
top-level keys "update_prompt" and "update_skipped_version" as appropriate)
instead of viper.IsSet, and when the top-level legacy keys are present map them
into cfg.CLI.UpdatePrompt and cfg.CLI.UpdateSkippedVersion so legacy config
files are honored.

In `@internal/ui/components/input_prompt.go`:
- Around line 86-88: The selection rendering currently compares each option's
Key to p.options[p.selectedIndex].Key, which can mark multiple rows selected
when keys collide; change the range loop in the rendering code for input_prompt
(the loop that iterates over p.options and calls sb.WriteString with
styles.NimboMid.Render) to use the loop index (e.g., compare i ==
p.selectedIndex) instead of comparing opt.Key, so only the option at
p.selectedIndex is rendered as selected.

In `@internal/update/notify.go`:
- Line 20: The single shared const checkTimeout is too long for the inline
startup path called by NotifyUpdate (used during lstk start --non-interactive)
and causes a 5s stall; split the timeout into two constants (e.g.
startupCheckTimeout with a short duration and fullCheckTimeout with the existing
5s) and update call sites so NotifyUpdate (or the startup-specific call) uses
startupCheckTimeout while the explicit update command/CheckForUpdate uses
fullCheckTimeout; alternatively add a timeout parameter to
NotifyUpdate/CheckForUpdate and pass the short timeout from the non-interactive
startup path and the longer one from the explicit update command.

---

Outside diff comments:
In `@internal/update/notify_test.go`:
- Around line 129-142: Rename the test to TestNotifyUpdateSkippedVersion, create
a temporary config directory and point the app's config loader there (so writes
don't hit the real ~/.config/lstk), use output.SinkFunc to send the "s" response
(not "n") to trigger the per-version skip branch in notifyUpdateWithVersion with
NotifyOptions{UpdatePrompt: true} and the existing test fetcher/server, then
assert the config key "update_skipped_version" was written and equals the
current version (read back via the same config loader or Viper instance) and
finally restore any env/config state you changed.

---

Nitpick comments:
In `@internal/ui/components/input_prompt.go`:
- Around line 98-107: The layout detection in usesVerticalOptions (which
currently inspects input labels for "["/"]") is fragile; add an explicit boolean
field (e.g., VerticalLayout or UseVerticalOptions) to the InputPrompt struct and
change usesVerticalOptions to read that flag (or add a new function like
shouldUseVerticalOptions(prompt InputPrompt, options []output.InputOption) that
checks prompt.VerticalLayout first); remove the label-based bracket detection
and update all callers that construct InputPrompt to set the new flag where a
vertical layout is required so layout is driven explicitly rather than inferred
from opt.Label.

In `@internal/ui/components/message.go`:
- Around line 17-32: The local variable text := e.Text is unnecessary; replace
usages of text with the struct field e.Text directly (e.g., in calls to
wrap.SoftWrap(e.Text, width/availableWidth) and in styles.Message.Render /
styles.SecondaryMessage.Render) and remove the redundant text declaration,
keeping the existing prefixText, availableWidth, and severity-based style logic
intact (functions/identifiers to update: text variable, e.Text, wrap.SoftWrap,
styles.Message.Render, styles.SecondaryMessage.Render).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 6b0fc112-c5e4-4c89-a8b1-1230417ae1ae

📥 Commits

Reviewing files that changed from the base of the PR and between 87a0335 and 83f6741.

📒 Files selected for processing (11)
  • cmd/root.go
  • internal/config/config.go
  • internal/config/default_config.toml
  • internal/ui/app.go
  • internal/ui/app_test.go
  • internal/ui/components/input_prompt.go
  • internal/ui/components/message.go
  • internal/update/github.go
  • internal/update/notify.go
  • internal/update/notify_test.go
  • test/integration/update_test.go

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
internal/update/github.go (1)

43-43: Wrap propagated errors with operation context.

These paths currently return bare errors, which makes failure source less clear at call sites. Prefer contextual %w wrapping.

Suggested diff
 func fetchLatestRelease(ctx context.Context, token string) (*githubRelease, error) {
 	resp, err := githubRequest(ctx, latestReleaseURL, token)
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("fetch latest release request failed: %w", err)
 	}
 	defer func() { _ = resp.Body.Close() }()
@@
 	var release githubRelease
 	if err := json.NewDecoder(resp.Body).Decode(&release); err != nil {
-		return nil, err
+		return nil, fmt.Errorf("decode latest release response failed: %w", err)
 	}
@@
 func fetchLatestVersion(ctx context.Context, token string) (string, error) {
 	release, err := fetchLatestRelease(ctx, token)
 	if err != nil {
-		return "", err
+		return "", fmt.Errorf("fetch latest version failed: %w", err)
 	}
 	return release.TagName, nil
 }

Also applies to: 53-53, 62-62

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/update/github.go` at line 43, The three bare error propagations in
internal/update/github.go (the `return nil, err` occurrences around the block at
lines referenced) should be wrapped with contextual errors using fmt.Errorf and
the %w verb; update each `return nil, err` to return a wrapped error that
describes the operation (e.g., "fetching releases", "parsing release", or
"creating request" — choose wording appropriate to the surrounding code) and
include the original err via %w so callers get both context and the wrapped
error; apply this change to all three occurrences (the returns at the three
locations noted) and ensure fmt is imported if not already.
internal/config/config.go (1)

135-140: Backward-compat logic is correct.

Using viper.InConfig() properly checks for explicit presence in the loaded config file (not defaults), ensuring legacy top-level update_prompt and update_skipped_version keys are migrated to cfg.CLI.* only when the new cli.* keys aren't explicitly set.

However, no existing tests cover this legacy migration path. All current tests use the new [cli] section format. Adding a unit test for configs with the legacy top-level keys would improve coverage and prevent regressions if this migration logic changes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/config/config.go` around lines 135 - 140, Add a unit test that
verifies the legacy top-level keys migrate into the CLI struct when the new
cli.* keys are absent: create a test (e.g., TestLoadConfig_LegacyTopLevelKeys)
that provides a Viper config containing update_prompt and update_skipped_version
but no cli.update_prompt or cli.update_skipped_version, call the config load
function used in your code path that reads viper.InConfig, and assert that
cfg.CLI.UpdatePrompt and cfg.CLI.UpdateSkippedVersion are populated accordingly;
also include a negative case where cli.update_prompt is present to ensure the
migration does not override explicit cli.* values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@internal/config/config.go`:
- Around line 135-140: Add a unit test that verifies the legacy top-level keys
migrate into the CLI struct when the new cli.* keys are absent: create a test
(e.g., TestLoadConfig_LegacyTopLevelKeys) that provides a Viper config
containing update_prompt and update_skipped_version but no cli.update_prompt or
cli.update_skipped_version, call the config load function used in your code path
that reads viper.InConfig, and assert that cfg.CLI.UpdatePrompt and
cfg.CLI.UpdateSkippedVersion are populated accordingly; also include a negative
case where cli.update_prompt is present to ensure the migration does not
override explicit cli.* values.

In `@internal/update/github.go`:
- Line 43: The three bare error propagations in internal/update/github.go (the
`return nil, err` occurrences around the block at lines referenced) should be
wrapped with contextual errors using fmt.Errorf and the %w verb; update each
`return nil, err` to return a wrapped error that describes the operation (e.g.,
"fetching releases", "parsing release", or "creating request" — choose wording
appropriate to the surrounding code) and include the original err via %w so
callers get both context and the wrapped error; apply this change to all three
occurrences (the returns at the three locations noted) and ensure fmt is
imported if not already.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 01cec8fe-04f5-476f-ab26-763c1eaafcbf

📥 Commits

Reviewing files that changed from the base of the PR and between 83f6741 and 0dd4a7b.

📒 Files selected for processing (12)
  • cmd/root.go
  • internal/config/config.go
  • internal/config/default_config.toml
  • internal/ui/app.go
  • internal/ui/app_test.go
  • internal/ui/components/input_prompt.go
  • internal/ui/components/message.go
  • internal/update/github.go
  • internal/update/notify.go
  • internal/update/notify_test.go
  • test/integration/start_test.go
  • test/integration/update_test.go
✅ Files skipped from review due to trivial changes (4)
  • internal/config/default_config.toml
  • internal/ui/components/message.go
  • internal/ui/app.go
  • internal/ui/app_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • internal/update/notify_test.go
  • internal/ui/components/input_prompt.go
  • internal/update/notify.go

Copy link
Copy Markdown
Contributor

@anisaoshafi anisaoshafi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The UX looks really nice, thanks George 🤩

I left a few comments

return Set("cli.update_skipped_version", version)
}

func GetUpdateSkippedVersion() string {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is unused 👀

}

const checkTimeout = 500 * time.Millisecond
const checkTimeout = 2 * time.Second
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: PR description says the timeout was reduced

Comment on lines +327 to +328
case "n":
return checkmark + " Won't ask again"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like this code is unreachable 🤔

# CLI settings
[cli]
update_prompt = true

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: not sure we want this here since true is the default value anyways? Showing to users might invite them to disable it? Not sure what's right. If not documented here, we don't really have another place where we document all settings...

if !viper.InConfig("cli.update_skipped_version") && viper.InConfig("update_skipped_version") {
cfg.CLI.UpdateSkippedVersion = viper.GetString("update_skipped_version")
}
for i := range cfg.Containers {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: this looks like migration code, is this right?

  • update_prompt: I think we could ignore the fact that some users previously had this setting one level up in the config. They would just be asked again and in exchange we get rid of some complexity.
  • update_skipped_version: This is introduced in this PR so there is nothing to migrate.
    In short: can we remove these lines?

return a, responseCmd
}
}
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the Update method is already doing a lot and the PR adds another ~20 lines. Can we extract this in a new method, something like:

func (a App) handleVerticalPromptKey(msg tea.KeyMsg) (App, tea.Cmd, bool) {
      ...
      return a, nil, false
}

}

func componentsUsesVerticalPrompt(prompt components.InputPrompt, options []output.InputOption) bool {
return prompt.Visible() && len(options) > 1 && strings.Contains(options[0].Label, "[")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue:

strings.Contains(options[0].Label, "[")

We should not rely on string parsing. Can we add something in the model that indicates that this user input should be displayed vertically? Maybe as simple as:

 type UserInputRequestEvent struct {
      Prompt     string
      Options    []InputOption
      ResponseCh chan<- InputResponse
      Vertical   bool
  }

Not sure if it would help but we might want to add this to CLAUDE.md since it's come back a few times.

case "n":
return checkmark + " Won't ask again"
}
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: this file is generic UI rendering code, it should not know anything about the update logic.
We need to find another solution for this. Maybe a confirmation text can be added on the input options.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
internal/ui/components/input_prompt_test.go (1)

17-59: Consider adding a test case for vertical rendering.

All test cases set vertical: false. While the vertical selection behavior is tested in app_test.go, adding a test case here for vertical: true would verify the component's vertical rendering output (e.g., ensuring options render on separate lines with selection indicators).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/ui/components/input_prompt_test.go` around lines 17 - 59, Add a new
table-driven test case in input_prompt_test.go that sets vertical: true (e.g.,
name: "vertical renders options on separate lines") using the existing options
field (output.InputOption) and populate contains/excludes to assert that each
option appears on its own line and that selection indicators/markers are present
(for example, check for each label on separate lines and for a selection marker
like ">" or "(Y)"). Place the new case alongside the other cases in the test
slice so the test harness iterates over it, using the same test
helpers/assertions already used in the file to validate the rendered output.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@internal/ui/components/input_prompt_test.go`:
- Around line 17-59: Add a new table-driven test case in input_prompt_test.go
that sets vertical: true (e.g., name: "vertical renders options on separate
lines") using the existing options field (output.InputOption) and populate
contains/excludes to assert that each option appears on its own line and that
selection indicators/markers are present (for example, check for each label on
separate lines and for a selection marker like ">" or "(Y)"). Place the new case
alongside the other cases in the test slice so the test harness iterates over
it, using the same test helpers/assertions already used in the file to validate
the rendered output.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 76bfc11f-bcae-4f5a-be16-d5a844d58c92

📥 Commits

Reviewing files that changed from the base of the PR and between 0dd4a7b and 0b42a8b.

📒 Files selected for processing (13)
  • cmd/root.go
  • internal/config/config.go
  • internal/output/events.go
  • internal/ui/app.go
  • internal/ui/app_test.go
  • internal/ui/components/input_prompt.go
  • internal/ui/components/input_prompt_test.go
  • internal/ui/components/message.go
  • internal/update/github.go
  • internal/update/notify.go
  • internal/update/notify_test.go
  • test/integration/start_test.go
  • test/integration/update_test.go
✅ Files skipped from review due to trivial changes (3)
  • internal/ui/components/message.go
  • test/integration/start_test.go
  • test/integration/update_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • cmd/root.go
  • internal/ui/app_test.go
  • internal/update/github.go
  • internal/ui/components/input_prompt.go

@gtsiolis
Copy link
Copy Markdown
Member Author

Tried to address all review comments in one commit, haven't tested yet. I will re-request reviews after testing, unless someone wants to pick this up in the meantime. ⚠️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants