mirror of
https://github.com/microsoft/vscode.git
synced 2026-06-06 15:45:54 +01:00
Add agent-customization skill with primitives documentation (#3196)
* Add agent-customization skill with primitives documentation * Update assets/prompts/skills/agent-customization/primitives/workspace-instructions.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: rename agentCustomizationSkill setting to follow Advanced naming convention * Updated skills.md based on spec --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
---
|
||||
name: agent-customization
|
||||
description: 'Work with VS Code agent customization files (.instructions.md, .prompt.md, .agent.md, SKILL.md, copilot-instructions.md, AGENTS.md). Use when asked to: create, update, review, fix, or debug instructions/prompts/agents/skills; save coding preferences or conventions; understand how customization files work; troubleshoot why instructions/skills are not applying or being ignored; compare customization approaches; migrate or refactor existing customizations; set up project guidelines; configure applyTo patterns; define tool restrictions; create reusable workflows; build custom agent modes or personas; package domain knowledge; add frontmatter; fix YAML syntax; or share team standards.'
|
||||
---
|
||||
|
||||
# Agent Customization
|
||||
|
||||
## Decision Flow
|
||||
|
||||
| Primitive | When to Use |
|
||||
|-----------|-------------|
|
||||
| Workspace Instructions | Always-on, applies everywhere in the project |
|
||||
| File Instructions | Explicit via `applyTo` patterns, or on-demand via `description` |
|
||||
| MCP | Integrates external systems, APIs, or data |
|
||||
| Custom Agents | Subagents for context isolation, or multi-stage workflows with tool restrictions |
|
||||
| Prompts | Single focused task with parameterized inputs |
|
||||
| Skills | On-demand workflow with bundled assets (scripts/templates) |
|
||||
|
||||
## Quick Reference
|
||||
|
||||
Consult the reference docs for templates, domain examples, advanced frontmatter options, asset organization, anti-patterns, and creation checklists.
|
||||
|
||||
| Type | File | Location | Key Field | Reference |
|
||||
|------|------|----------|-----------|---------|
|
||||
| Workspace Instructions | `copilot-instructions.md`, `AGENTS.md` | `.github/` or root | N/A (always applies) | [Link](./primitives/workspace-instructions.md) |
|
||||
| File Instructions | `*.instructions.md` | `.github/instructions/` | `applyTo` (explicit), `description` (on-demand) | [Link](./primitives/instructions.md) |
|
||||
| Prompts | `*.prompt.md` | `.github/prompts/` | `description` (required) | [Link](./primitives/prompts.md) |
|
||||
| Custom Agents | `*.agent.md` | `.github/agents/` | `description` (on-demand), `infer` (subagent) | [Link](./primitives/agents.md) |
|
||||
| Skills | `SKILL.md` | `.github/skills/<name>/` | `description` (on-demand) | [Link](./primitives/skills.md) |
|
||||
|
||||
**User-level**: `{{USER_PROMPTS_FOLDER}}/` (*.prompt.md, *.instructions.md, *.agent.md; not skills)
|
||||
Customizations roam with user's settings sync
|
||||
|
||||
## Creation Process
|
||||
|
||||
If you need to explore or validate patterns in the codebase, use a read-only subagent. If the ask-questions tool is available, use it to interview the user and clarify requirements.
|
||||
|
||||
Follow these steps when creating any customization file.
|
||||
|
||||
### 1. Determine Scope
|
||||
|
||||
Ask the user where they want the customization:
|
||||
- **Workspace**: For project-specific, team-shared customizations → `.github/` folder
|
||||
- **User profile**: For personal, cross-workspace customizations → `{{USER_PROMPTS_FOLDER}}/`
|
||||
|
||||
### 2. Choose the Right Primitive
|
||||
|
||||
Use the Decision Flow above to select the appropriate file type based on the user's need.
|
||||
|
||||
### 3. Create the File
|
||||
|
||||
Create the file directly at the appropriate path:
|
||||
- Use the location tables in each reference file
|
||||
- Include required frontmatter as needed
|
||||
- Add the body content following the templates
|
||||
|
||||
### 4. Validate
|
||||
|
||||
After creating:
|
||||
- Confirm the file is in the correct location
|
||||
- Verify frontmatter syntax (YAML between `---` markers)
|
||||
- Check that `description` is present and meaningful
|
||||
|
||||
## Edge Cases
|
||||
|
||||
**Instructions vs Skill?** Does this apply to *most* work, or *specific* tasks? Most → Instructions. Specific → Skill.
|
||||
|
||||
**Skill vs Prompt?** Multi-step workflow with bundled assets → Skill. Single focused task with inputs → Prompt.
|
||||
|
||||
**Skill vs Custom Agent?** Same capabilities for all steps → Skill. Need context isolation (subagent returns single output) or different tool restrictions per stage → Custom Agent.
|
||||
@@ -0,0 +1,150 @@
|
||||
# [Custom Agents (.agent.md)](https://code.visualstudio.com/docs/copilot/customization/custom-agents)
|
||||
|
||||
Custom personas with specific tools, instructions, and behaviors.
|
||||
|
||||
## Locations
|
||||
|
||||
| Path | Scope |
|
||||
|------|-------|
|
||||
| `.github/agents/*.agent.md` | Workspace |
|
||||
| `<profile>/agents/*.agent.md` | User profile |
|
||||
|
||||
## Frontmatter
|
||||
|
||||
```yaml
|
||||
---
|
||||
description: "<required>" # For agent picker and subagent discovery
|
||||
name: "Agent Name" # Optional, defaults to filename
|
||||
tools: ["search", "fetch"] # Optional: built-in, MCP (<server>/*), extension
|
||||
model: "Claude Sonnet 4" # Optional, uses picker default
|
||||
argument-hint: "Task..." # Optional, input guidance
|
||||
infer: true # Optional, enable on-demand subagent discovery (default: true)
|
||||
handoffs: [...] # Optional, transitions to other agents
|
||||
---
|
||||
```
|
||||
|
||||
## Tools
|
||||
|
||||
Specify tool names in the `tools` array. Sources: built-in tools, tool sets, MCP servers (`<server>/*`), or extension-contributed tools.
|
||||
|
||||
To discover available tools, search your current tool list or use the tool search capability.
|
||||
|
||||
**Special**: `[]` = no tools, omit = defaults. Body reference: `#tool:<name>`
|
||||
|
||||
### Tool Aliases
|
||||
|
||||
Common aliases for restricting agent capabilities:
|
||||
|
||||
| Alias | Purpose |
|
||||
|-------|---------|
|
||||
| `shell` | Execute shell commands |
|
||||
| `read` | Read file contents |
|
||||
| `edit` | Edit files (exact tools vary) |
|
||||
| `search` | Search files or text |
|
||||
| `custom-agent` | Invoke other custom agents as subagents |
|
||||
| `web` | Fetch URLs and web search |
|
||||
| `todo` | Create and manage task lists |
|
||||
|
||||
### Common Restriction Patterns
|
||||
|
||||
```yaml
|
||||
# Read-only agent (no editing, no execution)
|
||||
tools: ["read", "search"]
|
||||
|
||||
# MCP-only agent
|
||||
tools: ["myserver/*"]
|
||||
|
||||
# No terminal access
|
||||
tools: ["read", "edit", "search"]
|
||||
|
||||
# Planning agent (research only)
|
||||
tools: ["search", "web", "read"]
|
||||
```
|
||||
|
||||
For the full list of available tools, see the [VS Code documentation](https://code.visualstudio.com/docs/copilot/customization/custom-agents).
|
||||
|
||||
## Template
|
||||
|
||||
```markdown
|
||||
---
|
||||
description: "Generate implementation plans"
|
||||
tools: ["search", "fetch", "githubRepo", "usages"]
|
||||
---
|
||||
You are in planning mode. Generate plans, don't edit code. Include: Overview, Requirements, Steps, Testing.
|
||||
```
|
||||
|
||||
## Invocation
|
||||
|
||||
- **Manual**: Agents dropdown or `Chat: Switch Agent...` command
|
||||
- **On-demand (subagent)**: When `infer: true`, parent agent can delegate based on `description` match—like skills and instructions
|
||||
|
||||
## When to Use
|
||||
|
||||
**Key Signal**: Orchestrated multi-stage processes with role-based tool restrictions. Different stages need different capabilities or strict handoffs.
|
||||
|
||||
## Domain Examples
|
||||
|
||||
| Domain | Example Workflow |
|
||||
|--------|------------------|
|
||||
| Engineering | planner → implementer → reviewer → deployer |
|
||||
| Product | research → strategy → execution → measurement |
|
||||
| Analytics | scope → build → analyze → report |
|
||||
| Support | triage → troubleshoot → escalate → close |
|
||||
| Content | research → write → edit → publish |
|
||||
|
||||
## Creation Process
|
||||
|
||||
### 1. Gather Requirements
|
||||
|
||||
- What role or persona should this agent embody?
|
||||
- What specific tools does this role need (and which should it NOT have)?
|
||||
- Should this be workspace-specific or personal (user profile)?
|
||||
- Will this agent hand off to other agents?
|
||||
|
||||
### 2. Determine Location
|
||||
|
||||
| Scope | Path |
|
||||
|-------|------|
|
||||
| Workspace | `.github/agents/<name>.agent.md` |
|
||||
| User profile | `<profile>/agents/<name>.agent.md` |
|
||||
|
||||
### 3. Create the File
|
||||
|
||||
```markdown
|
||||
---
|
||||
description: "<role description for agent picker>"
|
||||
tools: ["<minimal tool set>"]
|
||||
---
|
||||
You are a <role>. Your responsibilities:
|
||||
- <primary responsibility>
|
||||
- <constraints on behavior>
|
||||
|
||||
<Specific instructions for this role>
|
||||
```
|
||||
|
||||
### 4. Configure Handoffs (optional)
|
||||
|
||||
If this agent is part of a workflow:
|
||||
```yaml
|
||||
handoffs:
|
||||
- agent: "next-stage-agent"
|
||||
condition: "When <trigger condition>"
|
||||
```
|
||||
|
||||
## Core Principles
|
||||
|
||||
1. **Single role per agent**: Each agent embodies one persona with focused responsibilities
|
||||
2. **Minimal tool set**: Only include tools required for the role—excess tools dilute focus and increase risk
|
||||
3. **Clear boundaries**: Define what the agent should NOT do as clearly as what it should do
|
||||
4. **Explicit handoffs**: When workflows span agents, define clear transition triggers
|
||||
5. **Discoverable via description**: The `description` field drives agent picker display—make it actionable
|
||||
6. **Keyword-rich for subagent discovery**: When `infer: true`, the `description` determines automatic delegation—include trigger words and use cases so the parent agent knows when to invoke this subagent
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
- **Swiss-army agents**: Agents with many tools that try to do everything
|
||||
- **Missing constraints**: Agents without clear boundaries on what they shouldn't attempt
|
||||
- **Role confusion**: Description doesn't match the persona defined in the body
|
||||
- **Circular handoffs**: Agent A hands to B which hands back to A without progress criteria
|
||||
- **Tool sprawl**: Using `tools: []` to disable all tools when specific restrictions would suffice
|
||||
- **Vague subagent descriptions**: Generic descriptions like "A helpful agent" that don't help the parent decide when to delegate—use phrases like "use proactively after code changes" for clear triggers
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
# [File-Specific Instructions (.instructions.md)](https://code.visualstudio.com/docs/copilot/customization/custom-instructions)
|
||||
|
||||
Conditional guidelines that apply to specific file types, folders, or tasks using glob patterns.
|
||||
|
||||
## Locations
|
||||
|
||||
| Path | Scope |
|
||||
|------|-------|
|
||||
| `.github/instructions/*.instructions.md` | Workspace |
|
||||
| `<profile>/instructions/*.instructions.md` | User profile (cross-workspace) |
|
||||
|
||||
## Frontmatter
|
||||
|
||||
```yaml
|
||||
---
|
||||
description: "<required>" # For on-demand discovery (like skills)
|
||||
name: "Instruction Name" # Optional, defaults to filename
|
||||
applyTo: "**/*.ts" # Optional, explicit trigger for file patterns
|
||||
---
|
||||
```
|
||||
|
||||
## applyTo Patterns
|
||||
|
||||
| Pattern | Effect |
|
||||
|---------|--------|
|
||||
| `"**"` | Always include |
|
||||
| `"**/*.ts"` | Match .ts files |
|
||||
| `["src/**", "lib/**"]` | Match multiple (OR) |
|
||||
| `"**/test/**"` | Match paths containing test |
|
||||
| `"src/api/**/*.ts"` | Match specific folder + extension |
|
||||
|
||||
**Trigger**: Applied when creating or modifying files that match the pattern. Not applied for read-only operations.
|
||||
|
||||
**No applyTo**: Instructions can still be loaded implicitly via `description` matching, or manually attached via `Add Context > Instructions`.
|
||||
|
||||
## Template
|
||||
|
||||
```markdown
|
||||
---
|
||||
description: "TypeScript coding standards"
|
||||
applyTo: "**/*.ts"
|
||||
---
|
||||
# TypeScript Guidelines
|
||||
|
||||
- Use `interface` for object shapes, `type` for unions
|
||||
- Avoid `any`, enable strict mode
|
||||
- JSDoc for public APIs
|
||||
- Reference tools with #tool:<name> syntax
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Language-Specific
|
||||
|
||||
```yaml
|
||||
# python-standards.instructions.md
|
||||
---
|
||||
description: "Python coding standards"
|
||||
applyTo: "**/*.py"
|
||||
---
|
||||
```
|
||||
|
||||
### Framework-Specific
|
||||
|
||||
```yaml
|
||||
# react-components.instructions.md
|
||||
---
|
||||
description: "React component patterns"
|
||||
applyTo: ["src/components/**", "src/pages/**"]
|
||||
---
|
||||
```
|
||||
|
||||
### Folder-Specific
|
||||
|
||||
```yaml
|
||||
# backend-api.instructions.md
|
||||
---
|
||||
description: "Backend API conventions"
|
||||
applyTo: "src/api/**"
|
||||
---
|
||||
```
|
||||
|
||||
### Task-Based (On-Demand)
|
||||
|
||||
```yaml
|
||||
# database-migrations.instructions.md
|
||||
---
|
||||
description: "Database migration patterns and best practices"
|
||||
# No applyTo—loaded implicitly when the agent detects migration-related tasks
|
||||
---
|
||||
```
|
||||
|
||||
## Invocation
|
||||
|
||||
- **Explicit (applyTo)**: Auto-attaches when files matching the glob pattern are in context (creating/modifying)
|
||||
- **Implicit (description)**: Agent loads on-demand when the description fits the current task—like skills
|
||||
- **Manual**: Chat view → `Add Context` → `Instructions`
|
||||
- **Configure**: Chat view → gear icon → `Chat Instructions`
|
||||
- **New file**: `Chat: New Instructions File` command
|
||||
|
||||
## Settings
|
||||
|
||||
| Setting | Purpose |
|
||||
|---------|---------|
|
||||
| `chat.instructionsFilesLocations` | Additional folders to search for `.instructions.md` |
|
||||
|
||||
## Task-Specific Settings (deprecated)
|
||||
|
||||
Prefer `.instructions.md` files. Legacy settings for specific workflows:
|
||||
|
||||
| Setting | Scenario |
|
||||
|---------|----------|
|
||||
| `github.copilot.chat.reviewSelection.instructions` | Code review |
|
||||
| `github.copilot.chat.commitMessageGeneration.instructions` | Commit messages |
|
||||
| `github.copilot.chat.pullRequestDescriptionGeneration.instructions` | PR descriptions |
|
||||
|
||||
## When to Use
|
||||
|
||||
- **Language-specific rules** (Python style, TypeScript patterns) → use `applyTo`
|
||||
- **Framework conventions** (React, Vue, backend frameworks) → use `applyTo`
|
||||
- **Folder-based guidelines** (frontend vs backend, tests vs source) → use `applyTo`
|
||||
- **Task-focused instructions** (API development, migrations, refactoring) → rely on `description` for on-demand loading
|
||||
|
||||
**Key Signal**: Use `applyTo` when the instruction is file-based; use a descriptive `description` when the instruction is task-based.
|
||||
|
||||
## Creation Process
|
||||
|
||||
### 1. Gather Requirements
|
||||
|
||||
- **File-based or task-based?** Use `applyTo` for file patterns; omit for task-focused instructions loaded via `description`
|
||||
- What file types, folders, or patterns should this apply to?
|
||||
- What coding standards, conventions, or guidelines are needed? Research current codebase using a subagent if needed.
|
||||
- Should this be workspace-specific or personal (user profile)?
|
||||
|
||||
### 2. Determine Location
|
||||
|
||||
| Scope | Path |
|
||||
|-------|------|
|
||||
| Workspace | `.github/instructions/<name>.instructions.md` |
|
||||
| User profile | `<profile>/instructions/<name>.instructions.md` |
|
||||
|
||||
### 3. Create the File
|
||||
|
||||
```markdown
|
||||
---
|
||||
description: "<clear, concise description>"
|
||||
applyTo: "<glob pattern or array>" # Optional—omit for task-based instructions
|
||||
---
|
||||
# <Title>
|
||||
|
||||
<Guidelines organized by topic>
|
||||
```
|
||||
|
||||
### 4. Verify Activation
|
||||
|
||||
- For `applyTo` patterns: Create or edit a matching file to confirm auto-attachment
|
||||
- For `description`-based: Perform a task matching the description and verify the instruction is loaded
|
||||
- For manual instructions: Add via `Add Context > Instructions` in chat
|
||||
|
||||
## Core Principles
|
||||
|
||||
1. **Keyword-rich descriptions**: The `description` frontmatter is how instructions are discovered—include relevant trigger words and use cases
|
||||
2. **One concern per file**: Layer multiple instruction files for different concerns (e.g., separate files for testing, styling, documentation)
|
||||
3. **Concise and actionable**: Instructions share context window with conversation—keep them focused
|
||||
4. **Show, don't tell**: Include brief code examples over lengthy explanations
|
||||
5. **Pattern precision**: Use specific `applyTo` patterns to avoid over-matching (e.g., `src/api/**/*.ts` not `**/*.ts`)
|
||||
6. **Reference, don't duplicate**: Use `#tool:<name>` and Markdown links instead of copying content
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
- **Vague descriptions**: Generic descriptions that don't help discovery (e.g., "Helpful coding tips")
|
||||
- **Overly broad patterns**: `applyTo: "**"` with content only relevant to specific files
|
||||
- **Duplicating project docs**: Copying README or CONTRIBUTING content instead of linking
|
||||
- **Mixing concerns**: Combining unrelated guidelines (testing + API design + styling) in one file
|
||||
- **Stale instructions**: Guidelines that contradict current codebase patterns
|
||||
- **Verbose prose**: Long paragraphs instead of actionable bullet points
|
||||
@@ -0,0 +1,119 @@
|
||||
# [Prompts (.prompt.md)](https://code.visualstudio.com/docs/copilot/customization/prompt-files)
|
||||
|
||||
Reusable task templates triggered on-demand in chat.
|
||||
|
||||
## Locations
|
||||
|
||||
| Path | Scope |
|
||||
|------|-------|
|
||||
| `.github/prompts/*.prompt.md` | Workspace |
|
||||
| `<profile>/prompts/*.prompt.md` | User profile |
|
||||
|
||||
## Frontmatter
|
||||
|
||||
```yaml
|
||||
---
|
||||
description: "<required>" # Prompt description
|
||||
name: "Prompt Name" # Optional, defaults to filename
|
||||
agent: "agent" # Optional: ask, edit, agent, or custom agent
|
||||
tools: ["search", "fetch"] # Optional: built-in, MCP (<server>/*), extension
|
||||
model: "Claude Sonnet 4" # Optional, uses picker default
|
||||
argument-hint: "Task..." # Optional, input guidance
|
||||
---
|
||||
```
|
||||
|
||||
## Variables
|
||||
|
||||
| Syntax | Description |
|
||||
|--------|-------------|
|
||||
| `${workspaceFolder}` | Workspace path |
|
||||
| `${file}`, `${fileBasename}` | Current file |
|
||||
| `${selection}`, `${selectedText}` | Editor selection |
|
||||
| `${input:varName}` | Prompt user for input |
|
||||
| `${input:varName:placeholder}` | With placeholder text |
|
||||
|
||||
**Context references**: Use Markdown links for files, `#tool:<name>` for tools.
|
||||
|
||||
## Template
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: "Create React Form"
|
||||
description: "Generate a React form component"
|
||||
argument-hint: "Provide form requirements"
|
||||
---
|
||||
Generate a React form component with the following requirements:
|
||||
- Use TypeScript and functional components
|
||||
- Include form validation
|
||||
- Follow existing patterns in #tool:codebase
|
||||
```
|
||||
|
||||
## Invocation
|
||||
|
||||
- Chat: Type `/` → select prompt (add extra info: `/create-form formName=MyForm`)
|
||||
- Command: `Chat: Run Prompt...`
|
||||
- Editor: Open prompt file → play button in title bar
|
||||
|
||||
**Tip**: Use `chat.promptFilesRecommendations` to show prompts as actions when starting a new chat.
|
||||
|
||||
## Tool Priority
|
||||
|
||||
When prompt references an agent, tools are resolved: prompt tools → agent tools → default agent tools.
|
||||
|
||||
## When to Use
|
||||
|
||||
**Key Signal**: Single focused task with parameterized inputs. Reusable prompt run once per task with different inputs each time.
|
||||
|
||||
- Generate test cases for specific code
|
||||
- Summarize metrics with custom parameters
|
||||
- Create READMEs from specs
|
||||
- One-off generation tasks
|
||||
|
||||
## Creation Process
|
||||
|
||||
### 1. Gather Requirements
|
||||
|
||||
- What specific task should this prompt accomplish?
|
||||
- What inputs/variables does the user need to provide?
|
||||
- Should this be workspace-specific or personal (user profile)?
|
||||
- Does it need specific tools or a particular agent mode?
|
||||
|
||||
### 2. Determine Location
|
||||
|
||||
| Scope | Path |
|
||||
|-------|------|
|
||||
| Workspace | `.github/prompts/<name>.prompt.md` |
|
||||
| User profile | `<profile>/prompts/<name>.prompt.md` |
|
||||
|
||||
### 3. Create the File
|
||||
|
||||
```markdown
|
||||
---
|
||||
description: "<what this prompt does>"
|
||||
argument-hint: "<guidance for user input>"
|
||||
---
|
||||
<Clear task instructions with ${variables} for user input>
|
||||
|
||||
<Examples of expected output if helpful>
|
||||
```
|
||||
|
||||
### 4. Test the Prompt
|
||||
|
||||
- Ask the user to invoke with `/prompt-name` in chat
|
||||
- Confirm output matches intended behavior
|
||||
|
||||
## Core Principles
|
||||
|
||||
1. **Single task focus**: One prompt = one well-defined task; don't combine unrelated operations
|
||||
2. **Clear input contract**: Use `${input:varName:placeholder}` with descriptive placeholders
|
||||
3. **Output examples**: Show expected output format when quality depends on specific structure
|
||||
4. **Reuse over duplication**: Reference instruction files instead of copying guidelines
|
||||
5. **Appropriate tooling**: Only specify `tools` when the task requires more than defaults
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
- **Multi-task prompts**: Combining "create and test and deploy" in one prompt
|
||||
- **Missing context**: Prompts that assume knowledge not provided in variables
|
||||
- **Hardcoded values**: Embedding specific file paths or names instead of using variables
|
||||
- **Vague descriptions**: Descriptions that don't help users understand when to use the prompt
|
||||
- **Over-tooling**: Specifying many tools when the task only needs search or file access
|
||||
@@ -0,0 +1,182 @@
|
||||
# [Agent Skills (SKILL.md)](https://code.visualstudio.com/docs/copilot/customization/agent-skills)
|
||||
|
||||
Folders of instructions, scripts, and resources that agents loads when relevant for specialized tasks.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
.github/skills/<skill-name>/
|
||||
├── SKILL.md # Required
|
||||
├── test-template.js # Scripts
|
||||
├── examples/ # Example scenarios
|
||||
└── docs/ # Additional docs
|
||||
```
|
||||
|
||||
## Locations
|
||||
|
||||
| Path | Scope |
|
||||
|------|-------|
|
||||
| `.github/skills/<name>/` | Project (recommended) |
|
||||
| `.claude/skills/<name>/` | Project (legacy) |
|
||||
| `~/.copilot/skills/<name>/` | Personal (recommended) |
|
||||
| `~/.claude/skills/<name>/` | Personal (legacy) |
|
||||
|
||||
## SKILL.md Format
|
||||
|
||||
### Frontmatter (required)
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: skill-name # Must match parent folder name
|
||||
description: 'What the skill does and when to use it. For on-demand discovery. Max 1024 chars.'
|
||||
---
|
||||
```
|
||||
|
||||
#### `name` field rules
|
||||
|
||||
- **Must match the parent directory name** (e.g., `pdf-processing/SKILL.md` requires `name: pdf-processing`)
|
||||
- 1-64 characters
|
||||
- Lowercase alphanumeric and hyphens only (`a-z`, `0-9`, `-`)
|
||||
- Must not start or end with `-`
|
||||
- Must not contain consecutive hyphens (`--`)
|
||||
|
||||
#### Optional frontmatter fields
|
||||
|
||||
```yaml
|
||||
license: Apache-2.0 # License name or bundled file reference
|
||||
compatibility: Requires git, docker, jq # Environment requirements (max 500 chars)
|
||||
```
|
||||
|
||||
### Body
|
||||
|
||||
- What the skill accomplishes
|
||||
- When to use the skill
|
||||
- Step-by-step procedures
|
||||
- Examples of input/output
|
||||
- References to scripts/resources via relative paths: `[test script](./test-template.js)`
|
||||
|
||||
## Template
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: webapp-testing
|
||||
description: 'Test web applications using Playwright. Use when verifying frontend functionality, debugging UI, capturing screenshots.'
|
||||
---
|
||||
|
||||
# Web Application Testing
|
||||
|
||||
## When to Use
|
||||
|
||||
- Verify frontend functionality
|
||||
- Debug UI behavior
|
||||
- Capture browser screenshots
|
||||
|
||||
## Procedure
|
||||
|
||||
1. Start the web server
|
||||
2. Run tests with `[test script](./test-template.js)`
|
||||
3. Review screenshots in `./screenshots/`
|
||||
|
||||
## References
|
||||
|
||||
- [examples/login-test.js](./examples/login-test.js)
|
||||
```
|
||||
|
||||
## Progressive Loading
|
||||
|
||||
Skills use three-level loading for efficient context:
|
||||
|
||||
1. **Discovery** (~100 tokens): Agent reads `name` and `description` from frontmatter (always available)
|
||||
2. **Instructions** (<5000 tokens recommended): When description matches current task, loads `SKILL.md` body
|
||||
3. **Resources** (as needed): Additional files (scripts, examples) load only when referenced
|
||||
|
||||
Keep file references one level deep from `SKILL.md`. Avoid deeply nested reference chains.
|
||||
|
||||
## When to Use
|
||||
|
||||
**Key Signal**: Repeatable, on-demand workflows with bundled assets (scripts, templates, reference docs).
|
||||
|
||||
## Domain Examples
|
||||
|
||||
| Domain | Examples |
|
||||
|--------|----------|
|
||||
| Engineering | Microservice deployment, incident response runbook, security review |
|
||||
| Product | User research synthesis, roadmap prioritization, launch validation |
|
||||
| Data | Customer segmentation, data quality validation, cohort analysis |
|
||||
| Design | Design critique framework, user flow docs, design-to-dev handoff |
|
||||
| Sales | Enterprise qualification, demo prep checklist, proposal framework |
|
||||
|
||||
## Asset Organization
|
||||
|
||||
| Folder | Purpose |
|
||||
|--------|----------|
|
||||
| `scripts/` | Code that runs each time (profiling, deployment, data fetch) |
|
||||
| `references/` | Docs that clarify complex bits (architecture, API schemas) |
|
||||
| `assets/` | Templates and boilerplate (Terraform, SQL templates, dashboard JSON) |
|
||||
|
||||
## Creation Process
|
||||
|
||||
### 1. Gather Requirements
|
||||
|
||||
- What workflow or domain knowledge should this skill provide?
|
||||
- What resources are needed (scripts, templates, reference docs)?
|
||||
- Should this be project-specific or personal?
|
||||
|
||||
### 2. Determine Location
|
||||
|
||||
| Scope | Path |
|
||||
|-------|------|
|
||||
| Project | `.github/skills/<skill-name>/SKILL.md` |
|
||||
| Personal | `~/.copilot/skills/<skill-name>/SKILL.md` |
|
||||
|
||||
### 3. Create the Skill Folder
|
||||
|
||||
```
|
||||
<skill-name>/
|
||||
├── SKILL.md # Required: instructions and metadata
|
||||
├── scripts/ # Optional: executable code
|
||||
├── references/ # Optional: documentation to load as needed
|
||||
└── assets/ # Optional: templates, boilerplate
|
||||
```
|
||||
|
||||
### 4. Write SKILL.md
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: <skill-name>
|
||||
description: '<keyword-rich description of what and when>'
|
||||
---
|
||||
# <Skill Title>
|
||||
|
||||
## When to Use
|
||||
<Triggers and use cases>
|
||||
|
||||
## Procedure
|
||||
<Step-by-step workflow>
|
||||
|
||||
## Resources
|
||||
- [script.py](./scripts/script.py)
|
||||
- [reference.md](./references/reference.md)
|
||||
```
|
||||
|
||||
### 5. Add Resources
|
||||
|
||||
Create supporting files as needed, referencing them from SKILL.md with relative paths.
|
||||
|
||||
## Core Principles
|
||||
|
||||
1. **Keyword-rich descriptions**: The `description` frontmatter is how skills are discovered—include all relevant trigger words and use cases
|
||||
2. **Progressive loading**: Keep SKILL.md under 500 lines; move detailed content to reference files
|
||||
3. **Relative path references**: Always use `./` relative paths to reference skill resources
|
||||
4. **Minimal context footprint**: Only load resources when needed—context window is shared
|
||||
5. **Self-contained workflows**: Include all procedural knowledge needed to complete the task
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
- **Vague descriptions**: Generic descriptions that don't help discovery (e.g., "A helpful skill")
|
||||
- **Monolithic SKILL.md**: Putting everything in one file instead of using reference files
|
||||
- **Absolute paths**: Using system paths instead of relative references
|
||||
- **Missing procedures**: Descriptions of what but not how—skills need step-by-step guidance
|
||||
- **Untested scripts**: Including scripts without verifying they work in the target environment
|
||||
- **Duplicate content**: Copying reference content into SKILL.md instead of linking
|
||||
- **Name mismatch**: Folder name doesn't match the `name` field in frontmatter
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
# [Workspace Instructions](https://code.visualstudio.com/docs/copilot/customization/custom-instructions)
|
||||
|
||||
Guidelines that automatically apply to all chat requests across your entire workspace.
|
||||
|
||||
## File Types (Choose One)
|
||||
|
||||
Workspaces should have **only one** of these files—not both:
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `.github/copilot-instructions.md` | Project-wide coding standards and preferences (Recommended) |
|
||||
| `AGENTS.md` | Same, but using an open standard |
|
||||
|
||||
## copilot-instructions.md
|
||||
|
||||
Single file at workspace root that applies to every chat request automatically.
|
||||
|
||||
**Location**: `.github/copilot-instructions.md`
|
||||
|
||||
### Template
|
||||
|
||||
```markdown
|
||||
# Project Guidelines
|
||||
|
||||
## Code Style
|
||||
- Use TypeScript strict mode
|
||||
- Prefer functional components in React
|
||||
- Follow existing patterns in the codebase
|
||||
|
||||
## Architecture
|
||||
- Services use dependency injection
|
||||
- All public APIs need JSDoc documentation
|
||||
|
||||
## Testing
|
||||
- Write unit tests for business logic
|
||||
- Use integration tests for API endpoints
|
||||
```
|
||||
|
||||
### Cross-Editor Support
|
||||
|
||||
This file is also detected by GitHub Copilot in Visual Studio and GitHub.com, enabling shared instructions across editors.
|
||||
|
||||
## AGENTS.md
|
||||
|
||||
Instructions for projects using multiple AI agents. Placed at workspace root or in subfolders.
|
||||
|
||||
**Location**: Workspace root, or subfolders. Use `AGENTS.md` files in subfolders for different parts of your project (e.g., frontend vs backend).
|
||||
|
||||
## When to Use
|
||||
|
||||
- **General coding standards** that apply everywhere
|
||||
- **Team preferences** shared through version control
|
||||
- **Project-wide requirements** like testing standards or documentation rules
|
||||
|
||||
**Key Signal**: Context that's always available. Standards, guidelines, and expectations that apply broadly across work.
|
||||
|
||||
## Domain Examples
|
||||
|
||||
| Domain | Examples |
|
||||
|--------|----------|
|
||||
| Engineering | TypeScript strict mode, test coverage, accessibility (WCAG 2.1 AA) |
|
||||
| Product | User stories in briefs, accessibility/i18n in specs |
|
||||
| Data | SQL query comments, metric definitions linked |
|
||||
| Support | Empathetic tone, escalation includes impact/context |
|
||||
| Design | Use shared component library, include error states |
|
||||
|
||||
## Creation Process
|
||||
|
||||
### 1. Assess Existing Instructions
|
||||
|
||||
Check if a workspace instructions file already exists:
|
||||
- `.github/copilot-instructions.md`
|
||||
- `AGENTS.md` at workspace root
|
||||
|
||||
If one exists, update it rather than creating a second file. Workspaces should only have one.
|
||||
|
||||
### 2. Choose File Type (If None Exists)
|
||||
|
||||
| File | Best For |
|
||||
|------|----------|
|
||||
| `copilot-instructions.md` (Recommended) | VS Code/GitHub Copilot-specific, cross-editor support |
|
||||
| `AGENTS.md` | Open standard, supports subfolder organization |
|
||||
|
||||
### 3. Create or Update
|
||||
|
||||
**For copilot-instructions.md**:
|
||||
```
|
||||
.github/copilot-instructions.md
|
||||
```
|
||||
|
||||
**For AGENTS.md** (supports hierarchy):
|
||||
```
|
||||
/AGENTS.md # Root-level defaults
|
||||
/frontend/AGENTS.md # Frontend-specific
|
||||
/backend/AGENTS.md # Backend-specific
|
||||
```
|
||||
|
||||
### 4. Structure Content
|
||||
|
||||
Research existing guidelines and conventions in the workspace using a subagent as needed.
|
||||
|
||||
```markdown
|
||||
# Project Guidelines
|
||||
|
||||
## Code Style
|
||||
<Language and formatting preferences>
|
||||
|
||||
## Architecture
|
||||
<Patterns and structure conventions>
|
||||
|
||||
## Testing
|
||||
<Coverage and testing requirements>
|
||||
```
|
||||
|
||||
## Core Principles
|
||||
|
||||
1. **Concise and actionable**: Every line should guide behavior—remove filler prose
|
||||
2. **Project-specific focus**: Include conventions not obvious from reading the code
|
||||
3. **Link, don't duplicate**: Reference READMEs, ADRs, and docs instead of copying
|
||||
4. **Keep current**: Update when practices change—stale instructions cause confusion
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
- **Using both file types**: Having both `copilot-instructions.md` and `AGENTS.md` in the same workspace
|
||||
- **Duplicating project docs**: Copying README or CONTRIBUTING content instead of linking to them
|
||||
- **Obvious instructions**: Stating conventions already enforced by linters or obvious from code
|
||||
- **Verbose prose**: Long explanations instead of clear, scannable guidelines
|
||||
- **Stale content**: Instructions that no longer match actual project practices
|
||||
- **Kitchen sink**: Trying to include every possible guideline instead of focusing on what matters most
|
||||
@@ -4203,6 +4203,16 @@
|
||||
"experimental"
|
||||
]
|
||||
},
|
||||
"github.copilot.chat.agentCustomizationSkill.enabled": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"markdownDescription": "%github.copilot.config.agentCustomizationSkill.enabled%",
|
||||
"tags": [
|
||||
"advanced",
|
||||
"experimental",
|
||||
"onExp"
|
||||
]
|
||||
},
|
||||
"github.copilot.chat.searchSubagent.enabled": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
@@ -5577,4 +5587,4 @@
|
||||
"node-gyp": "npm:node-gyp@10.3.1",
|
||||
"zod": "3.25.76"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -393,5 +393,6 @@
|
||||
"copilot.tools.runSubagent.description": "Runs a task within an isolated subagent context. Enables efficient organization of tasks and context window management.",
|
||||
"copilot.tools.searchSubagent.name": "Search Subagent",
|
||||
"copilot.tools.searchSubagent.description": "Launch an iterative search-focused subagent to find relevant code in your workspace.",
|
||||
"github.copilot.config.searchSubagent.enabled": "Enable the search subagent tool for iterative code exploration in the workspace."
|
||||
"github.copilot.config.searchSubagent.enabled": "Enable the search subagent tool for iterative code exploration in the workspace.",
|
||||
"github.copilot.config.agentCustomizationSkill.enabled": "Enable the built-in agent customization skill."
|
||||
}
|
||||
|
||||
+250
@@ -0,0 +1,250 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { ILogService } from '../../../platform/log/common/logService';
|
||||
import { IVSCodeExtensionContext } from '../../../platform/extContext/common/extensionContext';
|
||||
import { Disposable } from '../../../util/vs/base/common/lifecycle';
|
||||
import { Emitter } from '../../../util/vs/base/common/event';
|
||||
|
||||
const SKILL_FOLDER_NAME = 'agent-customization';
|
||||
const SKILL_FILENAME = 'SKILL.md';
|
||||
const SKILL_SCHEME = 'copilot-skill';
|
||||
|
||||
/**
|
||||
* Placeholder in SKILL.md that will be replaced with the actual user prompts folder path.
|
||||
*/
|
||||
const USER_PROMPTS_FOLDER_PLACEHOLDER = '{{USER_PROMPTS_FOLDER}}';
|
||||
|
||||
/**
|
||||
* Provides the built-in agent-customization skill that teaches agents
|
||||
* how to work with VS Code's customization system (instructions, prompts, agents, skills).
|
||||
*
|
||||
* Uses a FileSystemProvider (instead of TextDocumentContentProvider) so that VS Code's
|
||||
* fileService.readFile() can read the skill content during prompt parsing, not just when
|
||||
* the file is opened in an editor.
|
||||
*/
|
||||
export class AgentCustomizationSkillProvider extends Disposable implements vscode.ChatSkillProvider, vscode.FileSystemProvider {
|
||||
|
||||
private readonly _skillContentUri: vscode.Uri;
|
||||
private _cachedContent: Uint8Array | undefined;
|
||||
|
||||
private readonly _onDidChangeFile = this._register(new Emitter<vscode.FileChangeEvent[]>());
|
||||
readonly onDidChangeFile = this._onDidChangeFile.event;
|
||||
|
||||
constructor(
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@IVSCodeExtensionContext private readonly extensionContext: IVSCodeExtensionContext,
|
||||
) {
|
||||
super();
|
||||
|
||||
// Create a virtual URI for the dynamically generated skill content
|
||||
this._skillContentUri = vscode.Uri.from({
|
||||
scheme: SKILL_SCHEME,
|
||||
path: `/${SKILL_FOLDER_NAME}/${SKILL_FILENAME}`
|
||||
});
|
||||
|
||||
// Register a FileSystemProvider to serve the dynamic skill content.
|
||||
// This is required because VS Code's promptsService uses fileService.readFile()
|
||||
// to read skill content, which only works with FileSystemProvider, not TextDocumentContentProvider.
|
||||
this._register(vscode.workspace.registerFileSystemProvider(SKILL_SCHEME, this, { isReadonly: true }));
|
||||
}
|
||||
|
||||
// #region FileSystemProvider implementation
|
||||
|
||||
watch(_uri: vscode.Uri, _options: { readonly recursive: boolean; readonly excludes: readonly string[] }): vscode.Disposable {
|
||||
// No need to watch - content is static after first load
|
||||
return { dispose: () => { } };
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a virtual URI path to the corresponding physical URI in the extension assets.
|
||||
* Virtual: /agent-customization/primitives/agents.md
|
||||
* Physical: extensionUri/assets/prompts/skills/agent-customization/primitives/agents.md
|
||||
*/
|
||||
private _toAssetUri(virtualPath: string): vscode.Uri | undefined {
|
||||
// Ensure the path is within our skill folder
|
||||
const prefix = `/${SKILL_FOLDER_NAME}`;
|
||||
if (!virtualPath.startsWith(prefix)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Get the relative path after /agent-customization
|
||||
const relativePath = virtualPath.substring(prefix.length);
|
||||
|
||||
// Build the full asset path
|
||||
return vscode.Uri.joinPath(
|
||||
this.extensionContext.extensionUri,
|
||||
'assets',
|
||||
'prompts',
|
||||
'skills',
|
||||
SKILL_FOLDER_NAME,
|
||||
...relativePath.split('/').filter(Boolean)
|
||||
);
|
||||
}
|
||||
|
||||
async stat(uri: vscode.Uri): Promise<vscode.FileStat> {
|
||||
// Handle the dynamic SKILL.md file
|
||||
if (uri.path === `/${SKILL_FOLDER_NAME}/${SKILL_FILENAME}`) {
|
||||
const content = await this._getSkillContentBytes();
|
||||
return {
|
||||
type: vscode.FileType.File,
|
||||
ctime: 0,
|
||||
mtime: Date.now(),
|
||||
size: content.length
|
||||
};
|
||||
}
|
||||
|
||||
// Handle root and skill folder directories
|
||||
if (uri.path === `/${SKILL_FOLDER_NAME}` || uri.path === '/') {
|
||||
return {
|
||||
type: vscode.FileType.Directory,
|
||||
ctime: 0,
|
||||
mtime: 0,
|
||||
size: 0
|
||||
};
|
||||
}
|
||||
|
||||
// Handle nested files/directories (e.g., /agent-customization/primitives/agents.md)
|
||||
const assetUri = this._toAssetUri(uri.path);
|
||||
if (assetUri) {
|
||||
try {
|
||||
return await vscode.workspace.fs.stat(assetUri);
|
||||
} catch {
|
||||
// Fall through to FileNotFound
|
||||
}
|
||||
}
|
||||
|
||||
throw vscode.FileSystemError.FileNotFound(uri);
|
||||
}
|
||||
|
||||
async readDirectory(uri: vscode.Uri): Promise<[string, vscode.FileType][]> {
|
||||
if (uri.path === '/' || uri.path === '') {
|
||||
return [[SKILL_FOLDER_NAME, vscode.FileType.Directory]];
|
||||
}
|
||||
|
||||
// For paths within the skill folder, enumerate actual directory contents
|
||||
const assetUri = this._toAssetUri(uri.path);
|
||||
if (assetUri) {
|
||||
try {
|
||||
return await vscode.workspace.fs.readDirectory(assetUri);
|
||||
} catch {
|
||||
// Fall through to empty result
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
createDirectory(_uri: vscode.Uri): void {
|
||||
throw vscode.FileSystemError.NoPermissions('Readonly file system');
|
||||
}
|
||||
|
||||
async readFile(uri: vscode.Uri): Promise<Uint8Array> {
|
||||
// The root SKILL.md has dynamic content (placeholder injection)
|
||||
if (uri.path === `/${SKILL_FOLDER_NAME}/${SKILL_FILENAME}`) {
|
||||
return this._getSkillContentBytes();
|
||||
}
|
||||
|
||||
// All other files are read directly from the assets folder
|
||||
const assetUri = this._toAssetUri(uri.path);
|
||||
if (assetUri) {
|
||||
try {
|
||||
return await vscode.workspace.fs.readFile(assetUri);
|
||||
} catch {
|
||||
// Fall through to FileNotFound
|
||||
}
|
||||
}
|
||||
|
||||
throw vscode.FileSystemError.FileNotFound(uri);
|
||||
}
|
||||
|
||||
writeFile(_uri: vscode.Uri, _content: Uint8Array, _options: { readonly create: boolean; readonly overwrite: boolean }): void {
|
||||
throw vscode.FileSystemError.NoPermissions('Readonly file system');
|
||||
}
|
||||
|
||||
delete(_uri: vscode.Uri, _options: { readonly recursive: boolean }): void {
|
||||
throw vscode.FileSystemError.NoPermissions('Readonly file system');
|
||||
}
|
||||
|
||||
rename(_oldUri: vscode.Uri, _newUri: vscode.Uri, _options: { readonly overwrite: boolean }): void {
|
||||
throw vscode.FileSystemError.NoPermissions('Readonly file system');
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
/**
|
||||
* Gets the user prompts folder path from the extension context's globalStorageUri.
|
||||
* The globalStorageUri is typically: `.../User/globalStorage/<extension-id>/`
|
||||
* The user prompts folder is: `.../User/prompts/`
|
||||
*/
|
||||
private _getUserPromptsFolder(): string {
|
||||
const globalStorageUri = this.extensionContext.globalStorageUri;
|
||||
|
||||
// Navigate up from globalStorage/<extension-id>/ to User/ and then to prompts/
|
||||
// globalStorageUri: file:///Users/.../User/globalStorage/github.copilot-chat/
|
||||
// We want: file:///Users/.../User/prompts/
|
||||
const userFolderUri = vscode.Uri.joinPath(globalStorageUri, '..', '..');
|
||||
const userPromptsFolderUri = vscode.Uri.joinPath(userFolderUri, 'prompts');
|
||||
|
||||
return userPromptsFolderUri.fsPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the SKILL.md template and injects the user prompts folder path.
|
||||
* Returns bytes for use by the FileSystemProvider.
|
||||
*/
|
||||
private async _getSkillContentBytes(): Promise<Uint8Array> {
|
||||
if (this._cachedContent) {
|
||||
return this._cachedContent;
|
||||
}
|
||||
|
||||
try {
|
||||
// Build the URI to the original skill file within the extension
|
||||
const skillTemplateUri = vscode.Uri.joinPath(
|
||||
this.extensionContext.extensionUri,
|
||||
'assets',
|
||||
'prompts',
|
||||
'skills',
|
||||
SKILL_FOLDER_NAME,
|
||||
SKILL_FILENAME
|
||||
);
|
||||
|
||||
// Read the template content
|
||||
const templateBytes = await vscode.workspace.fs.readFile(skillTemplateUri);
|
||||
const templateContent = new TextDecoder().decode(templateBytes);
|
||||
|
||||
// Replace the placeholder with the actual user prompts folder path
|
||||
const userPromptsFolder = this._getUserPromptsFolder();
|
||||
const processedContent = templateContent.replace(USER_PROMPTS_FOLDER_PLACEHOLDER, userPromptsFolder);
|
||||
this._cachedContent = new TextEncoder().encode(processedContent);
|
||||
|
||||
this.logService.trace(`[AgentCustomizationSkillProvider] Injected user prompts folder: ${userPromptsFolder}`);
|
||||
|
||||
return this._cachedContent;
|
||||
} catch (error) {
|
||||
this.logService.error(`[AgentCustomizationSkillProvider] Error reading skill template: ${error}`);
|
||||
return new Uint8Array();
|
||||
}
|
||||
}
|
||||
|
||||
async provideSkills(
|
||||
_context: unknown,
|
||||
token: vscode.CancellationToken
|
||||
): Promise<vscode.ChatResource[]> {
|
||||
try {
|
||||
if (token.isCancellationRequested) {
|
||||
return [];
|
||||
}
|
||||
|
||||
this.logService.trace(`[AgentCustomizationSkillProvider] Providing skill at ${this._skillContentUri.toString()}`);
|
||||
|
||||
return [{ uri: this._skillContentUri }];
|
||||
} catch (error) {
|
||||
this.logService.error(`[AgentCustomizationSkillProvider] Error providing skills: ${error}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService';
|
||||
import { IExperimentationService } from '../../../platform/telemetry/common/nullExperimentationService';
|
||||
import { Disposable } from '../../../util/vs/base/common/lifecycle';
|
||||
import { SyncDescriptor } from '../../../util/vs/platform/instantiation/common/descriptors';
|
||||
import { IInstantiationService } from '../../../util/vs/platform/instantiation/common/instantiation';
|
||||
@@ -13,6 +14,7 @@ import { GitHubOrgCustomAgentProvider } from './githubOrgCustomAgentProvider';
|
||||
import { GitHubOrgInstructionsProvider } from './githubOrgInstructionsProvider';
|
||||
import { ImplementAgentProvider } from './implementAgentProvider';
|
||||
import { PlanAgentProvider } from './planAgentProvider';
|
||||
import { AgentCustomizationSkillProvider } from './agentCustomizationSkillProvider';
|
||||
|
||||
export class PromptFileContribution extends Disposable implements IExtensionContribution {
|
||||
readonly id = 'PromptFiles';
|
||||
@@ -20,6 +22,7 @@ export class PromptFileContribution extends Disposable implements IExtensionCont
|
||||
constructor(
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IExperimentationService experimentationService: IExperimentationService,
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -48,5 +51,13 @@ export class PromptFileContribution extends Disposable implements IExtensionCont
|
||||
this._register(vscode.chat.registerInstructionsProvider(githubOrgInstructionsProvider));
|
||||
}
|
||||
}
|
||||
|
||||
// Register skill provider for built-in agent customization skill
|
||||
if ('registerSkillProvider' in vscode.chat) {
|
||||
if (configurationService.getExperimentBasedConfig(ConfigKey.Advanced.AgentCustomizationSkillEnabled, experimentationService)) {
|
||||
const agentCustomizationSkillProvider: vscode.ChatSkillProvider = instantiationService.createInstance(new SyncDescriptor(AgentCustomizationSkillProvider));
|
||||
this._register(vscode.chat.registerSkillProvider(agentCustomizationSkillProvider));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import { CancellationToken } from '../../../util/vs/base/common/cancellation';
|
||||
import { CancellationError } from '../../../util/vs/base/common/errors';
|
||||
import { Schemas } from '../../../util/vs/base/common/network';
|
||||
import { isAbsolute } from '../../../util/vs/base/common/path';
|
||||
import { isEqual, normalizePath } from '../../../util/vs/base/common/resources';
|
||||
import { extUriBiasedIgnorePathCase, isEqual, normalizePath } from '../../../util/vs/base/common/resources';
|
||||
import { isString } from '../../../util/vs/base/common/types';
|
||||
import { URI } from '../../../util/vs/base/common/uri';
|
||||
import { IInstantiationService, ServicesAccessor } from '../../../util/vs/platform/instantiation/common/instantiation';
|
||||
@@ -132,6 +132,12 @@ export async function assertFileOkForTool(accessor: ServicesAccessor, uri: URI,
|
||||
if (instructionIndexFile.instructions.has(normalizedUri) || instructionIndexFile.skills.has(normalizedUri)) {
|
||||
return;
|
||||
}
|
||||
// Check if the URI is under any skill folder (e.g., nested files like primitives/agents.md)
|
||||
for (const skillFolderUri of instructionIndexFile.skillFolders) {
|
||||
if (extUriBiasedIgnorePathCase.isEqualOrParent(normalizedUri, skillFolderUri)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (await customInstructionsService.isExternalInstructionsFile(normalizedUri)) {
|
||||
|
||||
@@ -716,6 +716,9 @@ export namespace ConfigKey {
|
||||
clearInputs?: boolean;
|
||||
thinkingKeepTurns?: number;
|
||||
} | null>('chat.anthropic.contextEditing.config', ConfigType.Simple, null);
|
||||
|
||||
/** Enable the built-in agent customization skill provider */
|
||||
export const AgentCustomizationSkillEnabled = defineSetting<boolean>('chat.agentCustomizationSkill.enabled', ConfigType.ExperimentBased, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user