From 67ea6000a053af2792c6f0a001ccdfac2f7c1c12 Mon Sep 17 00:00:00 2001 From: Theo Browne Date: Sat, 28 Feb 2026 15:31:20 -0800 Subject: [PATCH] publish alpha --- README.md | 7 ++ apps/server/package.json | 2 +- apps/server/src/codexAppServerManager.ts | 3 +- package.json | 10 ++- scripts/publish-alpha.mjs | 104 +++++++++++++++++++++++ scripts/version-alpha.mjs | 46 ++++++++++ 6 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 scripts/publish-alpha.mjs create mode 100644 scripts/version-alpha.mjs diff --git a/README.md b/README.md index 9c231a3bf9d1..f7e0c3b80b34 100644 --- a/README.md +++ b/README.md @@ -56,11 +56,16 @@ T3CODE_DEV_INSTANCE=feature-xyz bun run dev:desktop bun run build bun run start +# Publish an alpha build without touching npm "latest" +bun run version:alpha +bun run publish:alpha + # Build a shareable macOS .dmg (arm64 by default) bun run dist:desktop:dmg # Or from any project directory after publishing: npx t3 +npx t3@alpha ``` ## Scripts @@ -75,6 +80,8 @@ npx t3 - `bun run build` — Builds contracts, web app, and server through Turbo. - `bun run typecheck` — Strict TypeScript checks for all packages. - `bun run test` — Runs workspace tests. +- `bun run version:alpha` — Sets or increments the `t3` package to an `x.y.z-alpha.n` prerelease. +- `bun run publish:alpha` — Builds `t3` and publishes it with the npm `alpha` dist-tag, leaving `latest` unchanged. - `bun run dist:desktop:dmg` — Builds a shareable macOS `.dmg` into `./release`. - `bun run dist:desktop:dmg:x64` — Builds an Intel macOS `.dmg`. diff --git a/apps/server/package.json b/apps/server/package.json index f37ada2f2e05..149feb2144b8 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -1,6 +1,6 @@ { "name": "t3", - "version": "0.1.0", + "version": "0.1.0-alpha.1", "bin": { "t3": "./dist/index.mjs" }, diff --git a/apps/server/src/codexAppServerManager.ts b/apps/server/src/codexAppServerManager.ts index c2b594504849..fb5659710634 100644 --- a/apps/server/src/codexAppServerManager.ts +++ b/apps/server/src/codexAppServerManager.ts @@ -2,6 +2,7 @@ import { type ChildProcessWithoutNullStreams, spawn } from "node:child_process"; import { randomUUID } from "node:crypto"; import { EventEmitter } from "node:events"; import readline from "node:readline"; +import serverPackage from "../package.json"; import { ApprovalRequestId, @@ -200,7 +201,7 @@ export class CodexAppServerManager extends EventEmitter { + if (typeof spec !== "string" || !spec.startsWith("catalog:")) { + return [dependencyName, spec]; + } + + const catalogKey = spec.slice("catalog:".length).trim(); + const lookupKey = catalogKey.length > 0 ? catalogKey : dependencyName; + const resolvedSpec = catalog[lookupKey]; + if (typeof resolvedSpec !== "string" || resolvedSpec.length === 0) { + throw new Error( + `Unable to resolve '${spec}' for ${dependencySourceLabel} dependency '${dependencyName}'.`, + ); + } + + return [dependencyName, resolvedSpec]; + }), + ); +} + +const publishDir = mkdtempSync(path.join(os.tmpdir(), "t3-alpha-publish-")); +cpSync(path.join(packageDir, "dist"), path.join(publishDir, "dist"), { recursive: true }); +mkdirSync(path.join(publishDir, "bin"), { recursive: true }); +writeFileSync( + path.join(publishDir, "bin", "t3"), + '#!/usr/bin/env node\nimport "../dist/index.mjs";\n', +); +chmodSync(path.join(publishDir, "bin", "t3"), 0o755); + +const publishManifest = { + name: packageJson.name, + version: packageJson.version, + type: packageJson.type, + bin: { + t3: "bin/t3", + }, + main: packageJson.main, + files: ["dist", "bin"], + dependencies: resolveCatalogDependencies( + packageJson.dependencies, + readWorkspaceCatalog(rootPackageJson), + "apps/server", + ), +}; + +writeFileSync(path.join(publishDir, "package.json"), `${JSON.stringify(publishManifest, null, 2)}\n`); + +const publishArgs = ["publish", "--tag", "alpha"]; +if (isDryRun) { + publishArgs.push("--dry-run"); +} + +const publish = spawnSync("npm", publishArgs, { + cwd: publishDir, + stdio: "inherit", +}); + +rmSync(publishDir, { recursive: true, force: true }); +process.exit(publish.status ?? 1); diff --git a/scripts/version-alpha.mjs b/scripts/version-alpha.mjs new file mode 100644 index 000000000000..e11dcf08c1cd --- /dev/null +++ b/scripts/version-alpha.mjs @@ -0,0 +1,46 @@ +import { readFileSync, writeFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; + +const packageJsonPath = fileURLToPath(new URL("../apps/server/package.json", import.meta.url)); +const args = process.argv.slice(2); +const dryRun = args.includes("--dry-run"); +const versionArg = args.find((arg) => arg !== "--dry-run"); + +const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8")); +const currentVersion = packageJson.version; + +const alphaVersionPattern = /^\d+\.\d+\.\d+-alpha\.\d+$/; +const alphaCounterPattern = /^(?\d+\.\d+\.\d+)-alpha\.(?\d+)$/; + +function nextAlphaVersion(version) { + const alphaMatch = version.match(alphaCounterPattern); + if (alphaMatch?.groups) { + const counter = Number.parseInt(alphaMatch.groups.counter, 10); + return `${alphaMatch.groups.base}-alpha.${counter + 1}`; + } + + if (version.includes("-")) { + throw new Error( + `Cannot derive an alpha version from prerelease version "${version}". Pass an explicit version instead.`, + ); + } + + return `${version}-alpha.0`; +} + +const nextVersion = versionArg ?? nextAlphaVersion(currentVersion); + +if (!alphaVersionPattern.test(nextVersion)) { + throw new Error( + `Expected an explicit alpha version like "0.1.0-alpha.0", received "${nextVersion}".`, + ); +} + +if (dryRun) { + console.log(nextVersion); + process.exit(0); +} + +packageJson.version = nextVersion; +writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`); +console.log(`Updated apps/server/package.json to ${nextVersion}`);