Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion apps/desktop/bunfig.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
[test]
# Preload test setup before running tests
preload = ["./test-setup.ts"]
# xterm-env-polyfill: @xterm/headless 6.x references `window` at module load, which
# throws in Bun since its navigator.userAgent causes xterm's isNode check to return false
preload = ["./src/main/terminal-host/xterm-env-polyfill.ts", "./test-setup.ts"]

[test.env]
NODE_ENV = "test"
Expand Down
20 changes: 10 additions & 10 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,16 @@
"@trpc/server": "^11.7.1",
"@types/express": "^5.0.5",
"@vercel/blob": "^2.0.0",
"@xterm/addon-clipboard": "^0.2.0",
"@xterm/addon-fit": "^0.11.0",
"@xterm/addon-image": "^0.9.0",
"@xterm/addon-ligatures": "^0.10.0",
"@xterm/addon-search": "^0.16.0",
"@xterm/addon-serialize": "^0.14.0",
"@xterm/addon-unicode11": "^0.9.0",
"@xterm/addon-webgl": "^0.19.0",
"@xterm/headless": "^6.0.0",
"@xterm/xterm": "^6.0.0",
"@xterm/addon-clipboard": "0.3.0-beta.109",
"@xterm/addon-fit": "0.12.0-beta.109",
"@xterm/addon-image": "0.10.0-beta.109",
"@xterm/addon-ligatures": "0.11.0-beta.109",
"@xterm/addon-search": "0.17.0-beta.109",
"@xterm/addon-serialize": "0.15.0-beta.109",
"@xterm/addon-unicode11": "0.10.0-beta.109",
"@xterm/addon-webgl": "0.20.0-beta.109",
"@xterm/headless": "6.1.0-beta.109",
"@xterm/xterm": "6.1.0-beta.109",
"better-auth": "1.4.17",
"better-sqlite3": "12.6.2",
"bindings": "^1.5.0",
Expand Down
22 changes: 14 additions & 8 deletions apps/desktop/src/main/terminal-host/daemon.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const PID_PATH = join(SUPERSET_HOME_DIR, "terminal-host.pid");

// Path to the daemon source file
const DAEMON_PATH = resolve(__dirname, "index.ts");
// Polyfill for @xterm/headless in Bun (see xterm-env-polyfill.ts for details)
const XTERM_POLYFILL_PATH = resolve(__dirname, "xterm-env-polyfill.ts");

// Timeout for daemon operations
const DAEMON_TIMEOUT = 10000;
Expand Down Expand Up @@ -93,15 +95,19 @@ describe("Terminal Host Daemon", () => {
mkdirSync(SUPERSET_HOME_DIR, { recursive: true, mode: 0o700 });
}

// Start daemon with tsx (bun's typescript runner)
daemonProcess = spawn("bun", ["run", DAEMON_PATH], {
env: {
...process.env,
NODE_ENV: "development",
// Start daemon with --preload to polyfill window for @xterm/headless in Bun
daemonProcess = spawn(
"bun",
["run", "--preload", XTERM_POLYFILL_PATH, DAEMON_PATH],
{
env: {
...process.env,
NODE_ENV: "development",
},
stdio: ["ignore", "pipe", "pipe"],
detached: true,
},
stdio: ["ignore", "pipe", "pipe"],
detached: true,
});
);

let output = "";
let settled = false;
Expand Down
20 changes: 13 additions & 7 deletions apps/desktop/src/main/terminal-host/session-lifecycle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const PID_PATH = join(SUPERSET_HOME_DIR, "terminal-host.pid");

// Path to the daemon source file
const DAEMON_PATH = resolve(__dirname, "index.ts");
// Polyfill for @xterm/headless in Bun (see xterm-env-polyfill.ts for details)
const XTERM_POLYFILL_PATH = resolve(__dirname, "xterm-env-polyfill.ts");

// Timeouts
const DAEMON_TIMEOUT = 10000;
Expand Down Expand Up @@ -94,14 +96,18 @@ describe("Terminal Host Session Lifecycle", () => {
mkdirSync(SUPERSET_HOME_DIR, { recursive: true, mode: 0o700 });
}

daemonProcess = spawn("bun", ["run", DAEMON_PATH], {
env: {
...process.env,
NODE_ENV: "development",
daemonProcess = spawn(
"bun",
["run", "--preload", XTERM_POLYFILL_PATH, DAEMON_PATH],
{
env: {
...process.env,
NODE_ENV: "development",
},
stdio: ["ignore", "pipe", "pipe"],
detached: true,
},
stdio: ["ignore", "pipe", "pipe"],
detached: true,
});
);

let output = "";
let settled = false;
Expand Down
17 changes: 17 additions & 0 deletions apps/desktop/src/main/terminal-host/xterm-env-polyfill.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Polyfill for @xterm/headless in Bun.
*
* @xterm/headless 6.x detects Node via `navigator.userAgent.startsWith("Node.js/")`.
* Bun sets `navigator.userAgent` to `"Bun/..."`, so `isNode` is false and the bundle
* falls through to `"requestIdleCallback" in window`, which throws because `window`
* is undefined in server runtimes.
*
* Setting `globalThis.window = globalThis` makes the `in` check succeed without error.
* `requestIdleCallback` doesn't exist on `globalThis` in Bun/Node, so the correct
* fallback (PriorityTaskQueue) is used anyway.
*
* This file MUST be imported before any @xterm/headless import.
*/
if (typeof window === "undefined") {
(globalThis as Record<string, unknown>).window = globalThis;
}
52 changes: 23 additions & 29 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.