From d672b7b8f1fe04ba2bf8fbd01509e2e326f784a3 Mon Sep 17 00:00:00 2001 From: cschubiner Date: Sat, 4 Apr 2026 02:02:47 -0400 Subject: [PATCH 1/2] add toolchain guardrails --- .nvmrc | 1 + README.md | 30 ++++++++++++++ package.json | 51 ++++++++++++------------ scripts/check-toolchain.mjs | 78 +++++++++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 25 deletions(-) create mode 100644 .nvmrc create mode 100644 scripts/check-toolchain.mjs diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000000..32f8c50de0 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +24.13.1 diff --git a/README.md b/README.md index 93188ee240..44829cc6b1 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,36 @@ T3 Code is a minimal web GUI for coding agents (currently Codex and Claude, more ## Installation +## Local Development Toolchain + +This repo expects the versions declared in `.mise.toml`: + +- Node `24.13.1` +- Bun `1.3.9` + +Recommended setup: + +```bash +mise install +``` + +Then activate `mise` in your shell so entering the repo automatically uses the right versions. If you use `nvm`, there is also an `.nvmrc` with the same Node version. + +Quick verification: + +```bash +node -v +bun -v +``` + +Both should match the versions above before you run `bun run typecheck`, `bun run start:desktop:main-state`, or other repo scripts. + +The root scripts now fail fast with a direct toolchain error if your shell is on the wrong Node version. As a fallback, you can also run commands through `mise` explicitly: + +```bash +mise exec node@24.13.1 -- bun run typecheck +``` + > [!WARNING] > T3 Code currently supports Codex and Claude. > Install and authenticate at least one provider before use: diff --git a/package.json b/package.json index d409296ff5..8fae04c363 100644 --- a/package.json +++ b/package.json @@ -24,35 +24,36 @@ }, "type": "module", "scripts": { - "dev": "node scripts/dev-runner.ts dev", - "dev:server": "node scripts/dev-runner.ts dev:server", - "dev:web": "node scripts/dev-runner.ts dev:web", - "dev:marketing": "turbo run dev --filter=@t3tools/marketing", - "dev:desktop": "node scripts/dev-runner.ts dev:desktop", - "start": "turbo run start --filter=t3", - "start:desktop": "turbo run start --filter=@t3tools/desktop", - "start:desktop:main-state": "cd apps/desktop && T3CODE_STATE_DIR=\"$HOME/.t3/userdata\" bun run start", - "start:marketing": "turbo run preview --filter=@t3tools/marketing", - "start:mock-update-server": "bun run scripts/mock-update-server.ts", - "build": "turbo run build", - "build:marketing": "turbo run build --filter=@t3tools/marketing", - "build:desktop": "turbo run build --filter=@t3tools/desktop --filter=t3", - "typecheck": "turbo run typecheck", + "toolchain:check": "node scripts/check-toolchain.mjs", + "dev": "bun run toolchain:check && node scripts/dev-runner.ts dev", + "dev:server": "bun run toolchain:check && node scripts/dev-runner.ts dev:server", + "dev:web": "bun run toolchain:check && node scripts/dev-runner.ts dev:web", + "dev:marketing": "bun run toolchain:check && turbo run dev --filter=@t3tools/marketing", + "dev:desktop": "bun run toolchain:check && node scripts/dev-runner.ts dev:desktop", + "start": "bun run toolchain:check && turbo run start --filter=t3", + "start:desktop": "bun run toolchain:check && turbo run start --filter=@t3tools/desktop", + "start:desktop:main-state": "bun run toolchain:check && cd apps/desktop && T3CODE_STATE_DIR=\"$HOME/.t3/userdata\" bun run start", + "start:marketing": "bun run toolchain:check && turbo run preview --filter=@t3tools/marketing", + "start:mock-update-server": "bun run toolchain:check && bun run scripts/mock-update-server.ts", + "build": "bun run toolchain:check && turbo run build", + "build:marketing": "bun run toolchain:check && turbo run build --filter=@t3tools/marketing", + "build:desktop": "bun run toolchain:check && turbo run build --filter=@t3tools/desktop --filter=t3", + "typecheck": "bun run toolchain:check && turbo run typecheck", "lint": "oxlint --report-unused-disable-directives", - "test": "turbo run test", - "test:desktop-smoke": "turbo run smoke-test --filter=@t3tools/desktop", + "test": "bun run toolchain:check && turbo run test", + "test:desktop-smoke": "bun run toolchain:check && turbo run smoke-test --filter=@t3tools/desktop", "fmt": "oxfmt", "fmt:check": "oxfmt --check", - "build:contracts": "turbo run build --filter=@t3tools/contracts", - "dist:desktop:artifact": "node scripts/build-desktop-artifact.ts", - "dist:desktop:dmg": "node scripts/build-desktop-artifact.ts --platform mac --target dmg", - "dist:desktop:dmg:arm64": "node scripts/build-desktop-artifact.ts --platform mac --target dmg --arch arm64", - "dist:desktop:dmg:x64": "node scripts/build-desktop-artifact.ts --platform mac --target dmg --arch x64", - "dist:desktop:linux": "node scripts/build-desktop-artifact.ts --platform linux --target AppImage --arch x64", - "dist:desktop:win": "node scripts/build-desktop-artifact.ts --platform win --target nsis --arch x64", - "release:smoke": "node scripts/release-smoke.ts", + "build:contracts": "bun run toolchain:check && turbo run build --filter=@t3tools/contracts", + "dist:desktop:artifact": "bun run toolchain:check && node scripts/build-desktop-artifact.ts", + "dist:desktop:dmg": "bun run toolchain:check && node scripts/build-desktop-artifact.ts --platform mac --target dmg", + "dist:desktop:dmg:arm64": "bun run toolchain:check && node scripts/build-desktop-artifact.ts --platform mac --target dmg --arch arm64", + "dist:desktop:dmg:x64": "bun run toolchain:check && node scripts/build-desktop-artifact.ts --platform mac --target dmg --arch x64", + "dist:desktop:linux": "bun run toolchain:check && node scripts/build-desktop-artifact.ts --platform linux --target AppImage --arch x64", + "dist:desktop:win": "bun run toolchain:check && node scripts/build-desktop-artifact.ts --platform win --target nsis --arch x64", + "release:smoke": "bun run toolchain:check && node scripts/release-smoke.ts", "clean": "rm -rf node_modules apps/*/node_modules packages/*/node_modules apps/*/dist apps/*/dist-electron packages/*/dist .turbo apps/*/.turbo packages/*/.turbo", - "sync:vscode-icons": "node scripts/sync-vscode-icons.mjs" + "sync:vscode-icons": "bun run toolchain:check && node scripts/sync-vscode-icons.mjs" }, "devDependencies": { "@types/node": "catalog:", diff --git a/scripts/check-toolchain.mjs b/scripts/check-toolchain.mjs new file mode 100644 index 0000000000..428bf04905 --- /dev/null +++ b/scripts/check-toolchain.mjs @@ -0,0 +1,78 @@ +#!/usr/bin/env node + +import { execFileSync } from "node:child_process"; +import { readFileSync } from "node:fs"; +import { join } from "node:path"; + +const FALLBACK_NODE_VERSION = "24.13.1"; +const FALLBACK_BUN_VERSION = "1.3.9"; + +function readMiseToolVersion(toolName) { + const misePath = join(import.meta.dirname, "..", ".mise.toml"); + const contents = readFileSync(misePath, "utf8"); + const match = contents.match(new RegExp(`^${toolName}\\s*=\\s*"([^"]+)"$`, "m")); + return match?.[1] ?? null; +} + +function normalizeVersion(version) { + return version.startsWith("v") ? version.slice(1) : version; +} + +function parseVersion(version) { + const [major = "0", minor = "0", patch = "0"] = normalizeVersion(version).split("."); + return { + major: Number(major), + minor: Number(minor), + patch: Number(patch), + }; +} + +function isCompatibleVersion(current, expected) { + if (current.major !== expected.major) { + return false; + } + if (current.minor !== expected.minor) { + return current.minor > expected.minor; + } + return current.patch >= expected.patch; +} + +function readCurrentBunVersion() { + try { + return normalizeVersion(execFileSync("bun", ["--version"], { encoding: "utf8" }).trim()); + } catch { + return null; + } +} + +function exitWithToolingGuidance(message) { + console.error(message); + console.error(""); + console.error("Fix:"); + console.error(" 1. Run `mise install`."); + console.error( + " 2. Activate mise in your shell so this repo picks the right Node/Bun automatically.", + ); + console.error(" 3. Or run commands with `mise exec node@24.13.1 -- bun run