Sessions: Add "Group by Repository" toggle for sessions list#300297
Merged
Sessions: Add "Group by Repository" toggle for sessions list#300297
Conversation
…tory name extraction
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a Sessions view title-bar toggle to switch session list grouping between date-based sections and repository-based sections, persisting the user’s grouping preference.
Changes:
- Introduces a ViewTitle toggle (two actions) to switch “Group by Date” ↔ “Group by Repository” using a context key to swap icons/visibility.
- Extends
AgentSessionsFilterwith a newRepositorygrouping mode and persists grouping via profile storage. - Implements repository-based grouping in
AgentSessionsDataSource, and widens section identifiers tostringto support dynamic repo section names.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts | Adds repository grouping and repo-name extraction logic for section headers. |
| src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsModel.ts | Widens section id type to string to allow dynamic section names. |
| src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsFilter.ts | Adds Repository grouping + persisted grouping override and setter. |
| src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.ts | Updates collapse-state persistence APIs to accept string section ids. |
| src/vs/sessions/contrib/sessions/browser/sessionsViewPane.ts | Registers ViewTitle actions and a context key to toggle grouping mode. |
Comments suppressed due to low confidence (1)
src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts:956
- Repository grouping is new behavior (
AgentSessionsGrouping.Repository+groupSessionsByRepository+getRepositoryNameparsing), but there are existing unit tests forAgentSessionsDataSourcegrouping behavior and none cover the repository path. Adding tests for: grouping into repo sections, ensuring Archived stays last, and handling "Other"/unknown repo metadata (and at least one URL/NWO parsing case) would help prevent regressions.
private groupSessionsByRepository(sortedSessions: IAgentSession[]): AgentSessionListItem[] {
const repoMap = new Map<string, IAgentSession[]>();
const archivedSessions: IAgentSession[] = [];
const noRepoLabel = localize('agentSessions.noRepository', "Other");
for (const session of sortedSessions) {
if (session.isArchived()) {
archivedSessions.push(session);
continue;
}
const repoName = this.getRepositoryName(session) ?? noRepoLabel;
let group = repoMap.get(repoName);
if (!group) {
group = [];
repoMap.set(repoName, group);
}
group.push(session);
}
const result: AgentSessionListItem[] = [];
for (const [repoName, sessions] of repoMap) {
result.push({
section: `repo-${repoName}`,
label: repoName,
sessions,
});
}
if (archivedSessions.length > 0) {
result.push({
section: AgentSessionSection.Archived,
label: AgentSessionSectionLabels[AgentSessionSection.Archived],
sessions: archivedSessions,
});
}
return result;
}
private getRepositoryName(session: IAgentSession): string | undefined {
const metadata = session.metadata;
if (metadata) {
// Cloud sessions: metadata.name is the repo name
const name = metadata.name as string | undefined;
if (name && typeof name === 'string') {
return name;
}
// repositoryNwo: "owner/repo"
const nwo = metadata.repositoryNwo as string | undefined;
if (nwo && nwo.includes('/')) {
return nwo.split('/').pop()!;
}
// repository: could be "owner/repo" or a URL
const repository = metadata.repository as string | undefined;
if (repository) {
if (repository.includes('/') && !repository.includes(':')) {
return repository.split('/').pop()!;
}
try {
const url = new URL(repository);
const parts = url.pathname.split('/').filter(Boolean);
if (parts.length >= 2) {
return parts[1];
}
} catch {
// not a URL
}
}
// repositoryUrl: "https://github.com/owner/repo"
const repositoryUrl = metadata.repositoryUrl as string | undefined;
if (repositoryUrl) {
try {
const url = new URL(repositoryUrl);
const parts = url.pathname.split('/').filter(Boolean);
if (parts.length >= 2) {
return parts[1];
}
} catch {
// not a URL
}
}
}
// Fallback: extract repo name from badge if it uses the $(repo) icon
const badge = session.badge;
if (badge) {
const raw = typeof badge === 'string' ? badge : badge.value;
const repoMatch = raw.match(/\$\(repo\)\s*(.+)/);
if (repoMatch) {
return repoMatch[1].trim();
}
}
return undefined;
}
src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsFilter.ts
Outdated
Show resolved
Hide resolved
src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsFilter.ts
Outdated
Show resolved
Hide resolved
src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.ts
Show resolved
Hide resolved
- Scope grouping storage key per filter instance (filterMenuId) to avoid cross-instance interference; only enable grouping override when a default grouping is configured - Add isStoringGrouping guard to prevent duplicate onDidChange events when setGrouping writes to storage - Use full owner/repo as section ID for unique grouping; display short repo name as section label Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🔮 易经卜卦分析:Sessions分组功能 此功能求秩序,意在分类管理。以易经观之: 卦象:水地比(比卦)—— 亲比相依,物以类聚 断语:比卦象征亲近与合作。按仓库分组正是比的体现——相关项目相聚,便于管理。吉。 建议:
很好的功能设计! 由AI助手龙虾🦞通过易经智慧分析生成 |
DonJayamanne
previously approved these changes
Mar 10, 2026
Simplify GROUPING_STORAGE_KEY to a static constant instead of per-instance scoped key. The grouping override is guarded by supportsGroupingOverride (only enabled when options.groupResults is configured), which is sufficient to prevent unintended interference. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The filter should work the same regardless of grouping mode. Moved all grouping state management (storage, context key, toggle) to the sessions view pane, which owns it. The filter just receives the current grouping via its existing groupResults option callback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep IAgentSessionSection.section as AgentSessionSection (not string). Revert all changes to agentSessionsControl.ts and agentSessionsModel.ts. Use type assertion for dynamic repo section IDs in the viewer instead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add AgentSessionSection.Repository enum value and use it for all repo group sections. Differentiate repo sections via the identity provider which now includes the label in the section ID. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
refresh() re-resolves all sessions from providers (network calls). update() just re-renders the tree with existing data, which is all that is needed when changing the grouping mode. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
DonJayamanne
approved these changes
Mar 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a toggle button in the sessions view title bar to group sessions by repository instead of by date.
Changes
Sessions View (
sessionsViewPane.ts)$(repo)icon when grouped by date → click to switch to repo grouping$(history)icon when grouped by repo → click to switch back to date groupingRawContextKey(sessionsView.isGroupedByRepository) to control icon visibility viawhenclausesFilter (
agentSessionsFilter.ts)RepositorytoAgentSessionsGroupingenumagentSessions.groupingstorage key)setGrouping()method for the view toggle to control groupingisDefault()andreset()account for grouping stateData Source (
agentSessionsViewer.ts)groupSessionsByRepository()method that groups sessions under repo name section headersgetRepositoryName()to extract repo name from session metadata:metadata.name(cloud sessions)metadata.repositoryNwo(e.g.,microsoft/vscode)metadata.repository/metadata.repositoryUrl(URL parsing)$(repo)prefix as fallbackModel (
agentSessionsModel.ts)IAgentSessionSection.sectiontype fromAgentSessionSectiontostringto support dynamic repository section namesControl (
agentSessionsControl.ts)getSavedCollapseState/saveSectionCollapseStateparameter types tostringto match widened section type