From e94349f105f55f6bd60e9e00b2a1c1a4c690a7f9 Mon Sep 17 00:00:00 2001
From: Lars Nieuwenhuis <35393046+lnieuwenhuis@users.noreply.github.com>
Date: Sat, 7 Mar 2026 13:49:02 +0100
Subject: [PATCH] Added support for Trae IDE
To make all the tests pass, I had GPT-5.4 go through until they all passed.
---
apps/server/src/open.test.ts | 18 ++++++++++++
apps/web/src/components/ChatView.tsx | 24 ++++++++++++++--
apps/web/src/components/Icons.tsx | 10 +++++++
apps/web/src/test/setup.ts | 43 ++++++++++++++++++++++++++++
apps/web/vitest.config.ts | 12 ++++++++
bun.lock | 12 ++------
package.json | 3 ++
packages/contracts/src/editor.ts | 1 +
scripts/build-desktop-artifact.ts | 28 ++++++++++++++----
scripts/dev-runner.ts | 24 ++++++++++++----
10 files changed, 152 insertions(+), 23 deletions(-)
create mode 100644 apps/web/src/test/setup.ts
create mode 100644 apps/web/vitest.config.ts
diff --git a/apps/server/src/open.test.ts b/apps/server/src/open.test.ts
index 0f864554e..67a91cf2d 100644
--- a/apps/server/src/open.test.ts
+++ b/apps/server/src/open.test.ts
@@ -34,6 +34,15 @@ describe("resolveEditorLaunch", () => {
args: ["/tmp/workspace"],
});
+ const traeLaunch = yield* resolveEditorLaunch(
+ { cwd: "/tmp/workspace", editor: "trae" },
+ "darwin",
+ );
+ assert.deepEqual(traeLaunch, {
+ command: "trae",
+ args: ["/tmp/workspace"],
+ });
+
const zedLaunch = yield* resolveEditorLaunch(
{ cwd: "/tmp/workspace", editor: "zed" },
"darwin",
@@ -74,6 +83,15 @@ describe("resolveEditorLaunch", () => {
args: ["--goto", "/tmp/workspace/src/open.ts:71:5"],
});
+ const traeLineAndColumn = yield* resolveEditorLaunch(
+ { cwd: "/tmp/workspace/src/open.ts:71:5", editor: "trae" },
+ "darwin",
+ );
+ assert.deepEqual(traeLineAndColumn, {
+ command: "trae",
+ args: ["/tmp/workspace/src/open.ts:71:5"],
+ });
+
const zedLineAndColumn = yield* resolveEditorLaunch(
{ cwd: "/tmp/workspace/src/open.ts:71:5", editor: "zed" },
"darwin",
diff --git a/apps/web/src/components/ChatView.tsx b/apps/web/src/components/ChatView.tsx
index c1693f419..27c392109 100644
--- a/apps/web/src/components/ChatView.tsx
+++ b/apps/web/src/components/ChatView.tsx
@@ -168,6 +168,7 @@ import {
Icon,
OpenAI,
OpenCodeIcon,
+ TraeIcon,
VisualStudioCode,
Zed,
} from "./Icons";
@@ -5575,6 +5576,11 @@ const OpenInPicker = memo(function OpenInPicker({
Icon: CursorIcon,
value: "cursor",
},
+ {
+ label: "Trae",
+ Icon: TraeIcon,
+ value: "trae",
+ },
{
label: "VS Code",
Icon: VisualStudioCode,
@@ -5606,6 +5612,15 @@ const OpenInPicker = memo(function OpenInPicker({
? lastEditor
: (options[0]?.value ?? null);
const primaryOption = options.find(({ value }) => value === effectiveEditor) ?? null;
+ const getEditorIconClassName = useCallback(
+ (editor: EditorId, surface: "button" | "menu") => {
+ if (surface === "button") {
+ return editor === "trae" ? "size-4" : "size-3.5";
+ }
+ return cn("text-muted-foreground", editor === "trae" && "size-5 sm:size-4.5");
+ },
+ [],
+ );
const openInEditor = useCallback(
(editorId: EditorId | null) => {
@@ -5647,7 +5662,12 @@ const OpenInPicker = memo(function OpenInPicker({
disabled={!effectiveEditor || !openInCwd}
onClick={() => openInEditor(effectiveEditor)}
>
- {primaryOption?.Icon && }
+ {primaryOption?.Icon && (
+
+ )}
Open
@@ -5661,7 +5681,7 @@ const OpenInPicker = memo(function OpenInPicker({
{options.length === 0 && }
{options.map(({ label, Icon, value }) => (