PRD: Normalize VS Code Customization Location Handling
Problem Statement
VS Code customization discovery currently mixes multiple location types and path forms across prompts, agents, hooks, and skills. The result is uneven handling of settings-defined locations, accidental reliance on machine-resolved absolute paths, and incorrect inference of repo-level counterparts from home-directory entries. That ambiguity is a boundary problem: the configured setting entry is the contract, but downstream handling can drift away from that contract.
Goals
- Treat prompts, agents, hooks, and skills as equal first-class customization location types.
- Define normalization in terms of the configured setting key plus the literal configured/default location entry.
- Preserve settings-defined location entries exactly as declared, without expanding them to machine-specific full paths for identity or mapping.
- Prevent inferred repo-level counterparts for home-directory entries.
- Support both directory entries and file entries under the same normalization model.
- Frame this work as an enhancement request: preserve the current normalization contract while identifying missing default entries that leave some customization types incomplete.
- Make the behavior concrete enough to drive implementation and tests.
Non-Goals
- Defining storage, caching, indexing, or UI implementation details unrelated to normalization.
- Redesigning instructions or modes behavior beyond any shared normalization logic they already use.
- Replacing the normalization identity with machine-resolved absolute paths, inferred mirrors, or any other derived form.
In Scope
- chat.promptFilesLocations
- chat.agentFilesLocations
- chat.hookFilesLocations
- chat.agentSkillsLocations
- Enhancement candidates for missing default entries within those same setting families
Current Behavior
- Customization surfaces are not treated consistently even when they are all driven by settings-defined locations.
- Some flows collapse configured entries into expanded machine-specific paths, which makes identity and comparison environment-dependent.
- Home-directory entries can be treated as if they imply repo-local mirrors, even though the setting only declares a home-relative location.
- Hooks are easy to special-case incorrectly because their defaults include both directories and files.
- Prompt locations are notably incomplete relative to the other customization families, which makes cross-type normalization comparisons uneven.
Proposed Behavior
Normalization must operate on the setting entry itself, not on an expanded filesystem path.
Each normalized location is defined by a pair:
- Setting key
- Literal location entry string from that setting
The normalization layer must preserve the literal entry string exactly as configured or provided by defaults. Relative entries, home-relative entries, directory entries, and file entries are all valid first-class values. Prompts, agents, hooks, and skills must all follow this same model.
This PRD is also an enhancement request for the default entry sets themselves. The enhancement must keep the current identity contract intact while adding missing literal entries where a customization type does not cover the expected location families.
Default Locations and Suggested Changes
Current defaults below are the literal setting entries that exist today. Suggested changes are enhancement candidates only; they are not current defaults and must not be represented as if they already exist.
| Customization type |
Setting key |
Current default entries |
Missing for normalization |
Suggested changes |
| Prompts |
chat.promptFilesLocations |
.github/prompts |
Missing most folder families: repo-local .copilot/prompts and .claude/prompts, plus home-relative ~/.copilot/prompts and ~/.claude/prompts |
Add .copilot/prompts, .claude/prompts, ~/.copilot/prompts, ~/.claude/prompts |
| Agents |
chat.agentFilesLocations |
.github/agents, .claude/agents, ~/.copilot/agents |
Missing repo-local .copilot/agents and home-relative ~/.claude/agents |
Add .copilot/agents and ~/.claude/agents |
| Hooks |
chat.hookFilesLocations |
.github/hooks, .claude/settings.local.json, .claude/settings.json, ~/.copilot/hooks, ~/.claude/settings.json |
Missing repo-local .copilot/hooks if hooks are expected to participate in the same repo-local family pattern as prompts, agents, and skills |
Add .copilot/hooks; keep .claude/settings.local.json, .claude/settings.json, and ~/.claude/settings.json as literal file entries rather than translating them into hook directories |
| Skills |
chat.agentSkillsLocations |
.github/skills, .agents/skills, .claude/skills, ~/.copilot/skills, ~/.agents/skills, ~/.claude/skills |
Missing repo-local .copilot/skills |
Add .copilot/skills; retain the existing .agents/skills and ~/.agents/skills entries as-is |
Target Normalized Family Pattern
The normalization identity remains unchanged: each location is still setting key + literal entry string. The enhancement is to make the default entry families more complete without converting any entry into an absolute path or inferred mirror.
For folder-based customization types, the target pattern is a clearer split between current defaults and proposed additions:
- Repo-local families stay literal, such as .github/, .copilot/, .claude/, and existing type-specific variants like .agents/skills where already supported.
- Home-relative families stay literal, such as ~/.copilot/ and ~/.claude/.
- Hook file entries remain first-class literals and are not downgraded or translated just because other types use directories.
Today, prompts cover only one repo-local family, agents cover a partial repo/home mix, hooks mix directories and files with no repo-local .copilot/hooks entry, and skills still lack repo-local .copilot/skills. This enhancement closes those gaps while preserving the rule that normalization is based only on the literal entries the setting declares.
Normalization Rules
- The canonical identifier for a customization location is the combination of setting key and literal location entry.
- The literal location entry must remain unchanged during normalization. Do not resolve it into a machine-specific absolute path for identity, comparison, or mapping.
- The setting key is part of the identity. The same literal entry string under different setting keys is not the same normalized location.
- Repo-relative entries and home-relative entries are distinct and must not be merged or inferred from one another.
- Do not create derived counterparts that are not explicitly declared in the setting value.
- File entries and directory entries must normalize the same way. A hook file entry such as .claude/settings.json is as first-class as a directory entry such as .github/hooks.
- Only entries enabled in the effective setting value participate in the normalized active set.
- If shared normalization code is reused by other location settings, it must preserve the same contract: setting key plus literal entry string.
Explicit Mapping Constraint
The normalization model must not invent repo-level counterparts for home-directory locations.
Example:
- ~/.copilot/skills is a declared default entry in chat.agentSkillsLocations.
- It does not imply a repo-level .copilot/skills location.
- It does not imply .github/skills.
- It does not imply any other sibling or translated path.
The same rule applies to other home-directory entries such as ~/.copilot/agents and ~/.copilot/hooks.
Edge Cases
- Hooks include both directory and file defaults; both must normalize without special-case identity rules.
- A repo-relative entry and a home-relative entry that end with the same segment name remain distinct because their literal setting entries differ.
- If a user configures additional entries, those entries must be normalized exactly as written rather than translated into guessed equivalents.
- Shared logic must not rely on OS-specific path expansion, path separator conversion, or case-folded absolute path comparisons to decide whether two normalized entries are the same.
Acceptance Criteria
- Prompts, agents, hooks, and skills all use the same normalization contract based on setting key plus literal entry string.
- The normalized form for default values can be produced directly from the settings entries listed in this document, without machine-resolved full paths.
- The document clearly separates current default entries from suggested enhancement entries.
- Missing entries are identified explicitly per customization type, with prompts called out as the least complete family and .copilot/skills called out as a suggested skill addition rather than an existing default.
- No repo-level counterpart is inferred from any home-directory entry.
- ~/.copilot/skills remains distinct from every repo-relative location and does not imply .copilot/skills.
- Hook file entries such as .claude/settings.local.json and .claude/settings.json are handled as first-class normalized locations.
- Engineering tests can assert normalized outputs using only the configured/default setting entries.
- Engineering tests cover at least one repo-relative entry, one home-relative entry, and one file-based hook entry.
Open Questions
- Should the same normalization contract be applied uniformly to other chat location settings such as chat.instructionsFilesLocations, even though this enhancement is scoped to prompts, agents, hooks, and skills?
- For downstream consumers, should disabled entries remain visible as metadata, or should normalization expose only the active enabled set?
- Should user-facing diagnostics display only the literal setting entry, or both the setting key and the literal setting entry?
PRD: Normalize VS Code Customization Location Handling
Problem Statement
VS Code customization discovery currently mixes multiple location types and path forms across prompts, agents, hooks, and skills. The result is uneven handling of settings-defined locations, accidental reliance on machine-resolved absolute paths, and incorrect inference of repo-level counterparts from home-directory entries. That ambiguity is a boundary problem: the configured setting entry is the contract, but downstream handling can drift away from that contract.
Goals
Non-Goals
In Scope
Current Behavior
Proposed Behavior
Normalization must operate on the setting entry itself, not on an expanded filesystem path.
Each normalized location is defined by a pair:
The normalization layer must preserve the literal entry string exactly as configured or provided by defaults. Relative entries, home-relative entries, directory entries, and file entries are all valid first-class values. Prompts, agents, hooks, and skills must all follow this same model.
This PRD is also an enhancement request for the default entry sets themselves. The enhancement must keep the current identity contract intact while adding missing literal entries where a customization type does not cover the expected location families.
Default Locations and Suggested Changes
Current defaults below are the literal setting entries that exist today. Suggested changes are enhancement candidates only; they are not current defaults and must not be represented as if they already exist.
Target Normalized Family Pattern
The normalization identity remains unchanged: each location is still
setting key + literal entry string. The enhancement is to make the default entry families more complete without converting any entry into an absolute path or inferred mirror.For folder-based customization types, the target pattern is a clearer split between current defaults and proposed additions:
Today, prompts cover only one repo-local family, agents cover a partial repo/home mix, hooks mix directories and files with no repo-local .copilot/hooks entry, and skills still lack repo-local .copilot/skills. This enhancement closes those gaps while preserving the rule that normalization is based only on the literal entries the setting declares.
Normalization Rules
Explicit Mapping Constraint
The normalization model must not invent repo-level counterparts for home-directory locations.
Example:
The same rule applies to other home-directory entries such as ~/.copilot/agents and ~/.copilot/hooks.
Edge Cases
Acceptance Criteria
Open Questions