Skip to content

Commit bab22b9

Browse files
authored
fix: emit agent instructions (AGENTS.md, CLAUDE.md, copilot-instructions.md) (#4974)
The provider only iterated chatPromptFileService.instructions, which contains .instructions.md files. Agent instruction files (AGENTS.md, CLAUDE.md, copilot-instructions.md) come from customInstructionsService.getAgentInstructions() and were used as a filter set but never emitted as items when they weren't also in chatPromptFileService.instructions. Now emits agent instructions from getAgentInstructions() first, then iterates chatPromptFileService.instructions while skipping any already emitted URIs.
1 parent 692b298 commit bab22b9

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

src/extension/chatSessions/vscode-node/copilotCLICustomizationProvider.ts

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -95,26 +95,33 @@ export class CopilotCLICustomizationProvider extends Disposable implements vscod
9595
* - on-demand-instructions: files without an applyTo pattern
9696
*/
9797
private async getInstructionItems(token: CancellationToken): Promise<vscode.ChatSessionCustomizationItem[]> {
98-
const agentInstructionUris = new Set(
99-
(await this.customInstructionsService.getAgentInstructions()).map(uri => uri.toString())
100-
);
98+
const agentInstructionUriList = await this.customInstructionsService.getAgentInstructions();
10199

102100
const items: vscode.ChatSessionCustomizationItem[] = [];
101+
const seenUris = new Set<string>();
102+
103+
// Emit agent instruction files (AGENTS.md, CLAUDE.md, copilot-instructions.md)
104+
// that come from customInstructionsService but may not appear in
105+
// chatPromptFileService.instructions.
106+
for (const uri of agentInstructionUriList) {
107+
seenUris.add(uri.toString());
108+
items.push({
109+
uri,
110+
type: vscode.ChatSessionCustomizationType.Instructions,
111+
name: basename(uri),
112+
groupKey: 'agent-instructions',
113+
});
114+
}
103115

104116
for (const instruction of this.chatPromptFileService.instructions) {
105117
const uri = instruction.uri;
106-
const name = deriveNameFromUri(uri, INSTRUCTION_FILE_EXTENSION);
107118

108-
if (agentInstructionUris.has(uri.toString())) {
109-
items.push({
110-
uri,
111-
type: vscode.ChatSessionCustomizationType.Instructions,
112-
name,
113-
groupKey: 'agent-instructions',
114-
});
115-
continue;
119+
if (seenUris.has(uri.toString())) {
120+
continue; // already emitted as agent instruction
116121
}
117122

123+
const name = deriveNameFromUri(uri, INSTRUCTION_FILE_EXTENSION);
124+
118125
let pattern: string | undefined;
119126
let description: string | undefined;
120127
try {

src/extension/chatSessions/vscode-node/test/copilotCLICustomizationProvider.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,22 @@ describe('CopilotCLICustomizationProvider', () => {
348348
expect(instrItems[0].badge).toBeUndefined();
349349
});
350350

351+
it('emits agent instructions not in chatPromptFileService.instructions', async () => {
352+
const agentsUri = URI.file('/workspace/AGENTS.md');
353+
const claudeUri = URI.file('/workspace/CLAUDE.md');
354+
const copilotUri = URI.file('/workspace/.github/copilot-instructions.md');
355+
// Agent instructions are NOT in chatPromptFileService.instructions —
356+
// they come only from customInstructionsService.getAgentInstructions().
357+
mockPromptFileService.setInstructions([]);
358+
mockCustomInstructionsService.setAgentInstructionUris([agentsUri, claudeUri, copilotUri]);
359+
360+
const items = await provider.provideChatSessionCustomizations(undefined!);
361+
const instrItems = items.filter(i => i.type === FakeChatSessionCustomizationType.Instructions);
362+
expect(instrItems).toHaveLength(3);
363+
expect(instrItems.every(i => i.groupKey === 'agent-instructions')).toBe(true);
364+
expect(instrItems.map(i => i.name)).toEqual(['AGENTS.md', 'CLAUDE.md', 'copilot-instructions.md']);
365+
});
366+
351367
it('uses context-instructions groupKey with badge for instructions with applyTo pattern', async () => {
352368
const uri = URI.file('/workspace/.github/style.instructions.md');
353369
mockPromptFileService.setInstructions([{ uri }]);

0 commit comments

Comments
 (0)