Skip to content

fix(mobile): align favorite star in selected model row - #6450

Merged
iscekic merged 1 commit into
mainfrom
kwf/explorer-model-thinking-effort-the-favorite-star-in-the-s-5b9d4-22fc
Sep 21, 2026
Merged

iscekic merged 1 commit into
mainfrom
kwf/explorer-model-thinking-effort-the-favorite-star-in-the-s-5b9d4-22fc

Conversation

@iscekic

@iscekic iscekic commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Changelog for users

  • In the session model picker, the favorite star keeps the same column in the selected row and in every other row.
  • The selected row still shows its checkmark at the row's right edge, and unselected rows show none.

Changelog for maintainers

  • The trailing checkmark now renders inside an always-present fixed-width slot, so selecting a row no longer shifts its favorite star left.
  • Every row renders that slot; only its content changes between the check and empty space.
  • A mounted test asserts the slot keeps the same class and width in selected and unselected rows.
  • Review the row layout first: alignment depends on the slot's fixed width and the row container's gap.
  • No API, data, configuration, or migration changes.

E2E proof

[e1] session-open: in the open picker tap the topmost not-yet-favorited row's star ('Add ... — android emulator-5554: 'SCENE e1 OK' after tapping 'Add Auto Efficient to favorites' then asserting 'Remove Auto Efficient from favorites'; that row renders at y 1623 under the FAVORITES header (y 1551-1588) and above RECOMMENDED (y 2114-2151) (e1-sections.log), and every star control shares x bounds [853,968] with the selected row's check glyph at [996,1043] (e1-alignment.log; e1-clean-hierarchy.xml); still e1.png for the visual reviewer.

[e1] session-open: in the open picker tap the topmost not-yet-favorited row's star ('Add ... — e2e-mobile-app/e1.png

[e1] session-open: open the session's model picker from its model chip and hold it open — the selected row's check sits in a reserved trailing column, so its favorite star lines up with the star in every… — android emulator-5554: SCENE e1 OK with the model picker open; e1-picker.xml shows all six favorite-star icons in the identical x-range 885..938 — selected 'Auto Balanced' (885,646,938,698) and unselected ALL-MODELS 'Auto Frontier' (885,1095,938,1148) — and the reserved trailing check at (996,648,1043,695); e1-picker.log names 'Auto Balanced, kilo-auto/balanced, and selected' and 'ALL MODELS'. Star-column alignment in e1-picker.png is the visual reviewer's.

[e1] session-open: open the session's model picker from its model chip and hold it open — the selected row's check sits in a reserved trailing column, so its favorite star lines up with the star in every… — prior/e1-picker.png

ux-check: The selected row still shows a fully visible, unclipped checkmark at the row's right edge, and no unselected row shows a checkmark. — e3-picker.png

[e4] ux-check: model picker — favorite star of the selected DeepSeek V4.1 Flash row shares the horizontal center of every ALL MODELS row and the FAVORITES rows above it — android emulator-5554 light mode: every favorite-star node measures the same bounds [853,][968,], center_x=910.5 in (e4-stars.log) — selected row 'Add DeepSeek V4.1 Flash to favorites … center_x=910.5', ALL MODELS rows 'Add DeepSeek Flash Latest … center_x=910.5' through 'Add DeepSeek V3.2 (retires Sep 28) … center_x=910.5', FAVORITES rows 'Remove Auto Balanced from favorites … center_x=910.5' and 'Remove Claude 3 Haiku from favorites … center_x=910.5'; captures e4-light-selected.png (selected row + ALL MODELS rows, tree e4-light-selected.xml) and e4-light-top.png (FAVORITES rows, tree…

[e4] ux-check: model picker — favorite star of the selected DeepSeek V4.1 Flash row shares the horizontal center of every ALL MODELS row and the FAVORITES rows above it — prior/e4-light-selected.png

[e4] ux-check: model picker — favorite star of the selected DeepSeek V4.1 Flash row shares the horizontal center of every ALL MODELS row and the FAVORITES rows above it

[e4] ux-check: model picker — favorite star of the selected DeepSeek V4.1 Flash row shares the horizontal center of every ALL MODELS row and the FAVORITES rows above it — prior/e4-light-top.png

[e8] ux-check: the star alignment holds in both light and dark mode — android emulator-5554 dark mode, same picker states as e4: e8-stars.log shows identical bounds [853,][968,] and center_x=910.5 for the selected 'Add DeepSeek V4.1 Flash to favorites' node and all ALL MODELS rows (e8-dark-selected.xml) and for the FAVORITES rows 'Remove Auto Balanced from favorites' / 'Remove Claude 3 Haiku from favorites' (e8-dark-top.xml); dark mode was active for those captures, proven by e8-theme.log line 'RadioButton text= desc=Dark checked=true bounds=[698,1036][1015,1137]' in the Preferences tree (e8-appearance-dark.xml) — the light captures (e4 files) were taken…

[e8] ux-check: the star alignment holds in both light and dark mode — prior/e8-dark-selected.png

[e8] ux-check: the star alignment holds in both light and dark mode

[e8] ux-check: the star alignment holds in both light and dark mode — prior/e8-dark-top.png

E2E proof — log excerpts

[e1] session-open: in the open picker tap the topmost not-yet-favorited row's st -> pass :: android emulator-5554: 'SCENE e1 OK' after tapping 'Add Auto Efficient to favorites' then asserting 'Remove Auto Efficient from favorites'; that row renders at y 1623 under the FAVORITES header (y 1551-1588) and above RECOMMENDED (y 2114-2151) (e1-sections.log), and every star control shares x bounds [853,968] with the selected row's check glyph at [996,1043] (e1-alignment.log; e1-clean-hierarchy.xml); still e1.png for the visual reviewer.
[e2] ux-check: reopening the picker with a pre-selected row already rendered sho -> pass :: android emulator-5554: 'SCENE e2 OK' for open-the-picker-then-read steps with no state change; the selected model row's star control sits at x [853,968] like the unselected 'Add Auto Efficient' [853,968] and 'Add Laguna S 2.1 (free)' [853,968] rows, and its star glyph [885,1655][938,1707] matches theirs while its check glyph occupies the trailing column [996,1657][1043,1704] (e2-alignment.log; e2-hierarchy.xml); still e2.png for the visual reviewer.
/home/igor_kilocode_ai/.local/share/kwf/sections/explorer-model-thinking-effort-the-favorite-star-in-the-s-5b9d4-22fc/e2e-mobile-app/e1-clean.log
android.widget.TextView Run `kilo remote` on your computer, or `/remote` in a running CLI session, to control a local kilo process. tappable [36,1056][1044,1130]
android.widget.TextView Repository tappable [37,1176][1045,1222]
android.widget.Button Repository: Select repository tappable [37,1240][1043,1356]
android.widget.TextView Select repository tappable [67,1270][978,1326]
android.widget.Button Connect GitLab tappable [76,1423][1004,1469]
android.widget.TextView Connect GitLab tappable [76,1423][944,1469]
android.widget.TextView Connect GitLab in your browser, then return here to pick a repository. tappable [76,1497][1004,1589]
android.widget.Button Open GitLab tappable [76,1617][870,1732]
android.widget.TextView Open GitLab tappable [412,1651][594,1697]
android.widget.Button Refresh repositories tappable [888,1617][1004,1732]
android.widget.TextView Changes tappable [37,1818][1045,1864]
android.view.View Changes tappable [37,1882][1043,2001]
android.widget.RadioButton Leave changes tappable [46,1891][540,1992]
android.widget.TextView Leave changes tappable [182,1918][403,1964]
android.widget.RadioButton Commit and push tappable [540,1891][1034,1992]
android.widget.TextView Commit and push tappable [656,1918][917,1964]
android.widget.TextView Environment tappable [37,2047][1045,2093]
android.widget.TextView Default environment tappable [37,2111][1045,2157]
android.widget.Button Start session [37,2213][1043,2329]
android.widget.TextView Start session tappable [442,2247][638,2293]
android.view.View Select model tappable [37,1255][858,1320]
android.widget.Button Done tappable [884,1237][1043,1338]
android.widget.TextView Done tappable [920,1259][1006,1315]
android.widget.EditText Search models... tappable [130,1414][1017,1489]
/home/igor_kilocode_ai/.local/share/kwf/sections/explorer-model-thinking-effort-the-favorite-star-in-the-s-5b9d4-22fc/e2e-mobile-app/e1-sections.log
<redacted>
<redacted>
/home/igor_kilocode_ai/.local/share/kwf/sections/explorer-model-thinking-effort-the-favorite-star-in-the-s-5b9d4-22fc/e2e-mobile-app/e1-alignment.log
<redacted>
<redacted>
<redacted>
<redacted>
<redacted>
<redacted>
<redacted>
<redacted>
<redacted>
/home/igor_kilocode_ai/.local/share/kwf/sections/explorer-model-thinking-effort-the-favorite-star-in-the-s-5b9d4-22fc/e2e-mobile-app/e2-reopen.log
android.widget.TextView Run `kilo remote` on your computer, or `/remote` in a running CLI session, to control a local kilo process. tappable [36,1056][1044,1130]
android.widget.TextView Repository tappable [37,1176][1045,1222]
android.widget.Button Repository: Select repository tappable [37,1240][1043,1356]
android.widget.TextView Select repository tappable [67,1270][978,1326]
android.widget.Button Connect GitLab tappable [76,1423][1004,1469]
android.widget.TextView Connect GitLab tappable [76,1423][944,1469]
android.widget.TextView Connect GitLab in your browser, then return here to pick a repository. tappable [76,1497][1004,1589]
android.widget.Button Open GitLab tappable [76,1617][870,1732]
android.widget.TextView Open GitLab tappable [412,1651][594,1697]
android.widget.Button Refresh repositories tappable [888,1617][1004,1732]
android.widget.TextView Changes tappable [37,1818][1045,1864]
android.view.View Changes tappable [37,1882][1043,2001]
android.widget.RadioButton Leave changes tappable [46,1891][540,1992]
android.widget.TextView Leave changes tappable [182,1918][403,1964]
android.widget.RadioButton Commit and push tappable [540,1891][1034,1992]
android.widget.TextView Commit and push tappable [656,1918][917,1964]
android.widget.TextView Environment tappable [37,2047][1045,2093]
android.widget.TextView Default environment tappable [37,2111][1045,2157]
android.widget.Button Start session [37,2213][1043,2329]
android.widget.TextView Start session tappable [442,2247][638,2293]
android.view.View Select model tappable [37,1255][858,1320]
android.widget.Button Done tappable [884,1237][1043,1338]
android.widget.TextView Done tappable [920,1259][1006,1315]
android.widget.EditText Search models... tappable [130,1414][1017,1489]
/home/igor_kilocode_ai/.local/share/kwf/sections/explorer-model-thinking-effort-the-favorite-star-in-the-s-5b9d4-22fc/e2e-mobile-app/e2-alignment.log
<redacted>
<redacted>
<redacted>
<redacted>
<redacted>
<redacted>
<redacted>
<redacted>
<redacted>
Owner request

Explorer finding: model-thinking-effort: The favorite star in the selected 'DeepSeek V4.1 Flash' row sits well to the left of the star in every 'ALL MODELS' row because the trailing checkmark takes the right column, so the favorite column does not line up down the list.

The user-agent explorer found this while using the app like a user.
One finding per item; the explorer never edits product code.

Flow: model-thinking-effort
Found on revision: f2181ae

Repro:

  1. set this state first: reviews 4; credits 22; org; uimode day; battery 55 discharging; relaunch; the device in light mode
  2. open the app on emulator-5602
  3. reach model-thinking-effort
  4. the capture shows the defect named below

Observed: The favorite star in the selected 'DeepSeek V4.1 Flash' row sits well to the left of the star in every 'ALL MODELS' row because the trailing checkmark takes the right column, so the favorite column does not line up down the list.
Expected: the screen renders without this defect

Evidence (from the device run):

[e6] ux-check: selecting an unselected row moves the checkmark to that row — android emulator-5604: e6-select.log records 'SCENE e6 OK' for tap 'Laguna S 2.1 (free)'; e6-after.txt carries content-desc="Laguna S 2.1 (free), poolside/laguna-s-2.1:free, Free, Data collected, and selected" while e6-before.txt carried content-desc="Auto Efficient, kilo-auto/efficient, and selected" (no longer present after), and e6-before.png / e6-after.png are the before/after stills for the visual reviewer's alignment check (no screenshot claims made here).

[e6] ux-check: selecting an unselected row moves the checkmark to that row — e6-before.png

[e2] session-open: no-match model query shows EmptyState and no row/star column — android emulator-5604: e2-nomatch.log records 'SCENE e2 OK' after typing zzzqqq, and e2-empty-state.txt shows text="No matches" and text="Try a different search term." with the query text="zzzqqq" and no 'to favorites' node in the list (e2-empty-state.png is the visual reviewer's still).

[e2] session-open: no-match model query shows EmptyState and no row/star column — e2-empty-state.png

[e6] ux-check: selecting an unselected row moves the checkmark to that row

[e6] ux-check: selecting an unselected row moves the checkmark to that row — e6-after.png

Follow-ups (not changed here)

  • not proved live: session-open: in the open picker type a query that matches no model — the EmptyState 'No matches' renders and no row (and no star column) is drawn (platform: android) (no capture cited it)
  • not proved live: ux-check: In the model picker for the model-thinking-effort flow, with the selected model (DeepSeek V4.1 Flash) visible in the ALL MODELS section, the favorite star in the selected row has the same horizontal center as the favorite star in every other ALL MODELS row and in the FAVORITES rows above it. (no capture cited it)
  • not proved live: ux-check: Reopening the picker with a pre-selected row already rendered (no state change during the capture) shows the same star alignment, so the alignment does not depend on a selection interaction happening in that session. (no capture cited it)
  • not proved live: ux-check: Selecting the currently unselected row moves the checkmark to that row without the model name, provider/id text, or the favorite star shifting horizontally (compare screenshots before and after the tap). (no capture cited it)
  • not proved live: ux-check: The alignment holds in both light and dark mode. (no capture cited it)

Open findings (not fixed here)

  • not proved live: model-thinking-effort.png is no longer on the host that took it, so no publish can carry it

e2

Explorer finding: model-thinking-effort: The favorite star in the selected 'DeepSeek V4.1 Flash' row sits well to the left of the star in every 'ALL MODELS' row because the trailing checkmark takes the right column, so the favorite column does not line up down the list.

The user-agent explorer found this while using the app like a user.
One finding per item; the explorer never edits product code.

Flow: model-thinking-effort
Found on revision: f2181ae

Repro:
1. set this state first: reviews 4; credits 22; org; uimode day; battery 55 discharging; relaunch; the device in light mode
2. open the app on emulator-5602
3. reach model-thinking-effort
4. the capture shows the defect named below

Observed: The favorite star in the selected 'DeepSeek V4.1 Flash' row sits well to the left of the star in every 'ALL MODELS' row because the trailing checkmark takes the right column, so the favorite column does not line up down the list.
Expected: the screen renders without this defect

Evidence (from the device run):
- ~/.local/share/kwf/findings/explorer-model-thinking-effort-the-favorite-star-in-the-s-5b9d44d8/model-thinking-effort.png
@kilo-code-bot

kilo-code-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The trailing check is now wrapped in an always-rendered fixed-width w-[18px] slot (model-selector.tsx:332), which aligns the favorite star across selected and unselected rows without changing accessibility structure or behavior; the added mounted test covers the reserved-column invariant.

Files Reviewed (2 files)
  • apps/mobile/src/components/agents/model-selector.tsx - no issues
  • apps/mobile/src/components/agents/model-selector.mounted.test.tsx - no issues

Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

@iscekic

iscekic commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator Author

This description names a scenario the proof did not capture:

  • not proved live: session-open: in the open picker type a query that matches no model — the EmptyState 'No matches' renders and no row (and no star column) is drawn (platform: android) (no capture cited it)

A repeated proof run rebuilds the same evidence, so no proof run is dispatched for a named gap. Merging with this gap open is your decision.

@iscekic iscekic added the human-ready The PR is ready for human review. label Sep 21, 2026
@iscekic iscekic self-assigned this Sep 21, 2026

@eshurakov eshurakov left a comment

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.

Approved after a shallow triage pass. Duplicate of #6457 - close one before merge.

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

Labels

human-ready The PR is ready for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants