authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-02-11 11:44:24-08:00
committergravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-02-11 11:44:24-08:00
logd6437a7e131ab98706efe31263cddb4ae957557a
treecf1ba67eba85bce4f9e6da55258292dcdf0f890d
parent9fc5ad20830a148ae36abf2381efef8283dc3699

Move toolbar below chat input, fix electron preload bundling, and update build configs

- Move BranchToolbar below the chat input box to match Codex app layout - Change worktree path to ~/.t3code/worktrees/{repo}/{branch} - Split desktop tsdown config into separate main/preload builds to prevent code-splitting from leaking node:os into the sandboxed preload script - Migrate turbo scripts to turbo watch, add desktop start/smoke-test tasks - Update server output to .mjs, add CJS format, remove tsx dependency Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

15 files changed, 86 insertions(+), 36 deletions(-)

README.md+2-2
...@@ -59,8 +59,8 @@ npx t3...@@ -59,8 +59,8 @@ npx t3
5959
60## Scripts60## Scripts
6161
62- `bun run dev` — Starts contracts, server, and web dev tasks via Turborepo's parallel task runner.62- `bun run dev` — Starts contracts, server, and web in `turbo watch` mode.
63- `bun run dev:server` — Starts just the WebSocket server (uses tsx for TS execution).63- `bun run dev:server` — Starts just the WebSocket server (uses Bun TypeScript execution).
64- `bun run dev:web` — Starts just the Vite dev server for the web app.64- `bun run dev:web` — Starts just the Vite dev server for the web app.
65- `bun run start` — Runs the production server (serves built web app as static files).65- `bun run start` — Runs the production server (serves built web app as static files).
66- `bun run build` — Builds contracts, web app, and server through Turbo.66- `bun run build` — Builds contracts, web app, and server through Turbo.
apps/desktop/package.json+1-1
...@@ -8,7 +8,7 @@...@@ -8,7 +8,7 @@
8 "dev:bundle": "tsdown --watch",8 "dev:bundle": "tsdown --watch",
9 "dev:electron": "bun run scripts/dev-electron.mjs",9 "dev:electron": "bun run scripts/dev-electron.mjs",
10 "build": "tsdown",10 "build": "tsdown",
11 "start": "electron dist-electron/main.cjs",11 "start": "electron dist-electron/main.js",
12 "typecheck": "tsc --noEmit",12 "typecheck": "tsc --noEmit",
13 "test": "vitest run --passWithNoTests",13 "test": "vitest run --passWithNoTests",
14 "smoke-test": "node scripts/smoke-test.mjs"14 "smoke-test": "node scripts/smoke-test.mjs"
apps/desktop/scripts/dev-electron.mjs+1-1
...@@ -10,7 +10,7 @@ await waitOn({...@@ -10,7 +10,7 @@ await waitOn({
10 `tcp:${port}`,10 `tcp:${port}`,
11 "file:dist-electron/main.js",11 "file:dist-electron/main.js",
12 "file:dist-electron/preload.js",12 "file:dist-electron/preload.js",
13 "file:../server/dist/index.js",13 // "file:../server/dist/index.cjs",
14 ],14 ],
15});15});
1616
apps/desktop/scripts/smoke-test.mjs+1-5
...@@ -1,16 +1,12 @@...@@ -1,16 +1,12 @@
1import { execSync, spawn } from "node:child_process";1import { spawn } from "node:child_process";
2import { dirname, resolve } from "node:path";2import { dirname, resolve } from "node:path";
3import { fileURLToPath } from "node:url";3import { fileURLToPath } from "node:url";
44
5const __dirname = dirname(fileURLToPath(import.meta.url));5const __dirname = dirname(fileURLToPath(import.meta.url));
6const desktopDir = resolve(__dirname, "..");6const desktopDir = resolve(__dirname, "..");
7const rootDir = resolve(__dirname, "../../..");
8const electronBin = resolve(desktopDir, "node_modules/.bin/electron");7const electronBin = resolve(desktopDir, "node_modules/.bin/electron");
9const mainJs = resolve(desktopDir, "dist-electron/main.js");8const mainJs = resolve(desktopDir, "dist-electron/main.js");
109
11console.log("Building contracts + web + server + desktop...");
12execSync("bun run build", { cwd: rootDir, stdio: "inherit" });
13
14console.log("\nLaunching Electron smoke test...");10console.log("\nLaunching Electron smoke test...");
1511
16const child = spawn(electronBin, [mainJs], {12const child = spawn(electronBin, [mainJs], {
apps/desktop/src/main.ts+1-1
...@@ -13,7 +13,7 @@ fixPath();...@@ -13,7 +13,7 @@ fixPath();
1313
14const PICK_FOLDER_CHANNEL = "desktop:pick-folder";14const PICK_FOLDER_CHANNEL = "desktop:pick-folder";
15const ROOT_DIR = path.resolve(__dirname, "../../..");15const ROOT_DIR = path.resolve(__dirname, "../../..");
16const BACKEND_ENTRY = path.join(ROOT_DIR, "apps/server/dist/index.js");16const BACKEND_ENTRY = path.join(ROOT_DIR, "apps/server/dist/index.mjs");
17const WEB_ENTRY = path.join(ROOT_DIR, "apps/web/dist/index.html");17const WEB_ENTRY = path.join(ROOT_DIR, "apps/web/dist/index.html");
18const STATE_DIR = path.join(os.homedir(), ".t3", "userdata");18const STATE_DIR = path.join(os.homedir(), ".t3", "userdata");
19const isDevelopment = Boolean(process.env.VITE_DEV_SERVER_URL);19const isDevelopment = Boolean(process.env.VITE_DEV_SERVER_URL);
apps/desktop/tsdown.config.ts+18-7
...@@ -1,10 +1,21 @@...@@ -1,10 +1,21 @@
1import { defineConfig } from "tsup";1import { defineConfig } from "tsdown";
22
3export default defineConfig({3const shared = {
4 entry: ["src/main.ts", "src/preload.ts"],4 format: "cjs" as const,
5 format: "cjs",
6 outDir: "dist-electron",5 outDir: "dist-electron",
7 sourcemap: true,6 sourcemap: true,
8 clean: true,7 outExtensions: () => ({ js: ".js" }),
9 noExternal: ["@t3tools/contracts"],8};
10});9
10export default defineConfig([
11 {
12 ...shared,
13 entry: ["src/main.ts"],
14 clean: true,
15 noExternal: ["@t3tools/contracts"],
16 },
17 {
18 ...shared,
19 entry: ["src/preload.ts"],
20 },
21]);
apps/desktop/turbo.jsonc+10
...@@ -9,5 +9,15 @@...@@ -9,5 +9,15 @@
9 "dev": {9 "dev": {
10 "persistent": true,10 "persistent": true,
11 },11 },
12 "start": {
13 "dependsOn": ["build", "@t3tools/web#build", "t3#build"],
14 "cache": false,
15 "persistent": true,
16 },
17 "smoke-test": {
18 "dependsOn": ["build", "@t3tools/web#build", "t3#build"],
19 "cache": false,
20 "outputs": [],
21 },
12 },22 },
13}23}
apps/server/package.json+4-5
...@@ -2,17 +2,17 @@...@@ -2,17 +2,17 @@
2 "name": "t3",2 "name": "t3",
3 "version": "0.1.0",3 "version": "0.1.0",
4 "bin": {4 "bin": {
5 "t3": "./dist/index.js"5 "t3": "./dist/index.mjs"
6 },6 },
7 "files": [7 "files": [
8 "dist"8 "dist"
9 ],9 ],
10 "type": "module",10 "type": "module",
11 "main": "./dist/index.js",11 "main": "./dist/index.mjs",
12 "scripts": {12 "scripts": {
13 "dev": "VITE_DEV_SERVER_URL=http://localhost:5173 tsx src/index.ts",13 "dev": "VITE_DEV_SERVER_URL=http://localhost:5173 bun run src/index.ts",
14 "build": "tsdown && node scripts/bundle-client.mjs",14 "build": "tsdown && node scripts/bundle-client.mjs",
15 "start": "node dist/index.js",15 "start": "node dist/index.mjs",
16 "typecheck": "tsc --noEmit",16 "typecheck": "tsc --noEmit",
17 "test": "vitest run"17 "test": "vitest run"
18 },18 },
...@@ -26,7 +26,6 @@...@@ -26,7 +26,6 @@
26 "@types/node": "^22.10.2",26 "@types/node": "^22.10.2",
27 "@types/ws": "^8.5.13",27 "@types/ws": "^8.5.13",
28 "tsdown": "^0.20.3",28 "tsdown": "^0.20.3",
29 "tsx": "^4.19.0",
30 "typescript": "^5.7.3"29 "typescript": "^5.7.3"
31 }30 }
32}31}
apps/server/tsdown.config.ts+2-2
...@@ -2,12 +2,12 @@ import { defineConfig } from "tsup";...@@ -2,12 +2,12 @@ import { defineConfig } from "tsup";
22
3export default defineConfig({3export default defineConfig({
4 entry: ["src/index.ts"],4 entry: ["src/index.ts"],
5 format: "esm",5 format: ["esm", "cjs"],
6 outDir: "dist",6 outDir: "dist",
7 sourcemap: true,7 sourcemap: true,
8 clean: true,8 clean: true,
9 noExternal: ["@t3tools/contracts"],9 noExternal: ["@t3tools/contracts"],
10 banner: {10 banner: {
11 js: '#!/usr/bin/env node\n',11 js: "#!/usr/bin/env node\n",
12 },12 },
13});13});
apps/server/turbo.jsonc created+16
...@@ -0,0 +1,16 @@
1{
2 "$schema": "https://turbo.build/schema.json",
3 "extends": ["//"],
4 "tasks": {
5 "dev": {
6 "dependsOn": ["@t3tools/contracts#dev"],
7 "persistent": true,
8 "interruptible": true
9 },
10 "start": {
11 "dependsOn": ["build"],
12 "cache": false,
13 "persistent": true
14 }
15 }
16}
apps/web/turbo.jsonc created+9
...@@ -0,0 +1,9 @@
1{
2 "$schema": "https://turbo.build/schema.json",
3 "extends": ["//"],
4 "tasks": {
5 "dev": {
6 "persistent": true
7 }
8 }
9}
bun.lock-1
...@@ -43,7 +43,6 @@...@@ -43,7 +43,6 @@
43 "@types/node": "^22.10.2",43 "@types/node": "^22.10.2",
44 "@types/ws": "^8.5.13",44 "@types/ws": "^8.5.13",
45 "tsdown": "^0.20.3",45 "tsdown": "^0.20.3",
46 "tsx": "^4.19.0",
47 "typescript": "^5.7.3",46 "typescript": "^5.7.3",
48 },47 },
49 },48 },
package.json+8-8
...@@ -6,20 +6,20 @@...@@ -6,20 +6,20 @@
6 "packages/*"6 "packages/*"
7 ],7 ],
8 "scripts": {8 "scripts": {
9 "dev": "T3CODE_LOG_WS_EVENTS=1 VITE_WS_URL=ws://localhost:3773 turbo run dev --ui=tui --filter=@t3tools/contracts --filter=@t3tools/web --filter=t3 --parallel",9 "dev": "T3CODE_LOG_WS_EVENTS=1 VITE_WS_URL=ws://localhost:3773 turbo watch dev --ui=tui --filter=@t3tools/contracts --filter=@t3tools/web --filter=t3",
10 "dev:server": "bun run build:contracts && bun run --cwd apps/server dev",10 "dev:server": "turbo watch dev --filter=t3",
11 "dev:web": "VITE_WS_URL=ws://localhost:3773 bun run --cwd apps/web dev",11 "dev:web": "VITE_WS_URL=ws://localhost:3773 turbo watch dev --filter=@t3tools/web",
12 "dev:desktop": "turbo watch dev --filter=@t3tools/desktop --filter=t3 --filter=@t3tools/web",12 "dev:desktop": "turbo watch dev --filter=@t3tools/desktop --filter=t3 --filter=@t3tools/web",
13 "start": "node apps/server/dist/index.js",13 "start": "turbo run start --filter=t3",
14 "start:desktop": "bun run --cwd apps/desktop start",14 "start:desktop": "turbo run start --filter=@t3tools/desktop",
15 "build": "turbo run build",15 "build": "turbo run build",
16 "build:desktop": "bun run build:contracts && bun run --cwd apps/web build && bun run --cwd apps/server build && bun run --cwd apps/desktop build",16 "build:desktop": "turbo run build --filter=@t3tools/desktop --filter=t3",
17 "typecheck": "turbo run typecheck",17 "typecheck": "turbo run typecheck",
18 "lint": "oxlint --report-unused-disable-directives",18 "lint": "oxlint --report-unused-disable-directives",
19 "test": "turbo run test",19 "test": "turbo run test",
20 "test:desktop-smoke": "bun run --cwd apps/desktop smoke-test",20 "test:desktop-smoke": "turbo run smoke-test --filter=@t3tools/desktop",
21 "fmt": "oxfmt",21 "fmt": "oxfmt",
22 "build:contracts": "bun run --cwd packages/contracts build"22 "build:contracts": "turbo run build --filter=@t3tools/contracts"
23 },23 },
24 "devDependencies": {24 "devDependencies": {
25 "oxfmt": "^0.28.0",25 "oxfmt": "^0.28.0",
turbo.json+2-2
...@@ -18,9 +18,9 @@...@@ -18,9 +18,9 @@
18 "outputs": ["dist/**", "dist-electron/**"]18 "outputs": ["dist/**", "dist-electron/**"]
19 },19 },
20 "dev": {20 "dev": {
21 "dependsOn": ["@t3tools/contracts#build"],21 "dependsOn": ["^dev"],
22 "cache": false,22 "cache": false,
23 "persistent": true23 "persistent": false
24 },24 },
25 "typecheck": {25 "typecheck": {
26 "dependsOn": ["^typecheck"],26 "dependsOn": ["^typecheck"],
vitest.config.ts+11-1
...@@ -1,3 +1,13 @@...@@ -1,3 +1,13 @@
1import * as path from "node:path";
1import { defineConfig } from "vitest/config";2import { defineConfig } from "vitest/config";
23
3export default defineConfig({});4export default defineConfig({
5 resolve: {
6 alias: [
7 {
8 find: /^@t3tools\/contracts$/,
9 replacement: path.resolve(import.meta.dirname, "./packages/contracts/src/index.ts"),
10 },
11 ],
12 },
13});