Repository: microsoft/vscode
File: src/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptValidator.ts (TypeScript)

Code before:

/**
 * Attributes supported in Claude rules files (`.claude/rules/*.md`).
 * Claude rules use `paths` instead of `applyTo` for glob patterns.
 */
export const claudeRulesAttributes: Record<string, { type: string; description: string; defaults?: string[]; items?: IValueEntry[]; enums?: IValueEntry[] }> = {
	'description': {
		type: 'scalar',
		description: localize('attribute.rules.description', "A description of what this rule covers, used to provide context about when it applies."),
	},
	'paths': {
		type: 'sequence',
		description: localize('attribute.rules.paths', "Array of glob patterns that describe for which files the rule applies. Based on these patterns, the file is automatically included in the prompt when the context contains a file that matches.\nExample: `['src/**/*.ts', 'test/**']`"),
	},
};

export function isVSCodeOrDefaultTarget(target: Target): boolean {
	return target === Target.VSCode || target === Target.Undefined;
}

export function getTarget(promptType: PromptsType, header: PromptHeader | URI): Target {
	const uri = header instanceof URI ? header : header.uri;
	if (promptType === PromptsType.agent) {
		const parentDir = dirname(uri);
		if (parentDir.path.endsWith(`/${CLAUDE_AGENTS_SOURCE_FOLDER}`)) {
			return Target.Claude;
		}
		if (!(header instanceof URI)) {
			const target = header.target;
			if (target === Target.GitHubCopilot || target === Target.VSCode) {
				return target;
			}
		}
		return Target.Undefined;
	} else if (promptType === PromptsType.instructions) {
		if (isInClaudeRulesFolder(uri)) {
			return Target.Claude;
		}
	}
	return Target.Undefined;
}

function toMarker(message: string, range: Range, severity = MarkerSeverity.Error): IMarkerData {
	return { severity, message, ...range };
}

export class PromptValidatorContribution extends Disposable {

	private readonly validator: PromptValidator;
	private readonly localDisposables = this._register(new DisposableStore());


Review comment (suggestion):
That's not correct, for agents from `.copilot/agents`, we use the `target` property from the header

Code after:
/**
 * Attributes supported in Claude rules files (`.claude/rules/*.md`).
 * Claude rules use `paths` instead of `applyTo` for glob patterns.
 */
export const claudeRulesAttributes: Record<string, { type: string; description: string; defaults?: string[]; items?: IValueEntry[]; enums?: IValueEntry[] }> = {
	'description': {
		type: 'scalar',
		description: localize('attribute.rules.description', "A description of what this rule covers, used to provide context about when it applies."),
	},
	'paths': {
		type: 'sequence',
		description: localize('attribute.rules.paths', "Array of glob patterns that describe for which files the rule applies. Based on these patterns, the file is automatically included in the prompt when the context contains a file that matches.\nExample: `['src/**/*.ts', 'test/**']`"),
	},
};

export function isVSCodeOrDefaultTarget(target: Target): boolean {
	return target === Target.VSCode || target === Target.Undefined;
}

export function getTarget(promptType: PromptsType, header: PromptHeader | URI): Target {
	const uri = header instanceof URI ? header : header.uri;
	if (promptType === PromptsType.agent) {
		if (isInClaudeAgentsFolder(uri)) {
			return Target.Claude;
		}
		if (isInCopilotAgentsFolder(uri)) {
			return Target.GitHubCopilot;
		}
		if (!(header instanceof URI)) {
			const target = header.target;
			if (target === Target.GitHubCopilot || target === Target.VSCode) {
				return target;
			}
		}
		return Target.Undefined;
	} else if (promptType === PromptsType.instructions) {
		if (isInClaudeRulesFolder(uri)) {
			return Target.Claude;
		}
	}
	return Target.Undefined;
}

function toMarker(message: string, range: Range, severity = MarkerSeverity.Error): IMarkerData {
	return { severity, message, ...range };
}

export class PromptValidatorContribution extends Disposable {

	private readonly validator: PromptValidator;
	private readonly localDisposables = this._register(new DisposableStore());