Compare commits

...
Author SHA1 Message Date
Tabish Bidiwale 4772d71b4e Merge main into fix-windsurf-workrules
Resolve conflict in docs/supported-tools.md: keep both the new Trae
entry from main and the updated Windsurf workflows path from this branch.
2026-01-29 17:57:26 -08:00
yangjun d59a0b347a fix a missing update 2026-01-28 22:35:59 +08:00
yangjun 04dc6deb5d fix windsurf workrules 2026-01-28 21:56:58 +08:00
6 changed files with 10 additions and 11 deletions
+1 -1
View File
@@ -34,7 +34,7 @@ For each tool you select, OpenSpec installs:
| Qwen Code | `.qwen/skills/` | `.qwen/commands/` |
| RooCode | `.roo/skills/` | `.roo/commands/` |
| Trae | `.trae/skills/` | `.trae/skills/` (via `/openspec-*`) |
| Windsurf | `.windsurf/skills/` | `.windsurf/commands/opsx/` |
| Windsurf | `.windsurf/skills/` | `.windsurf/workflows/` |
## Non-Interactive Setup
@@ -49,7 +49,7 @@ The system SHALL define a `ToolCommandAdapter` interface for per-tool formatting
- **WHEN** formatting a command for Windsurf
- **THEN** the adapter SHALL output YAML frontmatter with `name`, `description`, `category`, `tags` fields
- **AND** file path SHALL follow pattern `.windsurf/commands/opsx/<id>.md`
- **AND** file path SHALL follow pattern `.windsurf/workflows/opsx-<id>.md`
### Requirement: Command generator function
@@ -33,14 +33,14 @@ function formatTagsArray(tags: string[]): string {
/**
* Windsurf adapter for command generation.
* File path: .windsurf/commands/opsx/<id>.md
* File path: .windsurf/workflows/opsx-<id>.md
* Frontmatter: name, description, category, tags
*/
export const windsurfAdapter: ToolCommandAdapter = {
toolId: 'windsurf',
getFilePath(commandId: string): string {
return path.join('.windsurf', 'commands', 'opsx', `${commandId}.md`);
return path.join('.windsurf', 'workflows', `opsx-${commandId}.md`);
},
formatFile(content: CommandContent): string {
@@ -107,7 +107,7 @@ describe('command-generation/adapters', () => {
it('should generate correct file path', () => {
const filePath = windsurfAdapter.getFilePath('explore');
expect(filePath).toBe(path.join('.windsurf', 'commands', 'opsx', 'explore.md'));
expect(filePath).toBe(path.join('.windsurf', 'workflows', 'opsx-explore.md'));
});
it('should format file similar to Claude format', () => {
@@ -495,7 +495,7 @@ describe('command-generation/adapters', () => {
it('Windsurf adapter uses path.join for paths', () => {
const filePath = windsurfAdapter.getFilePath('test');
expect(filePath.split(path.sep)).toEqual(['.windsurf', 'commands', 'opsx', 'test.md']);
expect(filePath.split(path.sep)).toEqual(['.windsurf', 'workflows', 'opsx-test.md']);
});
it('All adapters use path.join for paths', () => {
+2 -2
View File
@@ -12,7 +12,7 @@ describe('InitCommand', () => {
await fs.mkdir(testDir, { recursive: true });
// Mock console.log to suppress output during tests
vi.spyOn(console, 'log').mockImplementation(() => {});
vi.spyOn(console, 'log').mockImplementation(() => { });
});
afterEach(async () => {
@@ -375,7 +375,7 @@ describe('InitCommand', () => {
const initCommand = new InitCommand({ tools: 'windsurf', force: true });
await initCommand.execute(testDir);
const cmdFile = path.join(testDir, '.windsurf', 'commands', 'opsx', 'explore.md');
const cmdFile = path.join(testDir, '.windsurf', 'workflows', 'opsx-explore.md');
expect(await fileExists(cmdFile)).toBe(true);
});
+2 -3
View File
@@ -301,9 +301,8 @@ Old instructions content
const windsurfCmd = path.join(
testDir,
'.windsurf',
'commands',
'opsx',
'explore.md'
'workflows',
'opsx-explore.md'
);
const exists = await FileSystemUtils.fileExists(windsurfCmd);
expect(exists).toBe(true);