promptFileLocations.ts ×11

Frontier kind: Code frontier

unlabeled · c_f0846befb264

628 tests · 7398 LOC · 35 files · introduces 0 tests · 252 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
11 ranges252 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
846 ranges7398 lines · 35 files · Browse complete extent
All tests (intent)
628 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 252 introduced LOC across 11 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/workbench/contrib/chat/common/promptSyntax/config/promptFileLocations.ts 252 introduced LOC · 11 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- promptFileLocations.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { URI } from '../../../../../../base/common/uri.js';
7 > import { basename, dirname } from '../../../../../../base/common/resources.js';
8 > import { PromptFileSource, PromptsType } from '../promptTypes.js';
9 > import { PromptsStorage } from '../service/promptsService.js';
10 > import { compareIgnoreCase } from '../../../../../../base/common/strings.js';
11 >
12 > /**
13 > * File extension for the reusable prompt files.
14 > */
15 > export const PROMPT_FILE_EXTENSION = '.prompt.md';
16 >
17 > /**
18 > * File extension for the reusable instruction files.
19 > */
20 > export const INSTRUCTION_FILE_EXTENSION = '.instructions.md';
21 >
22 > /**
23 > * File extension for the modes files.
24 > */
25 > export const LEGACY_MODE_FILE_EXTENSION = '.chatmode.md';
26 >
27 > /**
28 > * File extension for the agent files.
29 > */
30 > export const AGENT_FILE_EXTENSION = '.agent.md';
31 >
32 > /**
33 > * Skill file name (case insensitive).
34 > */
35 > export const SKILL_FILENAME = 'SKILL.md';
36 >
37 > /**
38 > * Check if a filename is a skill file (case insensitive).
39 > */
40 > export function isSkillFilename(filename: string): boolean {
41 return compareIgnoreCase(filename, SKILL_FILENAME) === 0;
42 }
44 > /**
45 > * Regex for valid skill names: lowercase alphanumeric and hyphens only.
46 > */
47 > export const VALID_SKILL_NAME_REGEX = /^[a-z0-9-]+$/;
48 >
49 > /**
50 > * AGENT file name
51 > */
52 > export const AGENT_MD_FILENAME = 'AGENTS.md';
53 >
54 > /**
55 > * Claude file name.
56 > */
57 > export const CLAUDE_MD_FILENAME = 'CLAUDE.md';
58 >
59 > /**
60 > * Claude local file name.
61 > */
62 > export const CLAUDE_LOCAL_MD_FILENAME = 'CLAUDE.local.md';
63 >
64 > /**
65 > * Claude configuration folder name.
66 > */
67 > export const CLAUDE_CONFIG_FOLDER = '.claude';
68 >
69 > /**
70 > * Copilot configuration folder name.
71 > */
72 > export const COPILOT_CONFIG_FOLDER = '.copilot';
73 >
74 > /**
75 > * Copilot custom instructions file name.
76 > */
77 > export const COPILOT_CUSTOM_INSTRUCTIONS_FILENAME = 'copilot-instructions.md';
78 >
79 > /**
80 > * GitHub configuration folder name.
81 > */
82 > export const GITHUB_CONFIG_FOLDER = '.github';
83 >
84 > /**
85 > * Default reusable prompt files source folder.
86 > */
87 > export const PROMPT_DEFAULT_SOURCE_FOLDER = '.github/prompts';
88 >
89 > /**
90 > * Default reusable instructions files source folder.
91 > */
92 > export const INSTRUCTIONS_DEFAULT_SOURCE_FOLDER = '.github/instructions';
93 >
94 > /**
95 > * Default modes source folder.
96 > */
97 > export const LEGACY_MODE_DEFAULT_SOURCE_FOLDER = '.github/chatmodes';
98 >
99 > /**
100 > * Agents folder.
101 > */
102 > export const AGENTS_SOURCE_FOLDER = '.github/agents';
103 >
104 > /**
105 > * Claude agents folder.
106 > */
107 > export const CLAUDE_AGENTS_SOURCE_FOLDER = '.claude/agents';
108 >
109 > /**
110 > * Copilot user agents folder.
111 > */
112 > export const COPILOT_USER_AGENTS_SOURCE_FOLDER = '~/.copilot/agents';
113 >
114 > /**
115 > * Claude rules folder.
116 > */
117 > export const CLAUDE_RULES_SOURCE_FOLDER = '.claude/rules';
118 >
119 > /**
120 > * Hooks folder.
121 > */
122 > export const HOOKS_SOURCE_FOLDER = '.github/hooks';
123 >
124 > /**
125 > * Subset of {@link PromptFileSource} values that can appear on folder-based
126 > * prompt source configurations (excludes extension/plugin-only sources).
127 > */
128 > export type PromptFolderSource = Exclude<PromptFileSource, PromptFileSource.ExtensionContribution | PromptFileSource.ExtensionAPI | PromptFileSource.Plugin>;
129 >
130 > /**
131 > * Prompt source folder path with source and storage type.
132 > */
133 > export interface IPromptSourceFolder {
134 > readonly path: string;
135 > readonly source: PromptFolderSource;
136 > readonly storage: PromptsStorage.local | PromptsStorage.user;
137 > }
138 >
139 > /**
140 > * Resolved prompt folder with source and storage type.
141 > */
142 > export interface IResolvedPromptSourceFolder {
143 > readonly uri: URI;
144 > readonly searchRoot: URI; // matches the URI when no glob pattern is used
145 > readonly filePattern: string | undefined; // the part of the path with the glob pattern, or undefined if no glob pattern is used
146 > readonly source: PromptFolderSource;
147 > readonly storage: PromptsStorage.local | PromptsStorage.user;
148 > /**
149 > * The original path string before resolution (e.g., '~/.copilot/agents' or '.github/agents').
150 > * Used for display purposes.
151 > */
152 > readonly displayPath?: string;
153 > /**
154 > * Whether this is a default location (vs user-configured).
155 > */
156 > readonly isDefault?: boolean;
157 > }
158 >
159 > /**
160 > * All default skill source folders (both workspace and user home).
161 > */
162 > export const DEFAULT_SKILL_SOURCE_FOLDERS: readonly IPromptSourceFolder[] = [
163 > { path: '.agents/skills', source: PromptFileSource.AgentsWorkspace, storage: PromptsStorage.local },
164 > { path: '.github/skills', source: PromptFileSource.GitHubWorkspace, storage: PromptsStorage.local },
165 > { path: '.claude/skills', source: PromptFileSource.ClaudeWorkspace, storage: PromptsStorage.local },
166 > { path: '~/.agents/skills', source: PromptFileSource.AgentsPersonal, storage: PromptsStorage.user },
167 > { path: '~/.copilot/skills', source: PromptFileSource.CopilotPersonal, storage: PromptsStorage.user },
168 > { path: '~/.claude/skills', source: PromptFileSource.ClaudePersonal, storage: PromptsStorage.user },
169 > ];
170 >
171 > /**
172 > * Default instructions source folders.
173 > */
174 > export const DEFAULT_INSTRUCTIONS_SOURCE_FOLDERS: readonly IPromptSourceFolder[] = [
175 > { path: INSTRUCTIONS_DEFAULT_SOURCE_FOLDER, source: PromptFileSource.GitHubWorkspace, storage: PromptsStorage.local },
176 > { path: CLAUDE_RULES_SOURCE_FOLDER, source: PromptFileSource.ClaudeWorkspace, storage: PromptsStorage.local },
177 > { path: '~/.copilot/instructions', source: PromptFileSource.CopilotPersonal, storage: PromptsStorage.user },
178 > { path: '~/' + CLAUDE_RULES_SOURCE_FOLDER, source: PromptFileSource.ClaudePersonal, storage: PromptsStorage.user },
179 > ];
180 >
181 > /**
182 > * Default prompt source folders.
183 > */
184 > export const DEFAULT_PROMPT_SOURCE_FOLDERS: readonly IPromptSourceFolder[] = [
185 > { path: PROMPT_DEFAULT_SOURCE_FOLDER, source: PromptFileSource.GitHubWorkspace, storage: PromptsStorage.local },
186 > ];
187 >
188 > /**
189 > * Default agent source folders.
190 > */
191 > export const DEFAULT_AGENT_SOURCE_FOLDERS: readonly IPromptSourceFolder[] = [
192 > { path: AGENTS_SOURCE_FOLDER, source: PromptFileSource.GitHubWorkspace, storage: PromptsStorage.local },
193 > { path: CLAUDE_AGENTS_SOURCE_FOLDER, source: PromptFileSource.ClaudeWorkspace, storage: PromptsStorage.local },
194 > { path: COPILOT_USER_AGENTS_SOURCE_FOLDER, source: PromptFileSource.CopilotPersonal, storage: PromptsStorage.user },
195 > { path: '~/' + CLAUDE_AGENTS_SOURCE_FOLDER, source: PromptFileSource.ClaudePersonal, storage: PromptsStorage.user },
196 > ];
197 >
198 > /**
199 > * Default hook file paths.
200 > * Entries can be either a directory or a specific file path (.json)
201 > */
202 > export const DEFAULT_HOOK_FILE_PATHS: readonly IPromptSourceFolder[] = [
203 > { path: '.github/hooks', source: PromptFileSource.GitHubWorkspace, storage: PromptsStorage.local },
204 > { path: '.claude/settings.local.json', source: PromptFileSource.ClaudeWorkspaceLocal, storage: PromptsStorage.local },
205 > { path: '.claude/settings.json', source: PromptFileSource.ClaudeWorkspace, storage: PromptsStorage.local },
206 > { path: '~/.copilot/hooks', source: PromptFileSource.CopilotPersonal, storage: PromptsStorage.user },
207 > { path: '~/.claude/settings.json', source: PromptFileSource.ClaudePersonal, storage: PromptsStorage.user },
208 > ];
209 >
210 > /**
211 > * Helper function to check if a file is directly in the .github/agents/ folder (not in subfolders).
212 > */
213 function isInAgentsFolder(fileUri: URI): boolean {
214 const dir = dirname(fileUri).path;
215 return dir.endsWith('/' + AGENTS_SOURCE_FOLDER) || dir.endsWith('/' + CLAUDE_AGENTS_SOURCE_FOLDER) || isInCopilotAgentsFolder(fileUri);
216 }
218 > /**
219 > * Helper function to check if a file is directly in the .claude/agents/ folder.
220 > */
221 > export function isInClaudeAgentsFolder(fileUri: URI): boolean {
222 const dir = dirname(fileUri).path;
223 return dir.endsWith('/' + CLAUDE_AGENTS_SOURCE_FOLDER);
224 }
226 > /**
227 > * Helper function to check if a file is directly in the ~/.copilot/agents/ folder.
228 > */
229 > export function isInCopilotAgentsFolder(fileUri: URI): boolean {
230 const dir = dirname(fileUri).path;
231 return dir.endsWith(COPILOT_USER_AGENTS_SOURCE_FOLDER.substring(1));
232 }
234 > /**
235 > * Helper function to check if a file is inside the .claude/rules/ folder (including subfolders).
236 > * Claude rules files (.md) in this folder are treated as instruction files.
237 > */
238 > export function isInClaudeRulesFolder(fileUri: URI): boolean {
239 const path = fileUri.path;
240 return path.includes('/' + CLAUDE_RULES_SOURCE_FOLDER + '/');
241 }
243 > /**
244 > * Gets the prompt file type from the provided path.
245 > *
246 > * Note: This function assumes the URI is already known to be a prompt file
247 > * (e.g., from a configured prompt source folder). It does not validate that
248 > * arbitrary URIs are prompt files - for example, any .json file will return
249 > * PromptsType.hook regardless of its location.
250 > */
251 > export function getPromptFileType(fileUri: URI): PromptsType | undefined {
252 const filename = basename(fileUri);
253
288 return undefined;
289 }
291 > /**
292 > * Check if provided URI points to a file that with prompt file extension.
293 > */
294 > export function isPromptOrInstructionsFile(fileUri: URI): boolean {
295 return getPromptFileType(fileUri) !== undefined;
296 }
298 > export function getPromptFileExtension(type: PromptsType): string {
299 switch (type) {
300 case PromptsType.instructions:
312 }
313 }
315 > export function getPromptFileDefaultLocations(type: PromptsType): readonly IPromptSourceFolder[] {
316 switch (type) {
317 case PromptsType.instructions:
329 }
330 }
332 > export function getSkillFolderName(fileUri: URI): string {
333 return basename(dirname(fileUri));
334 }
336 > /**
337 > * Gets clean prompt name without file extension.
338 > */
339 > export function getCleanPromptName(fileUri: URI): string {
340 const fileName = basename(fileUri);
341