Skip to content

Chat sidebar: lazy Archived + System groups, unbounded conversation feed - #269

Open
arsenmuk wants to merge 1 commit into
mainfrom
arsenmuk/archived-sessions-group
Open

Chat sidebar: lazy Archived + System groups, unbounded conversation feed#269
arsenmuk wants to merge 1 commit into
mainfrom
arsenmuk/archived-sessions-group

Conversation

@arsenmuk

@arsenmuk arsenmuk commented Aug 4, 2026

Copy link
Copy Markdown
Member

Problem

The sidebar silently dropped active chats: GET /api/sessions capped non-starred sessions at 50, and cron sessions (bumped every heartbeat tick) crowded conversations out of those slots. Archived sessions had no UI at all — and no unarchive path existed anywhere in the backend.

Changes

Backend

  • GET /api/sessions now serves list_active_sessions(): all non-archived conversation sessions, unbounded; cron/hook sources excluded from the feed. archived_count + system_count ride on the payload (two COUNT(*)s), so collapsed groups show a badge without fetching rows.
  • New GET /api/sessions/archived and GET /api/sessions/system — fetched lazily, only when the corresponding sidebar group is expanded.
  • New POST /api/sessions/{id}/unarchive (restores to idle, clears archived_at, logs an unarchived event) — inverse of archive.
  • PATCH /api/sessions/{id} with starred: true on an archived session unarchives + stars in one write, so the star→project hook fires on a live session.
  • Telegram's session picker keeps the old bounded list_sessions — untouched.

Frontend

  • New Archived and System groups at the bottom of the sidebar: collapsed by default (not persisted), lazy-fetch on first expand with spinner/empty states, hidden entirely when their count is 0.
  • Archived rows use the standard session item with a Star / Rename / Unarchive / Delete menu.
  • Date buckets simplified to Last hour / Last 3 hours / Today / This week / Other; the first two are elapsed-time (correct across midnight); empty buckets never render.

Testing

  • pytest tests/test_sessions.py — 70/70 (10 new: unarchive lifecycle/events/missing, archived list/count, star-unarchive write, active-feed exclusions, unbounded feed regression, system list/count).
  • npm run build (tsc + vite) green.
  • Validated live: no /archived / /system request until expand; unarchive returns a session to its date group; starring an archived session lands it in Starred.

🤖 Generated with Claude Code

The sidebar silently dropped active chats: GET /api/sessions capped
non-starred sessions at 50, and always-updating cron sessions crowded
conversations out of those slots. Archived sessions had no UI at all
(and no unarchive path anywhere).

- Main feed (GET /api/sessions) now returns ALL non-archived
  conversation sessions (no LIMIT); cron/hook sessions are excluded
  and served by GET /api/sessions/system instead. archived_count +
  system_count piggyback on the payload, so collapsed groups show a
  badge without fetching any rows.
- New Archived and System sidebar groups: collapsed by default (not
  persisted), lazily fetched on first expand, hidden when empty.
- Archived rows get a Star / Rename / Unarchive / Delete menu. New
  POST /api/sessions/{id}/unarchive restores to idle; starring an
  archived session unarchives + stars in one PATCH, so the
  star->project hook fires on a live session.
- Date buckets simplified to Last hour / Last 3 hours / Today /
  This week / Other (relative first two, empty buckets never render).

Telegram's session picker keeps the old bounded list_sessions.
pytest tests/test_sessions.py 70/70; npm run build green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant