@fission-ai/openspec
Version:
AI-native system for spec-driven development
50 lines (49 loc) • 1.54 kB
JavaScript
/**
* Claude Code Command Adapter
*
* Formats commands for Claude Code following its frontmatter specification.
*/
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(', ')}]`;
}
/**
* Claude Code adapter for command generation.
* File path: .claude/commands/opsx/<id>.md
* Frontmatter: name, description, category, tags
*/
export const claudeAdapter = {
toolId: 'claude',
getFilePath(commandId) {
return path.join('.claude', 'commands', '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=claude.js.map