@fission-ai/openspec
Version:
AI-native system for spec-driven development
51 lines (50 loc) • 1.63 kB
JavaScript
/**
* Windsurf Command Adapter
*
* Formats commands for Windsurf following its frontmatter specification.
* Windsurf uses a similar format to Claude but may have different conventions.
*/
import path from 'path';
/**
* Escapes a string value for safe YAML output.
* Quotes the string if it contains special YAML characters.
*/
function escapeYamlValue(value) {
// Check if value needs quoting (contains special YAML characters or starts/ends with whitespace)
const needsQuoting = /[:\n\r#{}[\],&*!|>'"%@`]|^\s|\s$/.test(value);
if (needsQuoting) {
// Use double quotes and escape internal double quotes and backslashes
const escaped = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
return `"${escaped}"`;
}
return value;
}
/**
* Formats a tags array as a YAML array with proper escaping.
*/
function formatTagsArray(tags) {
const escapedTags = tags.map((tag) => escapeYamlValue(tag));
return `[${escapedTags.join(', ')}]`;
}
/**
* Windsurf adapter for command generation.
* File path: .windsurf/workflows/opsx-<id>.md
* Frontmatter: name, description, category, tags
*/
export const windsurfAdapter = {
toolId: 'windsurf',
getFilePath(commandId) {
return path.join('.windsurf', 'workflows', `opsx-${commandId}.md`);
},
formatFile(content) {
return `---
name: ${escapeYamlValue(content.name)}
description: ${escapeYamlValue(content.description)}
category: ${escapeYamlValue(content.category)}
tags: ${formatTagsArray(content.tags)}
---
${content.body}
`;
},
};
//# sourceMappingURL=windsurf.js.map