[RFC] Folder-style session grouping (file-explorer sidebar)#3773
[RFC] Folder-style session grouping (file-explorer sidebar)#3773Alterego-42 wants to merge 1 commit into
Conversation
… [RFC draft] Replace the flat session list with a file-explorer sidebar: - Always-on rail + hover flyout showing a nestable group tree (up to 4 levels). - Entering a group shows only its direct sessions, backed by REAL keyset pagination on the DB session-meta store (no getAll()+slice). - Drag-reorder of groups (among siblings) and sessions (within a group). - Per-group color / rename / duplicate / delete; Unassigned + virtual Starred views. - AI Manager session: a reserved pinned session exposing a model-callable session-management toolset (list/move/rename/group ops, bulk variants, summaries with configurable concurrency, auto-organize proposal hook). - Adaptive session summaries (type-aware prompt; per-session/global override). - Selective export/import compatible with the official Chatbox format. This is a Draft / RFC for design discussion, built on top of v1.21.1's paginated session-meta store. The migration here carries fork-specific 15->16 self-healing (an artifact of this fork's history) that upstream would simplify to a clean forward migration. Local-build tweaks and a personal OpenAI-Responses change are intentionally excluded. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
This RFC PR introduces a folder-style (nested) session grouping experience in the renderer sidebar, backed by group-scoped keyset pagination for session meta storage. It also adds an “AI Manager” reserved system session with model-callable session-management tools and a new per-session summary system (prompt + caching + bulk concurrency controls), plus selective export/import support for the new grouping model.
Changes:
- Add session grouping primitives (group schema + group store + group tree utilities) and switch sidebar UI to a rail + flyout + group-scoped session list view.
- Extend session meta storage to support
groupIdfiltering/pagination (IndexedDB + SQLite) and add a migration step to bridge fork-specific version collisions. - Add AI Manager toolset + session summaries (model selection, prompt override, storage, modal UI) and selective export/import filtering for sessions/groups.
Reviewed changes
Copilot reviewed 54 out of 54 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/shared/types/settings.ts | Adds summary model, summary prompt, and concurrency settings to schema. |
| src/shared/types/session.ts | Adds SessionGroup schema and session meta fields (groupId, system, sortIndex, summaryPrompt). |
| src/shared/defaults.ts | Defines reserved system session IDs (AI Manager). |
| src/renderer/utils/session-utils.ts | Adds isSystemSession; filters system sessions out of sortSessions. |
| src/renderer/utils/session-utils.test.ts | Adds coverage for system-session filtering and preserved meta fields. |
| src/renderer/utils/group-tree.ts | Adds group tree builder + breadcrumb path utilities and STARRED sentinel. |
| src/renderer/utils/group-tree.test.ts | Tests tree building and breadcrumb path behavior. |
| src/renderer/stores/sessionHelpers.ts | Extends getSessionMeta pick list to include grouping/system fields. |
| src/renderer/stores/sessionActions.ts | Re-exports group ops and summary ops/types; exports group reorder-in-panel API. |
| src/renderer/stores/session/tools-builder.ts | Adds AI Manager toolset injection when sessionId is reserved manager ID. |
| src/renderer/stores/session/summary.ts | Implements summary cache/read/generate logic with prompt resolution and token budgeting. |
| src/renderer/stores/session/orchestration.ts | Passes sessionId into tool builder to enable AI Manager toolset. |
| src/renderer/stores/session/groups.ts | Implements move/reorder/duplicate operations for grouped sessions and groups. |
| src/renderer/stores/session/groups.test.ts | Tests group/session move/reorder/duplicate behaviors via mocks. |
| src/renderer/stores/session/crud.ts | Adds reorderSessionInGroup using fractional sortOrder updates. |
| src/renderer/stores/session/auto-organize.ts | Adds placeholder auto-organize strategy and proposal application logic. |
| src/renderer/stores/session/auto-organize.test.ts | Tests proposal application and temp-id resolution. |
| src/renderer/stores/migration.ts | Bumps version to 16 and adds fork-specific 15→16 self-healing migration. |
| src/renderer/stores/migration.test.ts | Updates version expectations and adds tests for new migration chain/self-heal. |
| src/renderer/stores/groupStore.ts | New storage-backed group CRUD with depth/cycle validation and react-query cache. |
| src/renderer/stores/groupStore.test.ts | Adds unit tests for group create/update/delete and nesting validation. |
| src/renderer/stores/chatStore.ts | Adds per-group paginated session queries + counts + starred view; ensures AI Manager session exists. |
| src/renderer/stores/atoms/uiAtoms.ts | Adds persisted atoms for expanded groups and current entered group id. |
| src/renderer/storage/StoreStorage.ts | Adds SessionGroupsList storage key and summary:* key generator. |
| src/renderer/storage/SQLiteSessionMetaStorage.ts | Adds group_id column/index and group-scoped pagination/count APIs. |
| src/renderer/storage/SessionMetaStorage.ts | Adds IndexedDB schema upgrade for group compound index + group pagination/count APIs. |
| src/renderer/storage/tests/SQLiteSessionMetaStorage.test.ts | Updates sqlite meta storage tests for new schema shape. |
| src/renderer/storage/tests/SessionMetaStorage.group.test.ts | Adds IndexedDB group pagination/count tests. |
| src/renderer/Sidebar.tsx | Replaces flat session list with grouped rail + panel + AI Manager pin. |
| src/renderer/routes/settings/general.tsx | Adds selective export/import UI and filtering for groups/sessions/meta DB. |
| src/renderer/routes/settings/default-models.tsx | Adds default summary model selector + summary concurrency setting. |
| src/renderer/routes/settings/chat.tsx | Adds global default summary prompt editor/reset UI. |
| src/renderer/routes/index.tsx | Adds groupId search param to seed new-session creation into a group. |
| src/renderer/packages/prompts.ts | Adds summarization prompt builder and default prompt constant. |
| src/renderer/packages/model-calls/toolsets/session-manager.ts | New AI Manager toolset (list/move/rename/group/summaries/bulk ops). |
| src/renderer/modals/SetGroupColor.tsx | Modal for setting/clearing group color. |
| src/renderer/modals/SessionSummary.tsx | Drawer UI for cached/regenerated per-session summaries. |
| src/renderer/modals/SessionSettings.tsx | Adds per-session summary prompt field in session settings. |
| src/renderer/modals/MoveSessionToGroup.tsx | Modal to move a session to a group (with create/search). |
| src/renderer/modals/index.tsx | Registers new modals (group + summary + confirmation). |
| src/renderer/modals/CreateGroup.tsx | Modal to create group/subgroup. |
| src/renderer/modals/ConfirmDangerousAction.tsx | Confirmation modal for destructive AI-manager actions. |
| src/renderer/lib/export-helpers.ts | Adds helper functions for selective export filtering and initial selection. |
| src/renderer/lib/export-helpers.test.ts | Tests export helper filtering/selection behavior. |
| src/renderer/lib/concurrency.ts | Adds concurrency helpers + fallback ladder runner. |
| src/renderer/lib/concurrency.test.ts | Tests concurrency helper correctness. |
| src/renderer/index.tsx | Ensures AI Manager session exists during renderer bootstrap. |
| src/renderer/i18n/locales/en/translation.json | Adds new UI strings for grouping/summaries/AI Manager. |
| src/renderer/components/session/SessionItem.tsx | Adds “Move to group…” and “View Summary”; supports restricted/starred view + drag overlay styling. |
| src/renderer/components/session/ManagerSessionPin.tsx | Adds persistent UI pin for the AI Manager session. |
| src/renderer/components/session/GroupTreeFlyout.tsx | Implements nested group tree flyout UI with DnD and actions. |
| src/renderer/components/session/GroupRail.tsx | Adds left rail that opens flyout and shows breadcrumb dots. |
| src/renderer/components/session/GroupedSessionList.tsx | Implements per-group paginated session list view with DnD and header controls. |
| src/renderer/components/ExportSelectionTree.tsx | Adds nested selection UI for selective export of conversations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| async getTotalByGroup(groupId: string | null): Promise<number> { | ||
| await this.initialize() | ||
| const groupKey = groupId ?? UNGROUPED_KEY | ||
| return new Promise((resolve, reject) => { | ||
| const index = this.getStore('readonly').index(GROUP_INDEX) | ||
| const request = index.count(IDBKeyRange.bound([groupKey], [groupKey, []])) | ||
| request.onsuccess = () => resolve(request.result) | ||
| request.onerror = () => reject(request.error) | ||
| }) | ||
| } |
| yield ',' | ||
| yield `"__exported_partial":${JSON.stringify(selectedSessionIds.size > 0 || selectedGroupIds.size > 0)}` | ||
| yield ',' | ||
| yield `"__exported_session_count":${selectedSessionIds.size}` | ||
| yield ',' | ||
| yield `"__exported_group_count":${selectedGroupIds.size}` |
| const { groups } = useGroups() | ||
| const { sessionMetaList } = useSessionList() | ||
| const userTouchedRef = useRef(false) | ||
|
|
||
| useEffect(() => { |
| <SessionItem | ||
| selected={routerState.location.pathname === `/session/${activeDragSession.id}`} | ||
| session={activeDragSession} | ||
| /> | ||
| </div> |
| <Text span size="sm" fw={600} lineClamp={1} c="chatbox-primary"> | ||
| {t('Ungrouped')} | ||
| </Text> |
| <Tooltip label={t('Ungrouped')} openDelay={500} withArrow> | ||
| <ActionIcon | ||
| variant="subtle" | ||
| color={currentGroupId === null ? 'chatbox-brand' : 'chatbox-tertiary'} | ||
| size={20} | ||
| aria-label={t('Ungrouped') ?? ''} | ||
| onClick={() => setCurrentGroupId(null)} | ||
| > | ||
| <IconInbox size={16} /> | ||
| </ActionIcon> | ||
| </Tooltip> | ||
| {currentGroupId === null ? ( | ||
| <Text span size="sm" fw={600} c="chatbox-primary" lineClamp={1}> | ||
| {t('Ungrouped')} | ||
| </Text> | ||
| ) : ( |
Replaces the flat session list with a file-explorer sidebar.
Highlights
getAll()+ slice) — stays fast at thousands of sessions.Notes for reviewers
src/renderer; diff is againstmain.groupIdand initializes the group list.Closes #3772 if accepted (design-dependent).