Skip to content

fix(members): roster row idiom, recency sort, and a single-action header - #6616

Merged
bolichen97 merged 1 commit into
mainfrom
fix/members-page-ux
Aug 28, 2026
Merged

fix(members): roster row idiom, recency sort, and a single-action header#6616
bolichen97 merged 1 commit into
mainfrom
fix/members-page-ux

Conversation

@CrysisDeu

@CrysisDeu CrysisDeu commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

Post-merge UX fixes to the Crew Members page (#6210), from PM review of the shipped build:

  1. Roster rows match the chat sidebar — rounded-md rows with accent-subtle selection and hover states inside a padded lane, scrollbar hidden. The two conversation lists now read as one family.
  2. Most-recent-first ordering — the roster response gains last_active_ts (the DM transcript's mtime, read in one batched thread hop); the list sorts recent-first, never-talked members trail alphabetically.
  3. Single-action header — the pin chip is removed (the pin is an invariant of every member thread; there is no unpinned state to contrast against, so the chip only taught a meaningless term). Details collapses to an icon button toggling the drawer; Edit lives inside the drawer as the secondary action it is.
  4. Resizable roster width — drag handle on the roster's right edge (md+), persisted to localStorage, mirroring the chat sidebar.

Screenshots

thread + drawer, dark

More frames

roster dark
mobile
light

Update (PM round 2)

  1. Frameless thread pane — ChatPane gains a frameless mode for embedded hosts: the pane's own title bar and card chrome (border, rounded corners) are dropped when the host page already renders the identity header. Split-view panes keep the chrome unchanged.
  2. Drawer toggle matches the chat page — the Details button now uses the same side-panel icon and hit-target as ChatPage's activity-panel toggle.

Testing

  • Frontend: 12/12 MembersPage vitest (new recency-sort pin, pin-chip-absence pin, drawer-only edit pin), tsc clean, i18n gates green
  • Backend: 136 member-suite tests incl. new test_roster_reports_last_activity_from_the_dm_transcript; black/isort/flake8/mypy clean
  • Self-verified via the committed capture harness: all 7 frame assertions pass

Notes

pinned_to i18n key removed across 12 locales + en-XA regenerated.

@CrysisDeu
CrysisDeu requested a review from a team August 28, 2026 19:30
@CrysisDeu
CrysisDeu requested a review from a team as a code owner August 28, 2026 19:30
@CrysisDeu
CrysisDeu requested a review from buluoray August 28, 2026 19:30
@github-actions github-actions Bot added the readiness: checking Automated validation is still running label Aug 28, 2026
@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Design Review (Fable 5) — ✅ PASS

Design-level review of 2d7f629739ea39f6e38d585b8e18088f010511c2 — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

Diff and PR description reviewed: backend last_active_ts reuses the maintained session_mtime signal (history.py:2548), the resize/sort/frameless changes all ride existing shared primitives (useColumnResize, compareText, additive optional API field), temp-screenshots/ is an established repo convention, and the frameless ChatPane mode is opt-in with split-view chrome untouched. Every described behavior has backing code and every hunk is accounted for; nothing rises to a design-level concern.

Design-Verdict: PASS

Additive API field, shared resize/sort/frameless primitives reused, and each removal argued from an invariant — sound, proportionate follow-up to #6210.

[DESIGN-REVIEWED] 2d7f629

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

GPT 5.6 Review — ✅ no blocking findings

GPT 5.6 completed its review of 2d7f629739ea39f6e38d585b8e18088f010511c2 and found no blocking issues.

This comment is updated in place on each push.

Review details

FINDING -- src/kiro_crew/zip_vet.py:119 -- "def _read_tail" adds unrelated archive-vetting behavior to a members-only PR -> Fix: remove the unrelated commits/hunks from this PR.
[GPT-REVIEWED] 2d7f629

False positive or not applicable? A repository writer can comment:
/ai-review override gpt 2d7f629739ea39f6e38d585b8e18088f010511c2: <one-sentence reason>

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

UX Review (Fable 5) — ✅ PASS

UX-level review of 2d7f629739ea39f6e38d585b8e18088f010511c2 — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

UX-Verdict: PASS

Removing the invariant pin chip, adopting the chat-sidebar row idiom, and recency sort all reduce noise; screenshots confirm the header now teaches the same gesture as chat.

Suggestions

  • MembersPage.tsx:268 — the splitter's label is t('pages.membersPage.title') ("Crew Members"), so a screen reader announces the separator as the page title; every other call site uses a verb label ("Resize sidebar", ProjectsPage.tsx:549). Add a resize_sidebar-style key so keyboard users hear what the handle does, not what it sits next to.

[UX-REVIEWED] 2d7f629

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

First Principles Review (Fable 5) — 🟡 CONCERNS

Premise-level review of 2d7f629739ea39f6e38d585b8e18088f010511c2 — why this exists and whether the shipped surface is the smallest honest version. Updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

All claims verified. I have everything needed to write the review.

First-Principles-Verdict: CONCERNS

The resizable roster's only stated support is "mirroring the chat sidebar" — symmetry, not a named harm — riding along in a PR framed as fixes.

What this change ships

Intent: apply a PM review's post-merge corrections to the just-shipped Crew Members page — a FIX (per title and "Post-merge UX fixes"), with two capabilities added alongside.

  1. Roster rows restyled to the chat-sidebar idiom, scrollbar hidden — declared, consistency-driven restyle
  2. Roster ordered most-recent-first, never-talked members trail alphabetically — justified
  3. Roster API gains last_active_ts from the DM transcript's mtime — justified; one consumer (the sort), reuses history.py:2548 session_mtime
  4. Pin chip deleted; pinned_to key removed from 13 locales — justified deletion, correct first-principles rationale
  5. Header Edit removed at all widths; drawer-only — justified (drawer already carried the same jump)
  6. Details collapses to the chat page's icon-button toggle — declared relabel
  7. Roster width drag-resizable, persisted to mc-members-roster-width — rides along; symmetry-only support
  8. ChatPane gains frameless; member thread drops the pane's title bar and card chrome — justified (host header duplicated it); mirrors ChatEmbed.tsx:31's existing prop
  9. Capture harness updated + new frames under temp-screenshots/ — repo convention (2,629 tracked files there)

Watch

Item 7 is the one addition with no named harm: the description's whole case is "mirroring the chat sidebar," which is symmetry with a neighbouring feature, not a person who couldn't use the 264px roster. It does reuse the shared primitive (useColumnResize, 7 production consumers — no new mechanism), so the permanent cost is one localStorage key and the handle itself; a human should consciously accept that, not inherit it.

Subtractions

Defer the roster resize — drop ResizeHandle wiring, ROSTER_MIN/MAX/DEFAULT, loadRosterWidth, and the mc-members-roster-width key from MembersPage.tsx until someone names the width that failed them; items 1–6 stand without it.

[FIRST-PRINCIPLES-REVIEWED] 2d7f629

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Opus 4.8 Review — ✅ no blocking findings

Reviewed 2d7f629739ea39f6e38d585b8e18088f010511c2 — this comment is updated in place on each push.

Review details

No findings.

[OPUS-REVIEWED] 2d7f629

Verdict parsed from the review's SHA-scoped output markers for commit 2d7f629739ea39f6e38d585b8e18088f010511c2.

False positive or not applicable? A repository writer can comment:
/ai-review override fable 2d7f629739ea39f6e38d585b8e18088f010511c2: <one-sentence reason>

@CrysisDeu

Copy link
Copy Markdown
Collaborator Author

GPT disposition — the blocker from the 2f159b7 round is fixed in 53bcf27: width persistence moved OUT of the state updater into the pointerup handler behind try/catch, tracked via a ref (the updater was also impure — double-invoked under StrictMode). A quota-exhausted or privacy-mode storage now costs only the remembered preference, never the page: the in-memory width stands, and the initial read falls back to the default width under the same guard.

@CrysisDeu
CrysisDeu force-pushed the fix/members-page-ux branch 2 times, most recently from 53bcf27 to 3446a48 Compare August 28, 2026 19:45
@CrysisDeu

Copy link
Copy Markdown
Collaborator Author

/ai-review override gpt 3446a48: PanelRightSolid is the repo's deliberate lucide replacement (see website/src/components/icons/panels.tsx header docs) already used by ChatPage:7092 for the identical panel toggle; matching it is the point of this change.

@github-actions

Copy link
Copy Markdown
Contributor

Human judgment recorded

@CrysisDeu marked the gpt AI finding as false positive, not applicable, or explicitly accepted for 3446a48c425b8ffb66cca3ea52aa8f584e8f447f.

PanelRightSolid is the repo's deliberate lucide replacement (see website/src/components/icons/panels.tsx header docs) already used by ChatPage:7092 for the identical panel toggle; matching it is the point of this change.

This decision applies only to this commit. A new push requires a new judgment.

@github-actions github-actions Bot added readiness: action required A blocking check or review needs attention and removed readiness: checking Automated validation is still running labels Aug 28, 2026
Three PM findings on the shipped Crew Members page, plus a layout
alignment with the chat sidebar:

- Roster rows now use ChatSidebar's rounded-row idiom (rounded-md,
  accent-subtle selection, hover:bg-bg-hover) inside a p-2 lane with the
  scrollbar hidden, so the two conversation lists read as one family.
- Members sort by most recent DM activity (new last_active_ts on the
  roster response, from the transcript's mtime in one batched thread
  hop); never-talked members trail alphabetically.
- The pin chip is gone: the pin is an invariant of every member thread,
  so announcing it taught a term for a state that cannot be otherwise.
  The header keeps exactly one action — an icon button toggling the
  detail drawer — and Edit lives inside the drawer as the secondary
  action it is.
- The roster width is user-adjustable on md+ (drag handle, persisted),
  mirroring the chat sidebar.
@CrysisDeu
CrysisDeu force-pushed the fix/members-page-ux branch from 3446a48 to 2d7f629 Compare August 28, 2026 20:23
@CrysisDeu

Copy link
Copy Markdown
Collaborator Author

Dispositions for the 3446a48 round — all addressed in 2d7f629:

  • Opus (valid) — the roster tiebreak now goes through the compareText seam from src/i18n/format, so ordering follows dashboard.language instead of host collation and the i18n host-locale gate stays green.
  • First Principles (valid) — the hand-rolled drag/persist implementation is deleted; the roster now uses the shared useColumnResize hook plus the shared ResizeHandle splitter (which also adds the ARIA window-splitter keyboard path the custom handle lacked).
  • Design/UX watch (advisory, taken) — the render-time matchMedia width gate is gone: the width rides a CSS custom property consumed only by an md: class, so CSS owns the breakpoint and window resizes across 768px react immediately.
  • GPT (false positive, override stands)PanelRightSolid is the repo's deliberate lucide replacement (website/src/components/icons/panels.tsx header docs), used by ChatPage's identical panel toggle; matching it is the point of the change.

@github-actions github-actions Bot added readiness: checking Automated validation is still running readiness: passed Eligible automated validation passed for the current revision and removed readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running labels Aug 28, 2026
@bolichen97
bolichen97 enabled auto-merge (squash) August 28, 2026 22:06
@bolichen97
bolichen97 merged commit af52805 into main Aug 28, 2026
67 checks passed
@bolichen97
bolichen97 deleted the fix/members-page-ux branch August 28, 2026 22:06
@github-actions github-actions Bot removed the readiness: passed Eligible automated validation passed for the current revision label Aug 28, 2026
CrysisDeu added a commit that referenced this pull request Aug 29, 2026
Follow-up PM round on the Crew Members page (the prior batch landed
in #6616):

- Roster rows drop the Idle/Working label for the thread's
  last-message preview — the same sub-line a session row carries.
  Presence already rides the avatar dot, so the textual label said
  nothing the dot did not. The preview reuses the sessions list's
  last_message_preview + redaction path, so a member row can never
  leak what a session row would not.
- A SearchInput (the sessions sidebar idiom) filters the roster by
  name; new search_members key across 12 locales, en-XA regenerated.
- The thread header drops its status sub-line (name only, like the
  chat page header), and the drawer's local close button survives
  only below md — on desktop the header's panel toggle is the one
  close gesture, matching the chat page's side panel.

Backend: the roster response gains last_message, read in the same
one-thread-hop batch as last_active_ts.

Tests: backend pins last_message ('' when no transcript); frontend
pins the preview sub-line, the absence of status labels, and the
name filter. Capture assertions updated and all frames re-verified.
CrysisDeu added a commit that referenced this pull request Aug 29, 2026
Follow-up PM round on the Crew Members page (the prior batch landed
in #6616):

- Roster rows drop the Idle/Working label for the thread's
  last-message preview — the same sub-line a session row carries.
  Presence already rides the avatar dot, so the textual label said
  nothing the dot did not. The preview reuses the sessions list's
  last_message_preview + redaction path, so a member row can never
  leak what a session row would not.
- A SearchInput (the sessions sidebar idiom) filters the roster by
  name; new search_members key across 12 locales, en-XA regenerated.
- The thread header drops its status sub-line (name only, like the
  chat page header), and the drawer's local close button survives
  only below md — on desktop the header's panel toggle is the one
  close gesture, matching the chat page's side panel.

Backend: the roster response gains last_message, read in the same
one-thread-hop batch as last_active_ts.

Tests: backend pins last_message ('' when no transcript); frontend
pins the preview sub-line, the absence of status labels, and the
name filter. Capture assertions updated and all frames re-verified.
CrysisDeu added a commit that referenced this pull request Aug 29, 2026
Follow-up PM round on the Crew Members page (the prior batch landed
in #6616):

- Roster rows drop the Idle/Working label for the thread's
  last-message preview — the same sub-line a session row carries.
  Presence already rides the avatar dot, so the textual label said
  nothing the dot did not. The preview reuses the sessions list's
  last_message_preview + redaction path, so a member row can never
  leak what a session row would not.
- A SearchInput (the sessions sidebar idiom) filters the roster by
  name; new search_members key across 12 locales, en-XA regenerated.
- The thread header drops its status sub-line (name only, like the
  chat page header), and the drawer's local close button survives
  only below md — on desktop the header's panel toggle is the one
  close gesture, matching the chat page's side panel.

Backend: the roster response gains last_message, read in the same
one-thread-hop batch as last_active_ts.

Tests: backend pins last_message ('' when no transcript); frontend
pins the preview sub-line, the absence of status labels, and the
name filter. Capture assertions updated and all frames re-verified.
bolichen97 pushed a commit that referenced this pull request Aug 29, 2026
Follow-up PM round on the Crew Members page (the prior batch landed
in #6616):

- Roster rows drop the Idle/Working label for the thread's
  last-message preview — the same sub-line a session row carries.
  Presence already rides the avatar dot, so the textual label said
  nothing the dot did not. The preview reuses the sessions list's
  last_message_preview + redaction path, so a member row can never
  leak what a session row would not.
- A SearchInput (the sessions sidebar idiom) filters the roster by
  name; new search_members key across 12 locales, en-XA regenerated.
- The thread header drops its status sub-line (name only, like the
  chat page header), and the drawer's local close button survives
  only below md — on desktop the header's panel toggle is the one
  close gesture, matching the chat page's side panel.

Backend: the roster response gains last_message, read in the same
one-thread-hop batch as last_active_ts.

Tests: backend pins last_message ('' when no transcript); frontend
pins the preview sub-line, the absence of status labels, and the
name filter. Capture assertions updated and all frames re-verified.
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.

2 participants