From 70bb47bc61f95b1be7de6c6941f31b9159bf4e94 Mon Sep 17 00:00:00 2001 From: Josh Spicer <23246594+joshspicer@users.noreply.github.com> Date: Sun, 5 Apr 2026 19:03:04 -0700 Subject: [PATCH 1/2] fix: exempt agent instructions from workspace subpath filter AGENTS.md, CLAUDE.md, and copilot-instructions.md live at the workspace root by design. The CLI harness restricts items to workspaceSubpaths (.github, .copilot, .agents, .claude) which filtered out these root-level agent instruction files. Now items with groupKey 'agent-instructions' are exempt from the subpath filter, matching the existing exemption for instructionFileFilter patterns. --- .../browser/aiCustomization/aiCustomizationListWidget.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationListWidget.ts b/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationListWidget.ts index f6f9955e39762c..40cdca1609ac98 100644 --- a/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationListWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationListWidget.ts @@ -1609,6 +1609,12 @@ export class AICustomizationListWidget extends Disposable { if (instrFilter && promptType === PromptsType.instructions && matchesInstructionFileFilter(item.uri.path, instrFilter)) { continue; } + // Keep agent instruction files (AGENTS.md, CLAUDE.md, copilot-instructions.md) + // — these live at the workspace root by design and should not be + // filtered out by workspace subpath restrictions. + if (item.groupKey === 'agent-instructions') { + continue; + } items.splice(i, 1); } } From 446d7308520822a6592b56b988a32e7feb2e0a0e Mon Sep 17 00:00:00 2001 From: Josh Spicer <23246594+joshspicer@users.noreply.github.com> Date: Fri, 3 Apr 2026 15:50:37 -0700 Subject: [PATCH 2/2] sessions: include AGENTS.md in instructions listing The sessions AI customization tree view and overview were only calling listPromptFiles(PromptsType.instructions) to discover instruction files. However, AGENTS.md (along with CLAUDE.md and copilot-instructions.md) is classified as an agent type by getPromptFileType(), so it was never returned by that call. Fix by also calling listAgentInstructions() and merging the results (deduplicating by URI), matching the pattern already used by the workbench customization editor. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../browser/aiCustomizationOverviewView.ts | 12 ++++++++++++ .../browser/aiCustomizationTreeViewViews.ts | 15 ++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationOverviewView.ts b/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationOverviewView.ts index b9fd774f52a775..9066280ddfa4a1 100644 --- a/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationOverviewView.ts +++ b/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationOverviewView.ts @@ -19,6 +19,7 @@ import { IContextKeyService } from '../../../../platform/contextkey/common/conte import { IOpenerService } from '../../../../platform/opener/common/opener.js'; import { IThemeService } from '../../../../platform/theme/common/themeService.js'; import { IHoverService } from '../../../../platform/hover/browser/hover.js'; +import { ResourceSet } from '../../../../base/common/map.js'; import { IPromptsService } from '../../../../workbench/contrib/chat/common/promptSyntax/service/promptsService.js'; import { PromptsType } from '../../../../workbench/contrib/chat/common/promptSyntax/promptTypes.js'; import { AICustomizationManagementSection } from '../../../../workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagement.js'; @@ -171,6 +172,17 @@ export class AICustomizationOverviewView extends ViewPane { } else { const allItems = await this.promptsService.listPromptFiles(type, CancellationToken.None); count = allItems.length; + + // For instructions, also count agent instructions (AGENTS.md, copilot-instructions.md, CLAUDE.md, etc.) + if (type === PromptsType.instructions) { + const existingUris = new ResourceSet(allItems.map(item => item.uri)); + const agentInstructions = await this.promptsService.listAgentInstructions(CancellationToken.None); + for (const file of agentInstructions) { + if (!existingUris.has(file.uri)) { + count++; + } + } + } } const sectionData = this.sections.find(s => s.id === section); diff --git a/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationTreeViewViews.ts b/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationTreeViewViews.ts index f5cfae860f42ec..aaeb0351e0c7b2 100644 --- a/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationTreeViewViews.ts +++ b/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationTreeViewViews.ts @@ -27,6 +27,7 @@ import { IThemeService } from '../../../../platform/theme/common/themeService.js import { IViewPaneOptions, ViewPane } from '../../../../workbench/browser/parts/views/viewPane.js'; import { IViewDescriptorService } from '../../../../workbench/common/views.js'; import { IPromptsService, PromptsStorage, IAgentSkill, IPromptPath } from '../../../../workbench/contrib/chat/common/promptSyntax/service/promptsService.js'; +import { ResourceSet } from '../../../../base/common/map.js'; import { PromptsType } from '../../../../workbench/contrib/chat/common/promptSyntax/promptTypes.js'; import { agentIcon, extensionIcon, instructionsIcon, mcpServerIcon, pluginIcon, promptIcon, skillIcon, userIcon, workspaceIcon, builtinIcon } from '../../../../workbench/contrib/chat/browser/aiCustomization/aiCustomizationIcons.js'; import { AICustomizationItemMenuId } from './aiCustomizationTreeView.js'; @@ -446,7 +447,19 @@ class UnifiedAICustomizationDataSource implements IAsyncDataSource item.uri)); + const agentInstructions = await this.promptsService.listAgentInstructions(CancellationToken.None); + for (const file of agentInstructions) { + if (!existingUris.has(file.uri)) { + allItems.push({ uri: file.uri, storage: PromptsStorage.local, type: PromptsType.instructions }); + } + } + } + const workspaceItems = allItems.filter(item => item.storage === PromptsStorage.local); const userItems = allItems.filter(item => item.storage === PromptsStorage.user); const extensionItems = allItems.filter(item => item.storage === PromptsStorage.extension);