From 91f4b477c392e7c34a0cdee08c871b33f9145d05 Mon Sep 17 00:00:00 2001 From: Ivan Malison Date: Sun, 12 Jul 2026 12:47:16 -0700 Subject: [PATCH] Remove the t3code package --- nix-shared/overlays/default.nix | 5 +- nixos/code.nix | 1 - .../t3code/canonicalize-node-modules.ts | 105 -------- nixos/packages/t3code/default.nix | 249 ------------------ .../packages/t3code/normalize-bun-binaries.ts | 135 ---------- 5 files changed, 2 insertions(+), 493 deletions(-) delete mode 100644 nixos/packages/t3code/canonicalize-node-modules.ts delete mode 100644 nixos/packages/t3code/default.nix delete mode 100644 nixos/packages/t3code/normalize-bun-binaries.ts diff --git a/nix-shared/overlays/default.nix b/nix-shared/overlays/default.nix index 550a7738..ace2e19c 100644 --- a/nix-shared/overlays/default.nix +++ b/nix-shared/overlays/default.nix @@ -32,7 +32,7 @@ final: prev: { # Fix poetry pbs-installer version constraint issue poetry = prev.poetry.overrideAttrs (oldAttrs: { dontCheckRuntimeDeps = true; - }); + }); direnv = prev.direnv.overrideAttrs (_: { doCheck = false; @@ -280,10 +280,9 @@ from transformers import (/' \ -e '/^ BeamSearchScorer,$/d' \ TTS/tts/layers/xtts/stream_generator.py ''; - }); + }); playwright-cli = final.callPackage ../../nixos/packages/playwright-cli { }; - t3code = final.callPackage ../../nixos/packages/t3code { }; # Custom Waybar fork for workspace taskbar support + external SNI watcher option. waybar = prev.waybar.overrideAttrs (old: { src = prev.fetchFromGitHub { diff --git a/nixos/code.nix b/nixos/code.nix index 50cb28c1..b9a71923 100644 --- a/nixos/code.nix +++ b/nixos/code.nix @@ -127,7 +127,6 @@ in inputs.gmcli.packages.${pkgs.stdenv.hostPlatform.system}.default inputs.lastfm-edit.packages.${pkgs.stdenv.hostPlatform.system}.scrobble-scrubber-app opencode - t3code # MCP github-mcp-server diff --git a/nixos/packages/t3code/canonicalize-node-modules.ts b/nixos/packages/t3code/canonicalize-node-modules.ts deleted file mode 100644 index f053b9a4..00000000 --- a/nixos/packages/t3code/canonicalize-node-modules.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { lstat, mkdir, readdir, rm, symlink } from "fs/promises"; -import { join, relative } from "path"; - -type Entry = { - dir: string; - version: string; -}; - -async function isDirectory(path: string) { - try { - const info = await lstat(path); - return info.isDirectory(); - } catch { - return false; - } -} - -const isValidSemver = (version: string) => Bun.semver.satisfies(version, "x.x.x"); - -const bunRoot = join(process.cwd(), "node_modules/.bun"); -const linkRoot = join(bunRoot, "node_modules"); -const directories = (await readdir(bunRoot)).sort(); - -const versions = new Map(); - -for (const entry of directories) { - const full = join(bunRoot, entry); - if (!(await isDirectory(full))) { - continue; - } - - const parsed = parseEntry(entry); - if (!parsed) { - continue; - } - - const list = versions.get(parsed.name) ?? []; - list.push({ dir: full, version: parsed.version }); - versions.set(parsed.name, list); -} - -const selections = new Map(); - -for (const [slug, list] of versions) { - list.sort((a, b) => { - const aValid = isValidSemver(a.version); - const bValid = isValidSemver(b.version); - - if (aValid && bValid) { - return -Bun.semver.order(a.version, b.version); - } - if (aValid) { - return -1; - } - if (bValid) { - return 1; - } - return b.version.localeCompare(a.version); - }); - - const first = list[0]; - if (first) { - selections.set(slug, first); - } -} - -await rm(linkRoot, { recursive: true, force: true }); -await mkdir(linkRoot, { recursive: true }); - -for (const [slug, entry] of Array.from(selections.entries()).sort((a, b) => a[0].localeCompare(b[0]))) { - const parts = slug.split("/"); - const leaf = parts.pop(); - if (!leaf) { - continue; - } - - const parent = join(linkRoot, ...parts); - await mkdir(parent, { recursive: true }); - - const linkPath = join(parent, leaf); - const desired = join(entry.dir, "node_modules", slug); - if (!(await isDirectory(desired))) { - continue; - } - - const relativeTarget = relative(parent, desired); - await rm(linkPath, { recursive: true, force: true }); - await symlink(relativeTarget.length == 0 ? "." : relativeTarget, linkPath); -} - -function parseEntry(label: string) { - const marker = label.startsWith("@") ? label.indexOf("@", 1) : label.indexOf("@"); - if (marker <= 0) { - return null; - } - - const name = label.slice(0, marker).replace(/\+/g, "/"); - const version = label.slice(marker + 1); - - if (!name || !version) { - return null; - } - - return { name, version }; -} diff --git a/nixos/packages/t3code/default.nix b/nixos/packages/t3code/default.nix deleted file mode 100644 index 7f7b15e9..00000000 --- a/nixos/packages/t3code/default.nix +++ /dev/null @@ -1,249 +0,0 @@ -{ - buildPackages, - lib, - stdenv, - stdenvNoCC, - fetchFromGitHub, - nix-update-script, - makeDesktopItem, - electron_40, - nodejs, -}: -stdenv.mkDerivation ( - finalAttrs: let - electron = electron_40; - nodeModules = stdenvNoCC.mkDerivation { - pname = "${finalAttrs.pname}-node_modules"; - inherit (finalAttrs) src version strictDeps; - - nativeBuildInputs = [ - buildPackages.bun - buildPackages.nodejs - buildPackages.writableTmpDirAsHomeHook - ]; - - dontConfigure = true; - dontFixup = true; - - postPatch = '' - replacePackageVersion() { - local packageJson="$1" - local currentVersion="$(sed -n 's/.*"version": "\([^"]*\)".*/\1/p' "$packageJson" | head -n1)" - local currentVersionPattern - - printf -v currentVersionPattern '"version": "%s"' "$currentVersion" - - substituteInPlace "$packageJson" \ - --replace-fail "$currentVersionPattern" '"version": "${finalAttrs.version}"' - } - - for packageJson in \ - apps/{desktop,server,web}/package.json \ - packages/{contracts,shared}/package.json - do - replacePackageVersion "$packageJson" - done - - for packageJson in packages/{contracts,shared}/package.json; do - substituteInPlace "$packageJson" \ - --replace-fail '"prepare": "effect-language-service patch",' '"prepare": "true",' - done - ''; - - buildPhase = '' - runHook preBuild - - bun install \ - --cpu="*" \ - --ignore-scripts \ - --no-progress \ - --frozen-lockfile \ - --os="*" - - bun --bun ${./canonicalize-node-modules.ts} - bun --bun ${./normalize-bun-binaries.ts} - - runHook postBuild - ''; - - installPhase = '' - runHook preInstall - - mkdir -p $out - cp -r node_modules $out - find apps packages -type d -name node_modules -exec cp -r --parents {} $out \; - - runHook postInstall - ''; - - outputHash = "sha256-yrzdhw+NPYZku10piHoxMy+TUJ8MYySZorMOMOztJY4="; - outputHashMode = "recursive"; - }; - in { - pname = "t3code"; - version = "0.0.15"; - strictDeps = true; - - src = fetchFromGitHub { - owner = "pingdotgg"; - repo = "t3code"; - tag = "v${finalAttrs.version}"; - hash = "sha256-HOPiA8X/FzswKGmOuYKog3YIn5iq5rJ/7kDoGhN11x0="; - }; - - postPatch = '' - replacePackageVersion() { - local packageJson="$1" - local currentVersion="$(sed -n 's/.*"version": "\([^"]*\)".*/\1/p' "$packageJson" | head -n1)" - local currentVersionPattern - - printf -v currentVersionPattern '"version": "%s"' "$currentVersion" - - substituteInPlace "$packageJson" \ - --replace-fail "$currentVersionPattern" '"version": "${finalAttrs.version}"' - } - - for packageJson in \ - apps/{desktop,server,web}/package.json \ - packages/contracts/package.json - do - replacePackageVersion "$packageJson" - done - - printf -v resourcePathSearch '%s\n%s' \ - 'Path.join(__dirname, "../prod-resources", fileName),' \ - ' Path.join(process.resourcesPath, "resources", fileName),' - printf -v resourcePathReplacement '%s\n%s\n%s' \ - 'Path.join(__dirname, "../prod-resources", fileName),' \ - ' Path.join(ROOT_DIR, "apps", "desktop", "prod-resources", fileName),' \ - ' Path.join(process.resourcesPath, "resources", fileName),' - - substituteInPlace apps/desktop/src/main.ts \ - --replace-fail "$resourcePathSearch" "$resourcePathReplacement" - - substituteInPlace apps/web/vite.config.ts \ - --replace-fail ' server: {' $' server: {\n host: "127.0.0.1",' \ - --replace-fail 'host: "localhost"' 'host: "127.0.0.1"' - ''; - - nativeBuildInputs = - [ - buildPackages.bun - buildPackages.copyDesktopItems - buildPackages.installShellFiles - buildPackages.makeBinaryWrapper - buildPackages.node-gyp - buildPackages.nodejs - buildPackages.python3 - buildPackages.writableTmpDirAsHomeHook - ] - ++ lib.optionals stdenv.buildPlatform.isDarwin [ - buildPackages.cctools.libtool - buildPackages.xcbuild - ]; - - nativeInstallCheckInputs = [buildPackages.versionCheckHook]; - doInstallCheck = stdenv.buildPlatform.canExecute stdenv.hostPlatform; - - configurePhase = '' - runHook preConfigure - - cp -r ${nodeModules}/. . - - chmod -R u+rwX node_modules - patchShebangs node_modules - - export npm_config_nodedir=${nodejs} - cd node_modules/.bun/node-pty@*/node_modules/node-pty - node-gyp rebuild - node scripts/post-install.js - cd - - - runHook postConfigure - ''; - - buildPhase = '' - runHook preBuild - - for app in web server desktop; do - bun run --cwd apps/"$app" build - done - - runHook postBuild - ''; - - installPhase = '' - runHook preInstall - - mkdir -p "$out"/libexec/t3code/apps/desktop "$out"/libexec/t3code/apps/server - cp -r --no-preserve=mode node_modules "$out"/libexec/t3code - cp -r --no-preserve=mode apps/server/{node_modules,dist} "$out"/libexec/t3code/apps/server - cp -r --no-preserve=mode apps/desktop/{node_modules,dist-electron} "$out"/libexec/t3code/apps/desktop - - mkdir -p "$out"/libexec/t3code/apps/desktop/prod-resources - install -m444 assets/prod/black-universal-1024.png \ - "$out"/libexec/t3code/apps/desktop/prod-resources/icon.png - - find "$out"/libexec/t3code -xtype l -delete - - makeWrapper ${lib.getExe nodejs} "$out"/bin/t3code \ - --add-flags "$out"/libexec/t3code/apps/server/dist/index.mjs - - makeWrapper ${lib.getExe electron} "$out"/bin/t3code-desktop \ - --add-flags "$out"/libexec/t3code/apps/desktop/dist-electron/main.js \ - --inherit-argv0 - - mkdir -p \ - "$out"/share/icons/hicolor/1024x1024/apps \ - "$out"/share/icons/hicolor/scalable/apps - install -m444 assets/prod/black-universal-1024.png \ - "$out"/share/icons/hicolor/1024x1024/apps/t3code.png - install -m444 assets/prod/logo.svg \ - "$out"/share/icons/hicolor/scalable/apps/t3code.svg - - runHook postInstall - ''; - - postInstall = lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) '' - installShellCompletion --cmd t3code \ - --bash <("$out"/bin/t3code --completions bash) \ - --fish <("$out"/bin/t3code --completions fish) \ - --zsh <("$out"/bin/t3code --completions zsh) - ''; - - desktopItems = [ - (makeDesktopItem { - name = "t3code"; - desktopName = "T3 Code"; - comment = finalAttrs.meta.description; - exec = "t3code-desktop %U"; - terminal = false; - icon = "t3code"; - startupWMClass = "T3 Code"; - categories = ["Development"]; - }) - ]; - - passthru = { - inherit nodeModules; - updateScript = nix-update-script { - extraArgs = [ - "--subpackage" - "nodeModules" - ]; - }; - }; - - meta = { - description = "Minimal web GUI for coding agents"; - homepage = "https://t3.codes"; - inherit (nodejs.meta) platforms; - license = lib.licenses.mit; - maintainers = with lib.maintainers; [ - imalison - qweered - ]; - mainProgram = "t3code"; - }; - } -) diff --git a/nixos/packages/t3code/normalize-bun-binaries.ts b/nixos/packages/t3code/normalize-bun-binaries.ts deleted file mode 100644 index 231b673d..00000000 --- a/nixos/packages/t3code/normalize-bun-binaries.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { lstat, mkdir, readdir, rm, symlink } from "fs/promises"; -import { join, relative } from "path"; - -type PackageManifest = { - name?: string; - bin?: string | Record; -}; - -const bunRoot = join(process.cwd(), "node_modules/.bun"); -const bunEntries = (await readdir(bunRoot)).sort(); - -for (const entry of bunEntries) { - const modulesRoot = join(bunRoot, entry, "node_modules"); - if (!(await exists(modulesRoot))) { - continue; - } - - const binRoot = join(modulesRoot, ".bin"); - await rm(binRoot, { recursive: true, force: true }); - await mkdir(binRoot, { recursive: true }); - - const packageDirs = await collectPackages(modulesRoot); - for (const packageDir of packageDirs) { - const manifest = await readManifest(packageDir); - if (!manifest?.bin) { - continue; - } - - const seen = new Set(); - if (typeof manifest.bin == "string") { - const fallback = manifest.name ?? packageDir.split("/").pop(); - if (fallback) { - await linkBinary(binRoot, fallback, packageDir, manifest.bin, seen); - } - continue; - } - - const entries = Object.entries(manifest.bin).sort((a, b) => a[0].localeCompare(b[0])); - for (const [name, target] of entries) { - await linkBinary(binRoot, name, packageDir, target, seen); - } - } -} - -async function collectPackages(modulesRoot: string) { - const found: string[] = []; - const topLevel = (await readdir(modulesRoot)).sort(); - - for (const name of topLevel) { - if (name == ".bin" || name == ".bun") { - continue; - } - - const full = join(modulesRoot, name); - if (!(await isDirectory(full))) { - continue; - } - - if (name.startsWith("@")) { - const scoped = (await readdir(full)).sort(); - for (const child of scoped) { - const scopedDir = join(full, child); - if (await isDirectory(scopedDir)) { - found.push(scopedDir); - } - } - continue; - } - - found.push(full); - } - - return found.sort(); -} - -async function readManifest(dir: string) { - const file = Bun.file(join(dir, "package.json")); - if (!(await file.exists())) { - return null; - } - - return (await file.json()) as PackageManifest; -} - -async function linkBinary( - binRoot: string, - name: string, - packageDir: string, - target: string, - seen: Set, -) { - if (!name || !target) { - return; - } - - const normalizedName = normalizeBinName(name); - if (seen.has(normalizedName)) { - return; - } - - const resolved = join(packageDir, target); - const script = Bun.file(resolved); - if (!(await script.exists())) { - return; - } - - seen.add(normalizedName); - const destination = join(binRoot, normalizedName); - const relativeTarget = relative(binRoot, resolved); - await rm(destination, { force: true }); - await symlink(relativeTarget.length == 0 ? "." : relativeTarget, destination); -} - -async function exists(path: string) { - try { - await lstat(path); - return true; - } catch { - return false; - } -} - -async function isDirectory(path: string) { - try { - const info = await lstat(path); - return info.isDirectory(); - } catch { - return false; - } -} - -function normalizeBinName(name: string) { - const slash = name.lastIndexOf("/"); - return slash >= 0 ? name.slice(slash + 1) : name; -}