diff --git a/src/core/command-generation/adapters/index.ts b/src/core/command-generation/adapters/index.ts index 83de1f0d..ad20eab5 100644 --- a/src/core/command-generation/adapters/index.ts +++ b/src/core/command-generation/adapters/index.ts @@ -24,4 +24,5 @@ export { opencodeAdapter } from './opencode.js'; export { qoderAdapter } from './qoder.js'; export { qwenAdapter } from './qwen.js'; export { roocodeAdapter } from './roocode.js'; +export { traeAdapter } from './trae.js'; export { windsurfAdapter } from './windsurf.js'; diff --git a/src/core/command-generation/adapters/trae.ts b/src/core/command-generation/adapters/trae.ts new file mode 100644 index 00000000..07c011a3 --- /dev/null +++ b/src/core/command-generation/adapters/trae.ts @@ -0,0 +1,47 @@ +/** + * Trae Command Adapter + * + * Formats commands for Trae following its frontmatter specification. + * Trae uses a similar frontmatter format to Cursor with file naming convention. + */ + +import path from 'path'; +import type { CommandContent, ToolCommandAdapter } from '../types.js'; + +/** + * Escapes a string value for safe YAML output. + * Quotes the string if it contains special YAML characters. + */ +function escapeYamlValue(value: string): string { + const needsQuoting = /[:\n\r#{}[\],&*!|>'"%@`]|^\s|\s$/.test(value); + if (needsQuoting) { + const escaped = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n'); + return `"${escaped}"`; + } + return value; +} + +/** + * Trae adapter for command generation. + * File path: .trae/commands/opsx-.md + * Frontmatter: name (as /opsx-), id, category, description + */ +export const traeAdapter: ToolCommandAdapter = { + toolId: 'trae', + + getFilePath(commandId: string): string { + return path.join('.trae', 'commands', `opsx-${commandId}.md`); + }, + + formatFile(content: CommandContent): string { + return `--- +name: /opsx-${content.id} +id: opsx-${content.id} +category: ${escapeYamlValue(content.category)} +description: ${escapeYamlValue(content.description)} +--- + +${content.body} +`; + }, +}; diff --git a/src/core/command-generation/registry.ts b/src/core/command-generation/registry.ts index f99edac6..0a7bd179 100644 --- a/src/core/command-generation/registry.ts +++ b/src/core/command-generation/registry.ts @@ -26,6 +26,7 @@ import { opencodeAdapter } from './adapters/opencode.js'; import { qoderAdapter } from './adapters/qoder.js'; import { qwenAdapter } from './adapters/qwen.js'; import { roocodeAdapter } from './adapters/roocode.js'; +import { traeAdapter } from './adapters/trae.js'; import { windsurfAdapter } from './adapters/windsurf.js'; /** @@ -56,6 +57,7 @@ export class CommandAdapterRegistry { CommandAdapterRegistry.register(qoderAdapter); CommandAdapterRegistry.register(qwenAdapter); CommandAdapterRegistry.register(roocodeAdapter); + CommandAdapterRegistry.register(traeAdapter); CommandAdapterRegistry.register(windsurfAdapter); }