Skip to content

Commit d3fee4b

Browse files
loppetyampcode-com
andcommitted
feat(copilot): replace global instructions with custom slash commands
BREAKING CHANGE: GitHub Copilot integration renamed from 'copilot-instructions' to 'copilot' - Add CopilotPromptsAdapter for .github/prompts/*.prompt.md files - Commands appear as /clavix-improve, /clavix-prd, etc. in Copilot Chat - YAML frontmatter with name, description, agent, and tools - Smart agent mapping: 'ask' for planning, 'agent' for implementation - Move Copilot from 'Universal Adapters' to 'IDE & IDE Extensions' - Remove CopilotInstructionsGenerator and copilot-instructions.md template - Update schemas to allow .prompt.md extension and prompt-files adapter Closes #copilot-slash-commands Amp-Thread-ID: https://ampcode.com/threads/T-019bb2d2-521b-71a0-82b3-2bb819bb76a7 Co-authored-by: Amp <amp@ampcode.com>
1 parent 31ef9ba commit d3fee4b

28 files changed

Lines changed: 345 additions & 421 deletions

CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,30 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [6.1.0] - 2026-01-12
9+
10+
### Added
11+
12+
- **GitHub Copilot Custom Slash Commands** - Full integration with VS Code GitHub Copilot:
13+
- Replaced global `.github/copilot-instructions.md` with proper slash commands
14+
- New adapter generates `.github/prompts/*.prompt.md` files
15+
- Commands appear as `/clavix-improve`, `/clavix-prd`, etc. in Copilot Chat
16+
- YAML frontmatter with `name`, `description`, `agent`, and `tools`
17+
- Smart agent mapping: `ask` for planning commands, `agent` for implementation
18+
- Moved from "Universal Adapters" to "IDE & IDE Extensions" category
19+
20+
### Changed
21+
22+
- **CopilotPromptsAdapter** replaces `CopilotInstructionsGenerator`
23+
- **Integration name**: `copilot-instructions``copilot`
24+
- **File location**: `.github/copilot-instructions.md``.github/prompts/clavix-*.prompt.md`
25+
- **Schema updates**: Added `.prompt.md` extension and `prompt-files` specialAdapter type
26+
27+
### Removed
28+
29+
- `CopilotInstructionsGenerator` class
30+
- `src/templates/agents/copilot-instructions.md` template
31+
832
## [6.0.0] - 2026-01-12
933

1034
### Added

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "clavix",
3-
"version": "6.0.0",
3+
"version": "6.1.0",
44
"description": "Agentic-first prompt workflows. Markdown templates that teach AI agents how to optimize prompts, create PRDs, and manage implementation.\n\nSLASH COMMANDS (in your AI assistant):\n /clavix:improve Optimize prompts with auto-depth\n /clavix:prd Generate PRD through questions\n /clavix:plan Create task breakdown from PRD\n /clavix:implement Execute tasks with progress tracking\n /clavix:start Begin conversational session\n /clavix:summarize Extract requirements from conversation\n /clavix:refine Refine existing PRD or prompt\n /clavix:verify Verify implementation against requirements\n /clavix:review Review teammate PRs with criteria\n /clavix:archive Archive completed projects\n\nWorks with Claude Code, Cursor, Windsurf, and 20 AI coding tools.",
55
"type": "module",
66
"main": "dist/index.js",

schemas/integrations.schema.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@
5757
"type": "string",
5858
"enum": [
5959
".md",
60-
".toml"
60+
".toml",
61+
".prompt.md"
6162
],
6263
"description": "File extension for commands"
6364
},
@@ -87,7 +88,8 @@
8788
"type": "string",
8889
"enum": [
8990
"toml",
90-
"doc-injection"
91+
"doc-injection",
92+
"prompt-files"
9193
],
9294
"description": "Special adapter type if needed"
9395
},

src/cli/commands/init.ts

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { DocInjector } from '../../core/doc-injector.js';
1111
import { AgentsMdGenerator } from '../../core/adapters/agents-md-generator.js';
1212
import { OctoMdGenerator } from '../../core/adapters/octo-md-generator.js';
1313
import { WarpMdGenerator } from '../../core/adapters/warp-md-generator.js';
14-
import { CopilotInstructionsGenerator } from '../../core/adapters/copilot-instructions-generator.js';
14+
1515
import { InstructionsGenerator } from '../../core/adapters/instructions-generator.js';
1616
import { FileSystem } from '../../utils/file-system.js';
1717
import { ClavixConfig, DEFAULT_CONFIG } from '../../types/config.js';
@@ -326,13 +326,6 @@ export default class Init extends Command {
326326
continue;
327327
}
328328

329-
// Handle copilot-instructions separately (it's not an adapter)
330-
if (integrationName === 'copilot-instructions') {
331-
this.log(chalk.gray(' ✓ Generating .github/copilot-instructions.md...'));
332-
await CopilotInstructionsGenerator.generate();
333-
continue;
334-
}
335-
336329
// Handle octo-md separately (it's not an adapter)
337330
if (integrationName === 'octo-md') {
338331
this.log(chalk.gray(' ✓ Generating OCTO.md...'));
@@ -537,12 +530,6 @@ export default class Init extends Command {
537530
continue;
538531
}
539532

540-
if (integrationName === 'copilot-instructions') {
541-
this.log(chalk.gray(' ✓ Regenerating .github/copilot-instructions.md...'));
542-
await CopilotInstructionsGenerator.generate();
543-
continue;
544-
}
545-
546533
if (integrationName === 'octo-md') {
547534
this.log(chalk.gray(' ✓ Regenerating OCTO.md...'));
548535
await OctoMdGenerator.generate();

src/cli/helpers/init/integrations.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,14 @@ import { DocInjector } from '../../../core/doc-injector.js';
66
import { AgentsMdGenerator } from '../../../core/adapters/agents-md-generator.js';
77
import { OctoMdGenerator } from '../../../core/adapters/octo-md-generator.js';
88
import { WarpMdGenerator } from '../../../core/adapters/warp-md-generator.js';
9-
import { CopilotInstructionsGenerator } from '../../../core/adapters/copilot-instructions-generator.js';
9+
1010
import { InstructionsGenerator } from '../../../core/adapters/instructions-generator.js';
1111
import type { AgentManager } from '../../../core/agent-manager.js';
1212

1313
/**
1414
* Doc generator integrations (not regular adapters)
1515
*/
16-
export const DOC_GENERATOR_INTEGRATIONS = [
17-
'agents-md',
18-
'octo-md',
19-
'warp-md',
20-
'copilot-instructions',
21-
] as const;
16+
export const DOC_GENERATOR_INTEGRATIONS = ['agents-md', 'octo-md', 'warp-md'] as const;
2217

2318
/**
2419
* Integrations that use colon separator (CLI tools)
@@ -53,9 +48,6 @@ export async function generateDocGeneratorContent(integrationName: string): Prom
5348
case 'warp-md':
5449
await WarpMdGenerator.generate();
5550
break;
56-
case 'copilot-instructions':
57-
await CopilotInstructionsGenerator.generate();
58-
break;
5951
}
6052
}
6153

@@ -73,9 +65,6 @@ export async function cleanupDocGeneratorIntegration(integrationName: string): P
7365
case 'warp-md':
7466
await DocInjector.removeBlock('WARP.md');
7567
break;
76-
case 'copilot-instructions':
77-
await DocInjector.removeBlock('.github/copilot-instructions.md');
78-
break;
7968
}
8069
}
8170

src/config/integrations.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,14 +194,15 @@
194194
"type": "universal"
195195
},
196196
{
197-
"name": "copilot-instructions",
197+
"name": "copilot",
198198
"displayName": "GitHub Copilot",
199-
"directory": ".github",
200-
"filenamePattern": "copilot-instructions",
201-
"extension": ".md",
199+
"directory": ".github/prompts",
200+
"filenamePattern": "clavix-{name}",
201+
"extension": ".prompt.md",
202202
"separator": "-",
203203
"detection": ".github",
204-
"type": "universal"
204+
"specialAdapter": "prompt-files",
205+
"type": "standard"
205206
},
206207
{
207208
"name": "octo-md",

src/core/adapters/copilot-instructions-generator.ts

Lines changed: 0 additions & 48 deletions
This file was deleted.
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import * as path from 'path';
2+
import { BaseAdapter } from './base-adapter.js';
3+
import { CommandTemplate } from '../../types/agent.js';
4+
import { FileSystem } from '../../utils/file-system.js';
5+
import { IntegrationError } from '../../types/errors.js';
6+
import { ClavixConfig } from '../../types/config.js';
7+
8+
/**
9+
* GitHub Copilot Prompts Adapter
10+
*
11+
* Generates custom slash commands as .prompt.md files in .github/prompts/
12+
* These appear as /clavix-improve, /clavix-prd, etc. in VS Code with GitHub Copilot
13+
*
14+
* Format reference: https://code.visualstudio.com/docs/copilot/copilot-customization
15+
*
16+
* @since v6.1.0
17+
*/
18+
export class CopilotPromptsAdapter extends BaseAdapter {
19+
readonly name = 'copilot';
20+
readonly displayName = 'GitHub Copilot';
21+
readonly directory = '.github/prompts';
22+
readonly fileExtension = '.prompt.md';
23+
readonly features = {
24+
supportsSubdirectories: false,
25+
commandFormat: { separator: '-' as const },
26+
};
27+
protected readonly userConfig?: ClavixConfig;
28+
29+
constructor(userConfig?: ClavixConfig) {
30+
super();
31+
this.userConfig = userConfig;
32+
}
33+
34+
/**
35+
* Detect if GitHub Copilot is likely in use
36+
* Check for .github directory (common for GitHub projects)
37+
*/
38+
async detectProject(): Promise<boolean> {
39+
return await FileSystem.exists('.github');
40+
}
41+
42+
/**
43+
* Get command path for Copilot prompts
44+
*/
45+
getCommandPath(): string {
46+
return this.directory;
47+
}
48+
49+
/**
50+
* Get target filename for a command
51+
* Format: clavix-{name}.prompt.md
52+
*/
53+
getTargetFilename(name: string): string {
54+
return `clavix-${name}${this.fileExtension}`;
55+
}
56+
57+
/**
58+
* Determine if a file is a Clavix-generated prompt
59+
*/
60+
protected isClavixGeneratedCommand(filename: string): boolean {
61+
return filename.startsWith('clavix-') && filename.endsWith('.prompt.md');
62+
}
63+
64+
/**
65+
* Format command content with Copilot prompt file frontmatter
66+
*
67+
* Copilot prompt files support YAML frontmatter with:
68+
* - name: The slash command name (shown after /)
69+
* - description: Short description shown in command picker
70+
* - agent: Which agent to use (ask, edit, agent)
71+
* - tools: List of available tools
72+
*/
73+
protected formatCommand(template: CommandTemplate): string {
74+
const frontmatter = this.generateFrontmatter(template);
75+
return `${frontmatter}\n${template.content}`;
76+
}
77+
78+
/**
79+
* Generate YAML frontmatter for Copilot prompt file
80+
*/
81+
private generateFrontmatter(template: CommandTemplate): string {
82+
// Extract description from template frontmatter if present
83+
const descMatch = template.content.match(/^---\s*\n[\s\S]*?description:\s*(.+)\n[\s\S]*?---/);
84+
const description = descMatch ? descMatch[1].trim() : template.description;
85+
86+
// Map Clavix commands to appropriate Copilot agents
87+
const agentMapping: Record<string, string> = {
88+
improve: 'ask',
89+
prd: 'ask',
90+
start: 'ask',
91+
summarize: 'ask',
92+
refine: 'ask',
93+
plan: 'ask',
94+
review: 'ask',
95+
verify: 'ask',
96+
implement: 'agent',
97+
archive: 'agent',
98+
};
99+
100+
const agent = agentMapping[template.name] || 'ask';
101+
102+
// For implementation commands, include tools
103+
const toolsLine =
104+
agent === 'agent' ? '\ntools:\n - editFiles\n - runCommands\n - codebase' : '';
105+
106+
return `---
107+
name: clavix-${template.name}
108+
description: "${description.replace(/"/g, '\\"')}"
109+
agent: ${agent}${toolsLine}
110+
---`;
111+
}
112+
113+
/**
114+
* Generate commands with Copilot-specific formatting
115+
*/
116+
async generateCommands(templates: CommandTemplate[]): Promise<void> {
117+
const commandPath = this.getCommandPath();
118+
119+
try {
120+
// Ensure directory exists
121+
await FileSystem.ensureDir(commandPath);
122+
123+
// Generate each command file
124+
for (const template of templates) {
125+
const content = this.formatCommand(template);
126+
const filename = this.getTargetFilename(template.name);
127+
const filePath = path.join(commandPath, filename);
128+
await FileSystem.writeFileAtomic(filePath, content);
129+
}
130+
} catch (error) {
131+
throw new IntegrationError(
132+
`Failed to generate ${this.displayName} commands: ${error}`,
133+
`Ensure ${commandPath} is writable`
134+
);
135+
}
136+
}
137+
}

src/core/agent-manager.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { AgentAdapter, ValidationResult } from '../types/agent.js';
22
import { ClaudeCodeAdapter } from './adapters/claude-code-adapter.js';
3+
import { CopilotPromptsAdapter } from './adapters/copilot-prompts-adapter.js';
34
import { GeminiAdapter } from './adapters/gemini-adapter.js';
45
import { QwenAdapter } from './adapters/qwen-adapter.js';
56
import { LlxprtAdapter } from './adapters/llxprt-adapter.js';
@@ -26,6 +27,7 @@ export class AgentManager {
2627

2728
// Register special adapters (require custom logic)
2829
this.registerAdapter(new ClaudeCodeAdapter(userConfig)); // Doc injection
30+
this.registerAdapter(new CopilotPromptsAdapter(userConfig)); // Prompt files
2931
this.registerAdapter(new GeminiAdapter(userConfig)); // TOML format
3032
this.registerAdapter(new QwenAdapter(userConfig)); // TOML format
3133
this.registerAdapter(new LlxprtAdapter(userConfig)); // TOML format

0 commit comments

Comments
 (0)