From e72265635fcb65ea1b8df29fc54097bfeee1cf9b Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 2 Feb 2026 17:14:54 -0800 Subject: [PATCH] Add support for .agents for skills resolution (#292428) --- .../promptSyntax/config/promptFileLocations.ts | 4 ++++ .../promptSyntax/service/promptsServiceImpl.ts | 6 ++++++ .../common/promptSyntax/config/config.test.ts | 14 +++++++++++++- .../utils/promptFilesLocator.test.ts | 16 ++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/common/promptSyntax/config/promptFileLocations.ts b/src/vs/workbench/contrib/chat/common/promptSyntax/config/promptFileLocations.ts index 713ddaaad3b..3e7dcd49add 100644 --- a/src/vs/workbench/contrib/chat/common/promptSyntax/config/promptFileLocations.ts +++ b/src/vs/workbench/contrib/chat/common/promptSyntax/config/promptFileLocations.ts @@ -67,6 +67,8 @@ export enum PromptFileSource { CopilotPersonal = 'copilot-personal', ClaudePersonal = 'claude-personal', ClaudeWorkspace = 'claude-workspace', + AgentsWorkspace = 'agents-workspace', + AgentsPersonal = 'agents-personal', ConfigWorkspace = 'config-workspace', ConfigPersonal = 'config-personal', ExtensionContribution = 'extension-contribution', @@ -114,8 +116,10 @@ export interface IResolvedPromptFile { */ export const DEFAULT_SKILL_SOURCE_FOLDERS: readonly IPromptSourceFolder[] = [ { path: '.github/skills', source: PromptFileSource.GitHubWorkspace, storage: PromptsStorage.local }, + { path: '.agents/skills', source: PromptFileSource.AgentsWorkspace, storage: PromptsStorage.local }, { path: '.claude/skills', source: PromptFileSource.ClaudeWorkspace, storage: PromptsStorage.local }, { path: '~/.copilot/skills', source: PromptFileSource.CopilotPersonal, storage: PromptsStorage.user }, + { path: '~/.agents/skills', source: PromptFileSource.AgentsPersonal, storage: PromptsStorage.user }, { path: '~/.claude/skills', source: PromptFileSource.ClaudePersonal, storage: PromptsStorage.user }, ]; diff --git a/src/vs/workbench/contrib/chat/common/promptSyntax/service/promptsServiceImpl.ts b/src/vs/workbench/contrib/chat/common/promptSyntax/service/promptsServiceImpl.ts index 161e73495b6..35e3fee0fe4 100644 --- a/src/vs/workbench/contrib/chat/common/promptSyntax/service/promptsServiceImpl.ts +++ b/src/vs/workbench/contrib/chat/common/promptSyntax/service/promptsServiceImpl.ts @@ -792,6 +792,8 @@ export class PromptsService extends Disposable implements IPromptsService { claudeWorkspace: number; copilotPersonal: number; githubWorkspace: number; + agentsPersonal: number; + agentsWorkspace: number; configPersonal: number; configWorkspace: number; extensionContribution: number; @@ -809,6 +811,8 @@ export class PromptsService extends Disposable implements IPromptsService { claudeWorkspace: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of Claude workspace skills.' }; copilotPersonal: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of Copilot personal skills.' }; githubWorkspace: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of GitHub workspace skills.' }; + agentsPersonal: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of .agents personal skills.' }; + agentsWorkspace: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of .agents workspace skills.' }; configPersonal: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of custom configured personal skills.' }; configWorkspace: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of custom configured workspace skills.' }; extensionContribution: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of extension contributed skills.' }; @@ -828,6 +832,8 @@ export class PromptsService extends Disposable implements IPromptsService { claudeWorkspace: skillsBySource.get(PromptFileSource.ClaudeWorkspace) ?? 0, copilotPersonal: skillsBySource.get(PromptFileSource.CopilotPersonal) ?? 0, githubWorkspace: skillsBySource.get(PromptFileSource.GitHubWorkspace) ?? 0, + agentsPersonal: skillsBySource.get(PromptFileSource.AgentsPersonal) ?? 0, + agentsWorkspace: skillsBySource.get(PromptFileSource.AgentsWorkspace) ?? 0, configWorkspace: skillsBySource.get(PromptFileSource.ConfigWorkspace) ?? 0, configPersonal: skillsBySource.get(PromptFileSource.ConfigPersonal) ?? 0, extensionContribution: skillsBySource.get(PromptFileSource.ExtensionContribution) ?? 0, diff --git a/src/vs/workbench/contrib/chat/test/common/promptSyntax/config/config.test.ts b/src/vs/workbench/contrib/chat/test/common/promptSyntax/config/config.test.ts index 36f585c0877..a6f8c489206 100644 --- a/src/vs/workbench/contrib/chat/test/common/promptSyntax/config/config.test.ts +++ b/src/vs/workbench/contrib/chat/test/common/promptSyntax/config/config.test.ts @@ -428,7 +428,7 @@ suite('PromptsConfig', () => { test('empty object returns default skill folders', () => { assert.deepStrictEqual( getPaths(PromptsConfig.promptSourceFolders(createMock({}), PromptsType.skill)), - ['.github/skills', '.claude/skills', '~/.copilot/skills', '~/.claude/skills'], + ['.github/skills', '.agents/skills', '.claude/skills', '~/.copilot/skills', '~/.agents/skills', '~/.claude/skills'], 'Must return default skill folders.', ); }); @@ -441,8 +441,10 @@ suite('PromptsConfig', () => { }), PromptsType.skill)), [ '.github/skills', + '.agents/skills', '.claude/skills', '~/.copilot/skills', + '~/.agents/skills', '~/.claude/skills', '/custom/skills', './local/skills', @@ -458,8 +460,10 @@ suite('PromptsConfig', () => { '/custom/skills': true, }), PromptsType.skill)), [ + '.agents/skills', '.claude/skills', '~/.copilot/skills', + '~/.agents/skills', '~/.claude/skills', '/custom/skills', ], @@ -471,8 +475,10 @@ suite('PromptsConfig', () => { assert.deepStrictEqual( getPaths(PromptsConfig.promptSourceFolders(createMock({ '.github/skills': false, + '.agents/skills': false, '.claude/skills': false, '~/.copilot/skills': false, + '~/.agents/skills': false, '~/.claude/skills': false, '/only/custom/skills': true, }), PromptsType.skill)), @@ -494,8 +500,10 @@ suite('PromptsConfig', () => { }), PromptsType.skill)), [ '.github/skills', + '.agents/skills', '.claude/skills', '~/.copilot/skills', + '~/.agents/skills', '~/.claude/skills', '/valid/skills', './another/valid', @@ -508,15 +516,19 @@ suite('PromptsConfig', () => { assert.deepStrictEqual( getPaths(PromptsConfig.promptSourceFolders(createMock({ '.github/skills': true, + '.agents/skills': true, '.claude/skills': true, '~/.copilot/skills': true, + '~/.agents/skills': true, '~/.claude/skills': true, '/extra/skills': true, }), PromptsType.skill)), [ '.github/skills', + '.agents/skills', '.claude/skills', '~/.copilot/skills', + '~/.agents/skills', '~/.claude/skills', '/extra/skills', ], diff --git a/src/vs/workbench/contrib/chat/test/common/promptSyntax/utils/promptFilesLocator.test.ts b/src/vs/workbench/contrib/chat/test/common/promptSyntax/utils/promptFilesLocator.test.ts index 6eb3fd520c9..050d29a767e 100644 --- a/src/vs/workbench/contrib/chat/test/common/promptSyntax/utils/promptFilesLocator.test.ts +++ b/src/vs/workbench/contrib/chat/test/common/promptSyntax/utils/promptFilesLocator.test.ts @@ -2629,8 +2629,10 @@ suite('PromptFilesLocator', () => { '**/skills': true, // disable defaults '.github/skills': false, + '.agents/skills': false, '.claude/skills': false, '~/.copilot/skills': false, + '~/.agents/skills': false, '~/.claude/skills': false, }, ['/Users/legomushroom/repos/vscode'], @@ -2652,8 +2654,10 @@ suite('PromptFilesLocator', () => { '/absolute/path/skills': true, // disable defaults '.github/skills': false, + '.agents/skills': false, '.claude/skills': false, '~/.copilot/skills': false, + '~/.agents/skills': false, '~/.claude/skills': false, }, ['/Users/legomushroom/repos/vscode'], @@ -2676,8 +2680,10 @@ suite('PromptFilesLocator', () => { 'custom/skills': true, // disable defaults '.github/skills': false, + '.agents/skills': false, '.claude/skills': false, '~/.copilot/skills': false, + '~/.agents/skills': false, '~/.claude/skills': false, }, ['/Users/legomushroom/repos/vscode'], @@ -2702,8 +2708,10 @@ suite('PromptFilesLocator', () => { '../shared-skills': true, // disable defaults '.github/skills': false, + '.agents/skills': false, '.claude/skills': false, '~/.copilot/skills': false, + '~/.agents/skills': false, '~/.claude/skills': false, }, ['/Users/legomushroom/repos/vscode'], @@ -2727,8 +2735,10 @@ suite('PromptFilesLocator', () => { '~/my-skills': true, // disable defaults '.github/skills': false, + '.agents/skills': false, '.claude/skills': false, '~/.copilot/skills': false, + '~/.agents/skills': false, '~/.claude/skills': false, }, ['/Users/legomushroom/repos/vscode'], @@ -2755,7 +2765,9 @@ suite('PromptFilesLocator', () => { 'custom-skills': true, // explicitly disable other defaults we don't want for this test '.github/skills': false, + '.agents/skills': false, '~/.copilot/skills': false, + '~/.agents/skills': false, '~/.claude/skills': false, }, [ @@ -2787,7 +2799,9 @@ suite('PromptFilesLocator', () => { '/absolute/skills': true, // absolute - should be filtered out // explicitly disable other defaults we don't want for this test '.github/skills': false, + '.agents/skills': false, '~/.copilot/skills': false, + '~/.agents/skills': false, '~/.claude/skills': false, }, ['/Users/legomushroom/repos/vscode'], @@ -2820,8 +2834,10 @@ suite('PromptFilesLocator', () => { [ // defaults '/Users/legomushroom/repos/vscode/.github/skills', + '/Users/legomushroom/repos/vscode/.agents/skills', '/Users/legomushroom/repos/vscode/.claude/skills', '/Users/legomushroom/.copilot/skills', + '/Users/legomushroom/.agents/skills', '/Users/legomushroom/.claude/skills', // custom '/Users/legomushroom/repos/vscode/custom-skills',