feat: add Trae runtime install support (#1566)

* feat: add Trae runtime install support

- Add Trae as a supported runtime in bin/install.js
- Update README and ARCHITECTURE documentation for Trae support
- Add trae-install.test.cjs test file
- Update multi-runtime-select tests for Trae compatibility

* feat(trae): add TRAE_CONFIG_DIR environment variable support

Add support for TRAE_CONFIG_DIR environment variable as an additional way to specify the config directory for Trae runtime, following the same precedence pattern as other runtimes.

* fix(trae): improve slash command conversion and subagent type mapping

Update the slash command regex pattern to properly match and convert command names. Change subagent type mapping from "general-purpose" to "general_purpose_task" to match Trae's conventions. Also add comprehensive tests for Trae uninstall cleanup behavior.

* docs: add Trae and Windsurf to supported runtimes in translations

Update Korean, Japanese, and Portuguese README files to include Trae and Windsurf as supported runtimes in the documentation. Add installation and uninstallation instructions for Trae.

* fix: update runtime selection logic and path replacements

- Change 'All' shortcut from option 11 to 12 to accommodate new runtime
- Update path replacement regex to handle gsd- prefix more precisely
- Adjust test cases to reflect new runtime selection numbering
- Add configDir to trae install options for proper path resolution

* test(trae-install): add tests for getGlobalDir function

Add test cases to verify behavior of getGlobalDir function with different configurations:
- Default directory when no env var or explicit dir is provided
- Explicit directory takes priority
- Respects TRAE_CONFIG_DIR env var
- Priority of explicit dir over env var
- Compatibility with other runtimes
This commit is contained in:
Elwin
2026-04-04 20:13:15 +08:00
committed by GitHub
parent f26e1e1141
commit 66368a42d9
9 changed files with 594 additions and 117 deletions

View File

@@ -27,9 +27,10 @@ const runtimeMap = {
'7': 'antigravity',
'8': 'cursor',
'9': 'windsurf',
'10': 'augment'
'10': 'augment',
'11': 'trae'
};
const allRuntimes = ['claude', 'kilo', 'opencode', 'gemini', 'codex', 'copilot', 'antigravity', 'cursor', 'windsurf', 'augment'];
const allRuntimes = ['claude', 'kilo', 'opencode', 'gemini', 'codex', 'copilot', 'antigravity', 'cursor', 'windsurf', 'augment', 'trae'];
/**
* Simulate the parsing logic from promptRuntime without requiring readline.
@@ -38,7 +39,7 @@ const allRuntimes = ['claude', 'kilo', 'opencode', 'gemini', 'codex', 'copilot',
function parseRuntimeInput(input) {
input = input.trim() || '1';
if (input === '11') {
if (input === '12') {
return allRuntimes;
}
@@ -88,8 +89,12 @@ describe('multi-runtime selection parsing', () => {
assert.deepStrictEqual(parseRuntimeInput('10'), ['augment']);
});
test('choice 11 returns all runtimes', () => {
assert.deepStrictEqual(parseRuntimeInput('11'), allRuntimes);
test('single choice for trae', () => {
assert.deepStrictEqual(parseRuntimeInput('11'), ['trae']);
});
test('choice 12 returns all runtimes', () => {
assert.deepStrictEqual(parseRuntimeInput('12'), allRuntimes);
});
test('empty input defaults to claude', () => {
@@ -98,13 +103,13 @@ describe('multi-runtime selection parsing', () => {
});
test('invalid choices are ignored, falls back to claude if all invalid', () => {
assert.deepStrictEqual(parseRuntimeInput('12'), ['claude']);
assert.deepStrictEqual(parseRuntimeInput('13'), ['claude']);
assert.deepStrictEqual(parseRuntimeInput('0'), ['claude']);
assert.deepStrictEqual(parseRuntimeInput('abc'), ['claude']);
});
test('invalid choices mixed with valid are filtered out', () => {
assert.deepStrictEqual(parseRuntimeInput('1,11,5'), ['claude', 'codex']);
assert.deepStrictEqual(parseRuntimeInput('1,13,5'), ['claude', 'codex']);
assert.deepStrictEqual(parseRuntimeInput('abc 3 xyz'), ['opencode']);
});
@@ -137,21 +142,21 @@ describe('install.js source contains multi-select support', () => {
}
});
test('all shortcut uses option 11', () => {
test('all shortcut uses option 12', () => {
assert.ok(
installSrc.includes("if (input === '11')"),
'all shortcut uses option 11'
installSrc.includes("if (input === '12')"),
'all shortcut uses option 12'
);
});
test('prompt lists Augment as option 10 and All as option 11', () => {
test('prompt lists Augment as option 10 and All as option 12', () => {
assert.ok(
installSrc.includes('10${reset}) Augment'),
'prompt lists Augment as option 10'
);
assert.ok(
installSrc.includes('11${reset}) All'),
'prompt lists All as option 11'
installSrc.includes('12${reset}) All'),
'prompt lists All as option 12'
);
});