feat(agent): add TraeCode CLI support (#807)

* feat(agent): add TraeCode CLI support

* fix(settings): index TraeCode agent hooks
This commit is contained in:
ayamir
2026-09-08 16:57:04 +08:00
committed by GitHub
parent ca9bb747e4
commit fc94022ed0
17 changed files with 119 additions and 16 deletions
+3 -2
View File
@@ -51,7 +51,7 @@ Native builds for macOS, Windows, and Linux on [**Releases**](https://github.com
| | |
|---|---|
| **Agent-aware** | per-pane detection (19 CLIs) · status dot · notifications · branch + diff · tray icon when input is needed · resume after reboot · tab sidebar grouped by repository |
| **Agent-aware** | per-pane detection (20 CLIs) · status dot · notifications · branch + diff · tray icon when input is needed · resume after reboot · tab sidebar grouped by repository |
| **CLI + Skills** | bundled `tty7` CLI · [agent skill](skills/tty7/SKILL.md) · `run` streams a command and exits with its code · `split` · `send` · `wait --until free` · `capture` |
| **Editor-grade input** | ghost suggestions from history · explained tab completion · syntax highlighting · multi-line editing · click places the caret · <kbd>⌃ R</kbd> fuzzy history |
| **Window** | tabs & splits · <kbd>⌘ P</kbd> palette · <kbd>⌘ F</kbd> scrollback search · <kbd>⌘ J</kbd> panel with process tree and listening ports · 13 themes, your own YAML, iTerm2 import · IME |
@@ -69,12 +69,13 @@ after a reboot. **Fork** needs both — the agent's own fork command, and the ho
that tells tty7 which session to fork.
<details>
<summary>The full support matrix, all nineteen</summary>
<summary>The full support matrix, all twenty</summary>
| Agent | Detected | Status · resume | Fork |
|---|:-:|:-:|:-:|
| **Claude Code** | ✓ | ✓ | ✓ |
| **Codex** | ✓ | ✓ | ✓ |
| **TraeCode** | ✓ | ✓ | ✓ |
| **Grok** | ✓ | ✓ | ✓ |
| **OpenCode** | ✓ | ✓ | ✓ |
| **Oh My Pi** | ✓ | ✓ | ✓ |
+3 -2
View File
@@ -50,7 +50,7 @@ macOS、Windows、Linux 的原生构建都在 [**Releases**](https://github.com/
| | |
|---|---|
| **Agent 感知** | 逐 pane 识别 19 个 CLI agent · 状态点 · 通知 · 分支 + diff · 需要输入时托盘图标提醒 · 重启后续上会话 · 侧边栏按仓库分组 |
| **Agent 感知** | 逐 pane 识别 20 个 CLI agent · 状态点 · 通知 · 分支 + diff · 需要输入时托盘图标提醒 · 重启后续上会话 · 侧边栏按仓库分组 |
| **CLI + Skills** | 安装包自带 `tty7` CLI · [agent skill](skills/tty7/SKILL.md) · `run` 转发命令输出并原样返回退出码 · `split` · `send` · `wait --until free` · `capture` |
| **编辑器级输入** | 从历史推出影子建议 · Tab 补全附带说明 · 语法高亮 · 多行编辑 · 点击定位光标 · <kbd>⌃ R</kbd> 模糊搜索历史 |
| **窗口** | 标签页与分屏 · <kbd>⌘ P</kbd> 命令面板 · <kbd>⌘ F</kbd> 回滚搜索 · <kbd>⌘ J</kbd> 侧栏列出进程树和监听端口 · 13 套主题,也能写自己的 YAML 或导入 iTerm2 配色 · 输入法 |
@@ -66,12 +66,13 @@ macOS、Windows、Linux 的原生构建都在 [**Releases**](https://github.com/
**Fork** 两个条件都要:agent 自己提供 fork 命令,且 hook 已装——tty7 得知道 fork 的是哪个会话。
<details>
<summary>19 个 agent 的完整支持矩阵</summary>
<summary>20 个 agent 的完整支持矩阵</summary>
| Agent | 识别 | 状态 · 重启恢复 | Fork |
|---|:-:|:-:|:-:|
| **Claude Code** | ✓ | ✓ | ✓ |
| **Codex** | ✓ | ✓ | ✓ |
| **TraeCode** | ✓ | ✓ | ✓ |
| **Grok** | ✓ | ✓ | ✓ |
| **OpenCode** | ✓ | ✓ | ✓ |
| **Oh My Pi** | ✓ | ✓ | ✓ |
+4
View File
@@ -0,0 +1,4 @@
<!-- TRAE brand mark, normalized from the user-provided trae-color.svg. -->
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24 20.541H3.428v-3.426H0V3.4h24V20.54zM3.428 17.115h17.144V6.827H3.428v10.288zm8.573-5.196-2.425 2.424-2.424-2.424 2.424-2.424 2.425 2.424zm6.857-.001-2.424 2.423-2.425-2.423 2.425-2.425 2.424 2.425z" fill="#32F08C"/>
</svg>

After

Width:  |  Height:  |  Size: 409 B

+33 -1
View File
@@ -246,6 +246,7 @@ fn ancestor_pids(procs: &[crate::daemon::winproc::Proc]) -> Vec<u32> {
pub enum HookAgent {
Claude,
Codex,
TraeCode,
Copilot,
OpenCode,
Pi,
@@ -259,9 +260,10 @@ pub enum HookAgent {
}
impl HookAgent {
pub const ALL: [HookAgent; 12] = [
pub const ALL: [HookAgent; 13] = [
HookAgent::Claude,
HookAgent::Codex,
HookAgent::TraeCode,
HookAgent::Copilot,
HookAgent::OpenCode,
HookAgent::Pi,
@@ -283,6 +285,7 @@ impl HookAgent {
match agent {
CLIAgent::Claude => Some(HookAgent::Claude),
CLIAgent::Codex => Some(HookAgent::Codex),
CLIAgent::TraeCode => Some(HookAgent::TraeCode),
CLIAgent::Copilot => Some(HookAgent::Copilot),
CLIAgent::OpenCode => Some(HookAgent::OpenCode),
CLIAgent::Pi => Some(HookAgent::Pi),
@@ -310,6 +313,7 @@ impl HookAgent {
match self {
HookAgent::Claude => Some(CLAUDE_HOOK_EVENTS),
HookAgent::Codex => Some(CODEX_HOOK_EVENTS),
HookAgent::TraeCode => Some(TRAE_CODE_HOOK_EVENTS),
HookAgent::Gemini => Some(GEMINI_HOOK_EVENTS),
HookAgent::Droid => Some(DROID_HOOK_EVENTS),
HookAgent::Qwen => Some(QWEN_HOOK_EVENTS),
@@ -337,6 +341,7 @@ impl HookAgent {
match self {
HookAgent::Claude => "claude",
HookAgent::Codex => "codex",
HookAgent::TraeCode => "traecli",
HookAgent::Copilot => "copilot",
HookAgent::OpenCode => "opencode",
HookAgent::Pi => "pi",
@@ -354,6 +359,7 @@ impl HookAgent {
match self {
HookAgent::Claude => "Claude Code",
HookAgent::Codex => "Codex",
HookAgent::TraeCode => "TraeCode",
HookAgent::Copilot => "Copilot CLI",
HookAgent::OpenCode => "OpenCode",
HookAgent::Pi => "Pi",
@@ -375,6 +381,7 @@ impl HookAgent {
match self {
HookAgent::Claude => target.claude_settings_path(),
HookAgent::Codex => target.under_home(&[".codex", "hooks.json"]),
HookAgent::TraeCode => target.traecli_hooks_path(),
HookAgent::Copilot => target.under_home(&[".copilot", "hooks", OWNED_FILE_STEM_JSON]),
HookAgent::OpenCode => target.under(
&target.xdg_config_dir(),
@@ -487,6 +494,18 @@ impl<'a> HookTarget<'a> {
self.under_home(&[".kimi-code", "config.toml"])
}
fn traecli_hooks_path(&self) -> PathBuf {
if self.is_local() {
if let Some(dir) = std::env::var_os("TRAECLI_HOME").filter(|d| !d.is_empty()) {
return PathBuf::from(dir).join("hooks.json");
}
if let Some(dir) = std::env::var_os("TRAE_HOME").filter(|d| !d.is_empty()) {
return PathBuf::from(dir).join("cli").join("hooks.json");
}
}
self.under_home(&[".trae", "cli", "hooks.json"])
}
fn hook_command(&self, agent: HookAgent, event: &str) -> String {
if let Some(exe) = self.hook_command_exe() {
return format!("{exe} agent-hook {} {event}", agent.slug());
@@ -697,6 +716,15 @@ const CODEX_HOOK_EVENTS: &[(&str, &str)] = &[
("Stop", "stop"),
];
const TRAE_CODE_HOOK_EVENTS: &[(&str, &str)] = &[
("SessionStart", "session-start"),
("UserPromptSubmit", "prompt-submit"),
("PermissionRequest", "permission-request"),
("PostToolUse", "tool-complete"),
("Stop", "stop"),
("SessionEnd", "session-end"),
];
/// Gemini names the turn boundaries after the agent rather than the user, and
/// omitting `matcher` matches everything (`hookPlanner.ts`, `!entry.matcher`),
/// so the bare entries [`hook_map_install`] already writes are enough.
@@ -1106,6 +1134,7 @@ fn owned_file_content(target: &HookTarget, agent: HookAgent) -> Option<String> {
HookAgent::Goose => goose_hooks_json(target),
HookAgent::Claude
| HookAgent::Codex
| HookAgent::TraeCode
| HookAgent::Gemini
| HookAgent::Droid
| HookAgent::Qwen
@@ -1538,6 +1567,7 @@ mod tests {
let mut events: Vec<&str> = CLAUDE_HOOK_EVENTS
.iter()
.chain(CODEX_HOOK_EVENTS)
.chain(TRAE_CODE_HOOK_EVENTS)
.chain(GEMINI_HOOK_EVENTS)
.chain(DROID_HOOK_EVENTS)
.chain(QWEN_HOOK_EVENTS)
@@ -1571,6 +1601,7 @@ mod tests {
(HookAgent::Gemini, "/home/me/.gemini/settings.json"),
(HookAgent::Droid, "/home/me/.factory/settings.json"),
(HookAgent::Qwen, "/home/me/.qwen/settings.json"),
(HookAgent::TraeCode, "/home/me/.trae/cli/hooks.json"),
(
HookAgent::Goose,
"/home/me/.agents/plugins/tty7/hooks/hooks.json",
@@ -1862,6 +1893,7 @@ mod tests {
for (agent, expected) in [
(HookAgent::Claude, "/home/me/.claude/settings.json"),
(HookAgent::Codex, "/home/me/.codex/hooks.json"),
(HookAgent::TraeCode, "/home/me/.trae/cli/hooks.json"),
(HookAgent::Copilot, "/home/me/.copilot/hooks/tty7.json"),
(
HookAgent::OpenCode,
+37 -2
View File
@@ -23,12 +23,16 @@ pub enum CLIAgent {
Qwen,
OhMyPi,
Kimi,
// Keep new variants at the end: daemon messages serialize this enum and
// moving an existing discriminant would break mixed-version clients.
TraeCode,
}
impl CLIAgent {
pub const ALL: [CLIAgent; 19] = [
pub const ALL: [CLIAgent; 20] = [
CLIAgent::Claude,
CLIAgent::Codex,
CLIAgent::TraeCode,
CLIAgent::Gemini,
CLIAgent::Aider,
CLIAgent::Amp,
@@ -52,6 +56,7 @@ impl CLIAgent {
match self {
CLIAgent::Claude => &["claude", "claude-code"],
CLIAgent::Codex => &["codex", "codex-cli"],
CLIAgent::TraeCode => &["traecli", "traex"],
CLIAgent::Gemini => &["gemini", "gemini-cli"],
CLIAgent::Aider => &["aider", "aider-chat"],
CLIAgent::Amp => &["amp"],
@@ -85,6 +90,7 @@ impl CLIAgent {
match self {
CLIAgent::Claude => "claude",
CLIAgent::Codex => "codex",
CLIAgent::TraeCode => "traecli",
CLIAgent::Gemini => "gemini",
CLIAgent::Aider => "aider",
CLIAgent::Amp => "amp",
@@ -114,6 +120,7 @@ impl CLIAgent {
match self {
CLIAgent::Claude => "Claude Code",
CLIAgent::Codex => "Codex",
CLIAgent::TraeCode => "TraeCode",
CLIAgent::Gemini => "Gemini",
CLIAgent::Aider => "Aider",
CLIAgent::Amp => "Amp",
@@ -146,6 +153,7 @@ impl CLIAgent {
match self {
CLIAgent::Claude => Some(format!("claude{flags} --resume {session_id}")),
CLIAgent::Codex => Some(format!("codex resume {session_id}{flags}")),
CLIAgent::TraeCode => Some(format!("traecli resume {session_id}{flags}")),
CLIAgent::Gemini => Some(format!("gemini{flags} --resume {session_id}")),
CLIAgent::OpenCode => Some(format!("opencode{flags} --session {session_id}")),
CLIAgent::Amp => Some(format!("amp threads continue {session_id}{flags}")),
@@ -189,6 +197,7 @@ impl CLIAgent {
let flags = self.session_command_flags(session_id, launch_argv)?;
match self {
CLIAgent::Codex => Some(format!("codex fork {session_id}{flags}")),
CLIAgent::TraeCode => Some(format!("traecli fork {session_id}{flags}")),
CLIAgent::Claude => Some(format!(
"claude{flags} --resume {session_id} --fork-session"
)),
@@ -213,6 +222,7 @@ impl CLIAgent {
match self {
CLIAgent::Claude
| CLIAgent::Codex
| CLIAgent::TraeCode
| CLIAgent::Grok
| CLIAgent::OpenCode
| CLIAgent::OhMyPi
@@ -260,7 +270,9 @@ impl CLIAgent {
let named = argv.iter().position(|t| names_self(t))?;
let mut tail: Vec<&str> = argv[named + 1..].iter().map(String::as_str).collect();
if self == CLIAgent::Codex && matches!(tail.first(), Some(&"resume") | Some(&"fork")) {
if matches!(self, CLIAgent::Codex | CLIAgent::TraeCode)
&& matches!(tail.first(), Some(&"resume") | Some(&"fork"))
{
tail.remove(0);
if tail.first().is_some_and(|t| !t.starts_with('-')) {
tail.remove(0);
@@ -339,6 +351,7 @@ impl CLIAgent {
CLIAgent::Antigravity => &["--conversation", "--continue", "-c"],
CLIAgent::OpenCode => &["--session", "-s", "--continue", "-c", "--fork"],
CLIAgent::Codex => &["--last"],
CLIAgent::TraeCode => &["--last", "--resume", "--session-id"],
CLIAgent::Pi => &[
"--session",
"--session-id",
@@ -422,6 +435,9 @@ impl CLIAgent {
match self {
CLIAgent::Claude => 0xD97757,
CLIAgent::Codex => 0x000000,
// The brand mark carries its own green foreground on a black
// field, so the surrounding tab avatar needs to stay black too.
CLIAgent::TraeCode => 0x000000,
CLIAgent::Gemini => 0x4285F4,
CLIAgent::Aider => 0x14B014,
CLIAgent::Amp => 0xF34E3F,
@@ -448,6 +464,7 @@ impl CLIAgent {
match self {
CLIAgent::Claude => "icons/agents/claude.svg",
CLIAgent::Codex => "icons/agents/codex.svg",
CLIAgent::TraeCode => "icons/agents/traecli.svg",
CLIAgent::Gemini => "icons/agents/gemini.svg",
CLIAgent::Amp => "icons/agents/amp.svg",
CLIAgent::OpenCode => "icons/agents/opencode.svg",
@@ -771,6 +788,14 @@ mod tests {
CLIAgent::detect_from_argv(&argv(&["/opt/homebrew/bin/codex", "--model", "o3"])),
Some(CLIAgent::Codex)
);
assert_eq!(
CLIAgent::detect_from_argv(&argv(&["/Users/me/.local/bin/traecli"])),
Some(CLIAgent::TraeCode)
);
assert_eq!(
CLIAgent::detect_from_argv(&argv(&["traex"])),
Some(CLIAgent::TraeCode)
);
assert_eq!(
CLIAgent::detect_from_argv(&argv(&["/usr/local/bin/gemini"])),
Some(CLIAgent::Gemini)
@@ -1192,6 +1217,12 @@ mod tests {
CLIAgent::Codex.resume_command("th_read.9", None).as_deref(),
Some("codex resume th_read.9")
);
assert_eq!(
CLIAgent::TraeCode
.resume_command("019c-123", None)
.as_deref(),
Some("traecli resume 019c-123")
);
assert_eq!(
CLIAgent::Pi
.resume_command("0199c3f2-1b0e-7c3a-9f21-6d4b8e2a5c17", None)
@@ -1522,6 +1553,10 @@ mod tests {
CLIAgent::Codex.fork_command("abc-123", None).as_deref(),
Some("codex fork abc-123")
);
assert_eq!(
CLIAgent::TraeCode.fork_command("019c-123", None).as_deref(),
Some("traecli fork 019c-123")
);
assert_eq!(
CLIAgent::Claude.fork_command("abc-123", None).as_deref(),
Some("claude --resume abc-123 --fork-session")
+4 -3
View File
@@ -1,6 +1,6 @@
---
title: "Coding agents"
description: "What tty7 does around Claude Code, Codex, and 17 others — without ever wrapping them."
description: "What tty7 does around Claude Code, Codex, TraeCode, and 17 others — without ever wrapping them."
---
tty7 recognises coding agents running in a pane and builds around them. It does
@@ -15,12 +15,13 @@ need, and what changed.
## Which agents
Nineteen CLIs are recognised on sight, by the command running in the pane:
Twenty CLIs are recognised on sight, by the command running in the pane:
| Agent | Command |
|---|---|
| Claude Code | `claude`, `claude-code` |
| Codex | `codex`, `codex-cli` |
| TraeCode | `traecli`, `traex` |
| Gemini | `gemini`, `gemini-cli` |
| Copilot | `copilot` |
| Cursor | `cursor-agent` |
@@ -58,7 +59,7 @@ If you launch agents through a wrapper script, map its name to an agent in
```
The key is your command's name; the value is one of the slugs above (`claude`,
`codex`, `gemini`, `aider`, `amp`, `opencode`, `copilot`, `cursor`, `goose`,
`codex`, `traecli`, `gemini`, `aider`, `amp`, `opencode`, `copilot`, `cursor`, `goose`,
`droid`, `pi`, `auggie`, `hermes`, `vibe`, `antigravity`, `grok`, `qwen`,
`omp`, `kimi`).
+1
View File
@@ -39,6 +39,7 @@ or right-click the **tab or sidebar row** to open the fork in a new tab.
|---|---|
| Claude Code | `claude --resume <id> --fork-session` |
| Codex | `codex fork <id>` |
| TraeCode | `traecli fork <id>` |
| Grok | `grok --resume <id> --fork-session` |
| OpenCode | `opencode --session <id> --fork` |
| Oh My Pi | `omp --fork <id>` |
+1 -1
View File
@@ -14,7 +14,7 @@ the agent say which one it is.
| Agent | |
|---|---|
| Claude Code · Codex · Copilot CLI · OpenCode · Pi · Grok Build · Oh My Pi · Gemini · Droid · Qwen Code · Goose · Kimi Code | Hooks available |
| Claude Code · Codex · TraeCode · Copilot CLI · OpenCode · Pi · Grok Build · Oh My Pi · Gemini · Droid · Qwen Code · Goose · Kimi Code | Hooks available |
| Aider · Amp · Cursor · Auggie · Hermes · Vibe · Antigravity | Detected and labelled, but no status channel yet |
Installing writes into that agent's own configuration directory. Once installed
+3 -3
View File
@@ -54,13 +54,13 @@ leave it off if you type accented characters.
## 4. If you use coding agents, install the hooks
**Settings → Agents.** tty7 detects 19 coding CLIs by process name on its own —
**Settings → Agents.** tty7 detects 20 coding CLIs by process name on its own —
you get brand avatars and tab labels for free. The *status dots*, the "needs
your permission" notifications, and `tty7 wait` all need one more thing: a small
hook the agent calls to report what it is doing.
Click **Install** next to Claude Code, Codex, Copilot CLI, OpenCode, Pi, Grok
Build, or Oh My Pi. It writes into that agent's own config directory and can be
Click **Install** next to Claude Code, Codex, TraeCode, Copilot CLI, OpenCode,
Pi, Grok Build, or Oh My Pi. It writes into that agent's own config directory and can be
removed from the same row.
[More about agents →](/agents/status)
+1 -1
View File
@@ -31,7 +31,7 @@ something floods the screen.
syntax highlighting, click-to-place-caret, real multi-line editing.
</Card>
<Card title="Agent-aware" icon="robot" href="/agents/overview">
19 coding CLIs are recognised on sight. Per-pane status dots, notifications
20 coding CLIs are recognised on sight. Per-pane status dots, notifications
when one needs you, git context, and session resume after a reboot.
</Card>
<Card title="Remote work that feels local" icon="server" href="/remote/workspaces">
+1
View File
@@ -49,6 +49,7 @@ fn agent_icon(path: &str) -> Option<&'static [u8]> {
"icons/refresh.svg" => include_bytes!("../../assets/icons/refresh.svg"),
"icons/agents/claude.svg" => include_bytes!("../../assets/icons/agents/claude.svg"),
"icons/agents/codex.svg" => include_bytes!("../../assets/icons/agents/codex.svg"),
"icons/agents/traecli.svg" => include_bytes!("../../assets/icons/agents/traecli.svg"),
"icons/agents/gemini.svg" => include_bytes!("../../assets/icons/agents/gemini.svg"),
"icons/agents/amp.svg" => include_bytes!("../../assets/icons/agents/amp.svg"),
"icons/agents/opencode.svg" => include_bytes!("../../assets/icons/agents/opencode.svg"),
+4
View File
@@ -738,6 +738,7 @@ pub fn translate_en(key: L10nKey) -> &'static str {
}
L10nKey::SettingsAgentClaudeCode => "Claude Code",
L10nKey::SettingsAgentCodex => "Codex",
L10nKey::SettingsAgentTraeCode => "TraeCode",
L10nKey::SettingsAgentCopilotCli => "Copilot CLI",
L10nKey::SettingsAgentOpencode => "OpenCode",
L10nKey::SettingsAgentPi => "Pi",
@@ -768,6 +769,9 @@ pub fn translate_en(key: L10nKey) -> &'static str {
"agent integration hooks install uninstall status rich session working waiting tab bar sidebar badge claude"
}
L10nKey::SettingsSearchCodexKeywords => "agent integration hooks install openai codex",
L10nKey::SettingsSearchTraeCodeKeywords => {
"agent integration hooks install trae code traecli traex"
}
L10nKey::SettingsSearchCommandLineToolKeywords => {
"command line tool cli tty7 path shell command install symlink terminal iterm agent script"
}
+4
View File
@@ -747,6 +747,7 @@ pub fn translate_ja(key: L10nKey) -> Option<&'static str> {
}
L10nKey::SettingsAgentClaudeCode => "Claude Code",
L10nKey::SettingsAgentCodex => "Codex",
L10nKey::SettingsAgentTraeCode => "TraeCode",
L10nKey::SettingsAgentCopilotCli => "Copilot CLI",
L10nKey::SettingsAgentOpencode => "OpenCode",
L10nKey::SettingsAgentPi => "Pi",
@@ -787,6 +788,9 @@ pub fn translate_ja(key: L10nKey) -> Option<&'static str> {
L10nKey::SettingsSearchCodexKeywords => {
"エージェント 統合 フック インストール openai codex agent integration hooks install"
}
L10nKey::SettingsSearchTraeCodeKeywords => {
"エージェント 統合 フック インストール trae code traecli traex agent integration hooks install"
}
L10nKey::SettingsSearchCommandLineToolKeywords => {
"cli tty7 パス シェル コマンド インストール シンボリックリンク ターミナル iterm エージェント スクリプト command line tool"
}
+3
View File
@@ -570,6 +570,7 @@ l10n_keys! {
SettingsAppHttpProxyInvalid,
SettingsAgentClaudeCode,
SettingsAgentCodex,
SettingsAgentTraeCode,
SettingsAgentCopilotCli,
SettingsAgentOpencode,
SettingsAgentPi,
@@ -593,6 +594,7 @@ l10n_keys! {
SettingsSearchBoldFontKeywords,
SettingsSearchClaudeCodeKeywords,
SettingsSearchCodexKeywords,
SettingsSearchTraeCodeKeywords,
SettingsSearchCommandLineToolKeywords,
SettingsSearchCommandLineToolTitle,
SettingsSearchCopilotCliKeywords,
@@ -1532,6 +1534,7 @@ mod tests {
// Product names.
L10nKey::SettingsAgentClaudeCode,
L10nKey::SettingsAgentCodex,
L10nKey::SettingsAgentTraeCode,
L10nKey::SettingsAgentCopilotCli,
L10nKey::SettingsAgentDroid,
L10nKey::SettingsAgentGemini,
+4
View File
@@ -656,6 +656,7 @@ pub fn translate_zh(key: L10nKey) -> Option<&'static str> {
L10nKey::SettingsAppHttpProxyInvalid => "不是有效的代理地址,该值未保存。",
L10nKey::SettingsAgentClaudeCode => "Claude Code",
L10nKey::SettingsAgentCodex => "Codex",
L10nKey::SettingsAgentTraeCode => "TraeCode",
L10nKey::SettingsAgentCopilotCli => "Copilot CLI",
L10nKey::SettingsAgentOpencode => "OpenCode",
L10nKey::SettingsAgentPi => "Pi",
@@ -694,6 +695,9 @@ pub fn translate_zh(key: L10nKey) -> Option<&'static str> {
L10nKey::SettingsSearchCodexKeywords => {
"Codex agent 集成 hook 安装 OpenAI codex agent integration hooks install"
}
L10nKey::SettingsSearchTraeCodeKeywords => {
"TraeCode traecli traex agent 集成 hook 安装 agent integration hooks install"
}
L10nKey::SettingsSearchCommandLineToolKeywords => {
"命令行工具 cli tty7 路径 shell 命令 安装 符号链接 terminal command line tool"
}
+5
View File
@@ -601,6 +601,11 @@ fn settings_search_entries() -> &'static [SearchEntry] {
title: SettingsAgentCodex,
keywords: SettingsSearchCodexKeywords,
},
SearchEntry {
section: Agents,
title: SettingsAgentTraeCode,
keywords: SettingsSearchTraeCodeKeywords,
},
SearchEntry {
section: Agents,
title: SettingsAgentCopilotCli,
+8 -1
View File
@@ -1301,7 +1301,14 @@ impl Tty7App {
gpui::svg()
.path(agent.icon_path())
.size(px(size * 0.54))
.text_color(gpui::white()),
// SVG assets are rendered as a single-colour mask.
// TraeCode's black field comes from the avatar, and
// its brand mark uses the official green.
.text_color(if agent == crate::core::cli_agent::CLIAgent::TraeCode {
gpui::rgb(0x32F08C)
} else {
gpui::rgb(0xFFFFFF)
}),
)
.when_some(dot, |b, dot| b.child(dot))
.tooltip(move |window, cx| {