From 3f05d8b6a7b1a4a32d0222d9c12f6e7e30bbc2f9 Mon Sep 17 00:00:00 2001 From: shog86 Date: Thu, 19 Mar 2026 11:32:09 +0800 Subject: [PATCH] Support both Trae China and International versions - Output skills to both .trae-cn/ and .trae/ directories - Update README with installation instructions for both versions - Update DEVELOP.md with dual-variant documentation --- DEVELOP.md | 9 ++-- README.md | 11 ++++- scripts/build.js | 6 ++- scripts/lib/transformers/trae.js | 81 +++++++++++++++++++------------- 4 files changed, 67 insertions(+), 40 deletions(-) diff --git a/DEVELOP.md b/DEVELOP.md index 76ecd751d..8be14f555 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -123,10 +123,13 @@ All providers output skills to `dist/{provider}/.{config}/skills/{name}/SKILL.md - Frontmatter: name, description, license, compatibility, metadata ### Trae (Full Featured) -- Output: `dist/trae/.trae-cn/builtin_skills/{name}/SKILL.md` +- Output: `dist/trae/.trae-cn/builtin_skills/{name}/SKILL.md` (China version) +- Output: `dist/trae/.trae/builtin_skills/{name}/SKILL.md` (International version) - Frontmatter: name, description, user-invokable, args, license, compatibility, metadata, allowed-tools - Same format as Claude Code -- Skills are installed to `~/.trae-cn/builtin_skills/` +- Two variants are generated automatically: + - **Trae China**: Skills installed to `~/.trae-cn/builtin_skills/` + - **Trae International**: Skills installed to `~/.trae/builtin_skills/` ## Adding New Content @@ -181,7 +184,7 @@ The build system uses a modular architecture under `scripts/`: - `transformKiro()`: Basic frontmatter with license/compatibility/metadata - `transformOpenCode()`: Full metadata (same as Claude Code) - `transformPi()`: Basic frontmatter with license/compatibility/metadata -- `transformTrae()`: Full metadata (same as Claude Code), outputs to `.trae-cn/builtin_skills/` +- `transformTrae()`: Full metadata (same as Claude Code), outputs to both `.trae-cn/builtin_skills/` and `.trae/builtin_skills/` ## Best Practices diff --git a/README.md b/README.md index be1f48442..b7517c824 100644 --- a/README.md +++ b/README.md @@ -127,11 +127,18 @@ cp -r dist/codex/.codex/* ~/.codex/ **Trae:** ```bash -# Global installation (recommended) +# Trae China (domestic version) cp -r dist/trae/.trae-cn/builtin_skills/* ~/.trae-cn/builtin_skills/ + +# Trae International +cp -r dist/trae/.trae/builtin_skills/* ~/.trae/builtin_skills/ ``` -> **Note:** Trae uses `~/.trae-cn/builtin_skills/` for skills. After copying, restart Trae IDE to activate the skills. +> **Note:** Trae has two versions with different config directories: +> - **Trae China**: `~/.trae-cn/builtin_skills/` +> - **Trae International**: `~/.trae/builtin_skills/` +> +> After copying, restart Trae IDE to activate the skills. ## Usage diff --git a/scripts/build.js b/scripts/build.js index 6287c5a00..8a932d6ee 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -151,7 +151,8 @@ function assembleUniversal(distDir, suffix = '') { { provider: 'kiro', configDir: '.kiro' }, { provider: 'opencode', configDir: '.opencode' }, { provider: 'pi', configDir: '.pi' }, - { provider: 'trae', configDir: '.trae-cn' } + { provider: 'trae', configDir: '.trae-cn' }, + { provider: 'trae', configDir: '.trae' } ]; for (const { provider, configDir } of providerMappings) { @@ -179,7 +180,8 @@ This folder contains skills for all supported tools: .kiro/ → Kiro .opencode/ → OpenCode .pi/ → Pi - .trae-cn/ → Trae + .trae-cn/ → Trae China + .trae/ → Trae International To install, copy the relevant folder(s) into your project root. These are hidden folders (dotfiles) — press Cmd+Shift+. in Finder to see them. diff --git a/scripts/lib/transformers/trae.js b/scripts/lib/transformers/trae.js index e997e4396..19a1c787b 100644 --- a/scripts/lib/transformers/trae.js +++ b/scripts/lib/transformers/trae.js @@ -4,7 +4,10 @@ import { cleanDir, ensureDir, writeFile, generateYamlFrontmatter, replacePlaceho /** * Trae Transformer (Skills Only) * - * All skills output to .trae-cn/builtin_skills/{name}/SKILL.md + * Outputs skills for both Trae China and Trae International versions: + * - .trae-cn/builtin_skills/{name}/SKILL.md (China version) + * - .trae/builtin_skills/{name}/SKILL.md (International version) + * * Trae uses a similar format to Claude Code with full metadata support. * * @param {Array} skills - All skills (including user-invokable ones) @@ -17,51 +20,63 @@ import { cleanDir, ensureDir, writeFile, generateYamlFrontmatter, replacePlaceho export function transformTrae(skills, distDir, patterns = null, options = {}) { const { prefix = '', outputSuffix = '' } = options; const traeDir = path.join(distDir, `trae${outputSuffix}`); - const skillsDir = path.join(traeDir, '.trae-cn/builtin_skills'); cleanDir(traeDir); - ensureDir(skillsDir); const allSkillNames = skills.map(s => s.name); const commandNames = skills.filter(s => s.userInvokable).map(s => `${prefix}${s.name}`); - let refCount = 0; - for (const skill of skills) { - const skillName = `${prefix}${skill.name}`; - const skillDir = path.join(skillsDir, skillName); - const frontmatterObj = { - name: skillName, - description: skill.description, - }; + const variants = [ + { name: 'China', configDir: '.trae-cn/builtin_skills' }, + { name: 'International', configDir: '.trae/builtin_skills' } + ]; - if (skill.userInvokable) frontmatterObj['user-invokable'] = true; - if (skill.args && skill.args.length > 0) frontmatterObj.args = skill.args; - if (skill.license) frontmatterObj.license = skill.license; - if (skill.compatibility) frontmatterObj.compatibility = skill.compatibility; - if (skill.metadata) frontmatterObj.metadata = skill.metadata; - if (skill.allowedTools) frontmatterObj['allowed-tools'] = skill.allowedTools; + let totalRefCount = 0; - const frontmatter = generateYamlFrontmatter(frontmatterObj); - let skillBody = replacePlaceholders(skill.body, 'trae', commandNames); - if (prefix) skillBody = prefixSkillReferences(skillBody, prefix, allSkillNames); - const content = `${frontmatter}\n\n${skillBody}`; - const outputPath = path.join(skillDir, 'SKILL.md'); - writeFile(outputPath, content); + for (const variant of variants) { + const skillsDir = path.join(traeDir, variant.configDir); + ensureDir(skillsDir); - if (skill.references && skill.references.length > 0) { - const refDir = path.join(skillDir, 'reference'); - ensureDir(refDir); - for (const ref of skill.references) { - const refOutputPath = path.join(refDir, `${ref.name}.md`); - const refContent = replacePlaceholders(ref.content, 'trae'); - writeFile(refOutputPath, refContent); - refCount++; + let refCount = 0; + for (const skill of skills) { + const skillName = `${prefix}${skill.name}`; + const skillDir = path.join(skillsDir, skillName); + + const frontmatterObj = { + name: skillName, + description: skill.description, + }; + + if (skill.userInvokable) frontmatterObj['user-invokable'] = true; + if (skill.args && skill.args.length > 0) frontmatterObj.args = skill.args; + if (skill.license) frontmatterObj.license = skill.license; + if (skill.compatibility) frontmatterObj.compatibility = skill.compatibility; + if (skill.metadata) frontmatterObj.metadata = skill.metadata; + if (skill.allowedTools) frontmatterObj['allowed-tools'] = skill.allowedTools; + + const frontmatter = generateYamlFrontmatter(frontmatterObj); + let skillBody = replacePlaceholders(skill.body, 'trae', commandNames); + if (prefix) skillBody = prefixSkillReferences(skillBody, prefix, allSkillNames); + const content = `${frontmatter}\n\n${skillBody}`; + const outputPath = path.join(skillDir, 'SKILL.md'); + writeFile(outputPath, content); + + if (skill.references && skill.references.length > 0) { + const refDir = path.join(skillDir, 'reference'); + ensureDir(refDir); + for (const ref of skill.references) { + const refOutputPath = path.join(refDir, `${ref.name}.md`); + const refContent = replacePlaceholders(ref.content, 'trae'); + writeFile(refOutputPath, refContent); + refCount++; + } } } + totalRefCount += refCount; } const userInvokableCount = skills.filter(s => s.userInvokable).length; - const refInfo = refCount > 0 ? ` (${refCount} reference files)` : ''; + const refInfo = totalRefCount > 0 ? ` (${totalRefCount / 2} reference files per variant)` : ''; const prefixInfo = prefix ? ` [${prefix}prefixed]` : ''; - console.log(`✓ Trae${prefixInfo}: ${skills.length} skills (${userInvokableCount} user-invokable)${refInfo}`); + console.log(`✓ Trae${prefixInfo}: ${skills.length} skills (${userInvokableCount} user-invokable) for 2 variants${refInfo}`); }