// @effect-diagnostics nodeBuiltinImport:off - Tests use Node's glob matcher to verify electron-builder exclusions.import * as NodeCrypto from "node:crypto";import * as NodePath from "node:path"; import * as NodeServices from "@effect/platform-node/NodeServices";import { assert, it } from "@effect/vitest";import * as ConfigProvider from "effect/ConfigProvider";import * as FileSystem from "effect/FileSystem";import * as Effect from "effect/Effect";import * as Layer from "effect/Layer";import * as Option from "effect/Option";import * as Path from "effect/Path";import * as Sink from "effect/Sink";import * as Stream from "effect/Stream";import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; import { BundleNotSelfContainedError, BuildCommandFailedError, buildWslRuntimeArchiveArgs, parseWslRuntimeArchiveMembers, DesktopDmgBackgroundSourceMissingError, createStageWorkspaceConfig, createStagePatchedDependencies, createBuildConfig, DESKTOP_ELECTRON_LANGUAGES, DESKTOP_FILE_EXCLUSIONS, DESKTOP_EXTRA_RESOURCES, LINUX_CAPTURE_EXTRA_RESOURCES, LINUX_BROWSER_SECRET_EXTRA_RESOURCES, MAC_FILE_EXCLUSIONS, InvalidMacPasskeyRpDomainError, InvalidMacPasskeyPublishableKeyError, InvalidMockUpdateServerPortError, UnsupportedDesktopBuildArchitectureError, isMacPasskeySigningConfigurationError, LinuxIconResizeError, LinuxDesktopBuildPrerequisitesMissingError, MacDesktopBuildPrerequisitesMissingError, MacPasskeySigningConfigurationResolutionError, MissingMacPasskeyProvisioningProfileError, packWindowsServerAsar, preflightLinuxDesktopBuild, preflightMacDesktopBuild, preflightWindowsDesktopBuild, renderMacPasskeyEntitlements, resolveClerkPasskeyNativeArtifacts, resolveMacPasskeySigningConfiguration, resolveDesktopRuntimeDependencies, resolveMacStageDependencies, resolveFffNativeDependencies, resolveBuildOptions, resolveDesktopBuildIconAssets, resolveDesktopProductName, resolveDesktopUpdateChannel, resolveDesktopWebAssetBrand, resolveResourceMonitorRustTargets, resolveWindowsServerAsarIgnoreGlobs, resourceMonitorExecutableName, resolveGitHubPublishConfig, resolveMockUpdateServerPort, resolveMockUpdateServerUrl, resolvePackageManagerUserAgent, stageLinuxIconSize, stageDesktopDmgBackground, stageResourceMonitor, stageLinuxCaptureHelper, stageWslRuntimeArchive, bundlesWslRuntime, STAGE_INSTALL_ARGS, ancestorNodeModulesPaths, copyDirectoryPreservingSymlinks, LinuxBrowserSecretHostError, stageBrowserSecret, validateWindowsPackagedPayload, WindowsPrimaryNativeProbeError, WindowsDesktopBuildPrerequisitesMissingError, WindowsPackagedPayloadValidationError, WINDOWS_NATIVE_ASAR_UNPACK_GLOB, WINDOWS_PACKAGED_PAYLOAD_FILE_LIMIT, WINDOWS_SERVER_ASAR_IGNORE_GLOBS, WINDOWS_SERVER_EXTRA_RESOURCES, WINDOWS_SERVER_ASAR_RESOURCE, WINDOWS_SERVER_RESOURCE_SOURCE_DIR, WSL_RUNTIME_ARCHIVE_EXTRA_RESOURCE, WSL_RUNTIME_ARCHIVE_HASH_EXTRA_RESOURCE, WSL_RUNTIME_ARCHIVE_HASH_NAME, WSL_RUNTIME_ARCHIVE_NAME, WSL_RUNTIME_EXTRA_RESOURCES, wslRuntimeArchiveTarTarget,} from "./build-desktop-artifact.ts";import { BRAND_ASSET_PATHS } from "./lib/brand-assets.ts";import { HostProcessArchitecture, HostProcessPlatform } from "@t3tools/shared/hostProcess";import { symlinksSupported } from "@t3tools/shared/testing/symlinks"; // A minimal stand-in for the staged sidecar roots packed into the WSL archive.const stageWslRuntimeTreeFixture = Effect.fn("stageWslRuntimeTreeFixture")(function* ( root: string, serverSource: string,) { const fs = yield* FileSystem.FileSystem; const path = yield* Path.Path; yield* fs.makeDirectory(path.join(root, "apps/server/dist"), { recursive: true }); yield* fs.writeFileString(path.join(root, "apps/server/dist/bin.mjs"), serverSource); yield* fs.makeDirectory(path.join(root, "node_modules/node-pty/prebuilds/linux-x64"), { recursive: true, }); yield* fs.writeFileString( path.join(root, "node_modules/node-pty/package.json"), '{"name":"node-pty"}\n', ); yield* fs.writeFileString( path.join(root, "node_modules/node-pty/prebuilds/linux-x64/pty.node"), "pty", );}); function mockProcess(exitCode: number, stdout = "") { const encodedStdout = new TextEncoder().encode(stdout); return ChildProcessSpawner.makeHandle({ pid: ChildProcessSpawner.ProcessId(1), exitCode: Effect.succeed(ChildProcessSpawner.ExitCode(exitCode)), isRunning: Effect.succeed(false), kill: () => Effect.void, unref: Effect.succeed(Effect.void), stdin: Sink.drain, stdout: stdout ? Stream.make(encodedStdout) : Stream.empty, stderr: Stream.empty, all: Stream.empty, getInputFd: () => Sink.drain, getOutputFd: () => Stream.empty, });} function iconResizeSpawnerLayer( commands: Array<{ readonly command: string; readonly args: ReadonlyArray<string> }>, exitCodes: ReadonlyArray<number>,) { let commandIndex = 0; return Layer.succeed( ChildProcessSpawner.ChildProcessSpawner, ChildProcessSpawner.make((command) => { const childProcess = command as unknown as { readonly command: string; readonly args: ReadonlyArray<string>; }; commands.push({ command: childProcess.command, args: childProcess.args, }); return Effect.succeed(mockProcess(exitCodes[commandIndex++] ?? 0)); }), );} const makeWindowsPayloadFixture = Effect.fn("test.makeWindowsPayloadFixture")(function* (input: { readonly copyUnpackedNatives: boolean; readonly serverEntrySource?: string; readonly wslRuntime?: "valid" | "forbidden" | "bad-digest";}) { const fs = yield* FileSystem.FileSystem; const path = yield* Path.Path; const tempDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-windows-payload-test-", }); const sourceDir = path.join(tempDir, "server-source"); const serverEntryPath = path.join(sourceDir, "apps/server/dist/bin.mjs"); const nativePath = path.join(sourceDir, "node_modules/native/addon.node"); yield* fs.makeDirectory(path.dirname(serverEntryPath), { recursive: true }); yield* fs.makeDirectory(path.dirname(nativePath), { recursive: true }); yield* fs.writeFileString(serverEntryPath, input.serverEntrySource ?? "console.log('server');\n"); yield* fs.writeFileString(nativePath, "native-binary"); const generatedAsarPath = path.join(tempDir, WINDOWS_SERVER_ASAR_RESOURCE); yield* packWindowsServerAsar({ sourceDir, asarPath: generatedAsarPath, arch: "x64" }); const stageDistDir = path.join(tempDir, "dist"); const packagedAppDir = path.join(stageDistDir, "win-unpacked"); const resourcesDir = path.join(packagedAppDir, "resources"); yield* fs.makeDirectory(path.join(resourcesDir, "resource-monitor"), { recursive: true }); yield* fs.copyFile(generatedAsarPath, path.join(resourcesDir, WINDOWS_SERVER_ASAR_RESOURCE)); if (input.copyUnpackedNatives) { yield* fs.copy( `${generatedAsarPath}.unpacked`, path.join(resourcesDir, `${WINDOWS_SERVER_ASAR_RESOURCE}.unpacked`), ); } yield* fs.writeFileString( path.join(resourcesDir, "resource-monitor/t3-resource-monitor.exe"), "monitor", ); const appExecutableName = "t3code.exe"; yield* fs.writeFileString(path.join(packagedAppDir, appExecutableName), "electron"); yield* fs.writeFileString(path.join(packagedAppDir, "chrome_crashpad_handler.exe"), "crashpad"); if (input.wslRuntime !== undefined) { const wslSourceDir = path.join(tempDir, "wsl-source"); const linuxPrebuildDir = path.join(wslSourceDir, "node_modules/node-pty/prebuilds/linux-x64"); yield* fs.makeDirectory(path.join(wslSourceDir, "apps/server/dist"), { recursive: true }); yield* fs.makeDirectory(linuxPrebuildDir, { recursive: true }); yield* fs.writeFileString( path.join(wslSourceDir, "apps/server/dist/bin.mjs"), "console.log('wsl server');\n", ); yield* fs.writeFileString( path.join(wslSourceDir, "node_modules/node-pty/package.json"), '{"name":"node-pty"}', ); yield* fs.writeFileString(path.join(linuxPrebuildDir, "pty.node"), "linux-pty"); yield* fs.writeFileString( path.join(linuxPrebuildDir, "t3code-wsl-node-pty.json"), '{"arch":"x64"}', ); if (input.wslRuntime === "forbidden") { const windowsPrebuildDir = path.join( wslSourceDir, "node_modules/node-pty/prebuilds/win32-x64", ); yield* fs.makeDirectory(windowsPrebuildDir, { recursive: true }); yield* fs.writeFileString(path.join(windowsPrebuildDir, "pty.node"), "windows-pty"); } const archivePath = path.join(resourcesDir, WSL_RUNTIME_ARCHIVE_NAME); const hashPath = path.join(resourcesDir, WSL_RUNTIME_ARCHIVE_HASH_NAME); const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; const tar = yield* spawner.spawn( ChildProcess.make( "tar", [ "-czf", wslRuntimeArchiveTarTarget(path.relative(wslSourceDir, archivePath)), "apps/server/dist", "node_modules", ], { cwd: wslSourceDir, stdin: "ignore", stdout: "ignore", stderr: "pipe" }, ), ); assert.equal(Number(yield* tar.exitCode), 0); const archiveDigest = NodeCrypto.createHash("sha256"); yield* fs .stream(archivePath) .pipe(Stream.runForEach((chunk) => Effect.sync(() => archiveDigest.update(chunk)))); yield* fs.writeFileString( hashPath, input.wslRuntime === "bad-digest" ? `${"0".repeat(64)}\n` : `${archiveDigest.digest("hex")}\n`, ); } return { stageDistDir, packagedAppDir, sourceDir, generatedAsarPath, appExecutableName, } as const;}); it.layer(NodeServices.layer)("build-desktop-artifact", (it) => { it("resolves the dedicated nightly updater channel from nightly versions", () => { assert.equal(resolveDesktopUpdateChannel("0.0.17-nightly.20260413.42"), "nightly"); assert.equal(resolveDesktopUpdateChannel("0.0.17"), "latest"); }); it("switches desktop packaging product names to nightly for nightly builds", () => { assert.equal(resolveDesktopProductName("0.0.17"), "T3 Code (Alpha)"); assert.equal(resolveDesktopProductName("0.0.17-nightly.20260413.42"), "T3 Code (Nightly)"); }); it("switches desktop packaging icons to the nightly artwork for nightly versions", () => { assert.deepStrictEqual(resolveDesktopBuildIconAssets("0.0.17"), { macIconPng: BRAND_ASSET_PATHS.productionMacIconPng, linuxIconPng: BRAND_ASSET_PATHS.productionLinuxIconPng, windowsIconIco: BRAND_ASSET_PATHS.productionWindowsIconIco, }); assert.deepStrictEqual(resolveDesktopBuildIconAssets("0.0.17-nightly.20260413.42"), { macIconPng: BRAND_ASSET_PATHS.nightlyMacIconPng, linuxIconPng: BRAND_ASSET_PATHS.nightlyLinuxIconPng, windowsIconIco: BRAND_ASSET_PATHS.nightlyWindowsIconIco, }); }); it("switches the bundled splash and favicon branding for nightly versions", () => { assert.equal(resolveDesktopWebAssetBrand("0.0.17"), "production"); assert.equal(resolveDesktopWebAssetBrand("0.0.17-nightly.20260413.42"), "nightly"); }); it.effect("resolves GitHub desktop publish config from Effect config", () => Effect.gen(function* () { const latestConfig = yield* resolveGitHubPublishConfig("latest").pipe( Effect.provide( ConfigProvider.layer( ConfigProvider.fromEnv({ env: { T3CODE_DESKTOP_UPDATE_REPOSITORY: "pingdotgg/t3code", }, }), ), ), ); const nightlyConfig = yield* resolveGitHubPublishConfig("nightly").pipe( Effect.provide( ConfigProvider.layer( ConfigProvider.fromEnv({ env: { GITHUB_REPOSITORY: "pingdotgg/t3code", }, }), ), ), ); assert.deepStrictEqual(latestConfig, { provider: "github", owner: "pingdotgg", repo: "t3code", releaseType: "release", }); assert.deepStrictEqual(nightlyConfig, { provider: "github", owner: "pingdotgg", repo: "t3code", releaseType: "prerelease", channel: "nightly", }); }), ); it.effect("omits update feeds for pull request preview builds", () => Effect.gen(function* () { const preview = yield* createBuildConfig( "mac", "dmg", "0.0.33-pr.8182.1", false, false, undefined, undefined, ); const release = yield* createBuildConfig( "mac", "dmg", "0.0.33", false, false, undefined, undefined, ); assert.notProperty(preview, "publish"); assert.deepStrictEqual(release.publish, [ { provider: "github", owner: "pingdotgg", repo: "t3code", releaseType: "release", }, ]); }).pipe( Effect.provide( ConfigProvider.layer( ConfigProvider.fromEnv({ env: { GITHUB_REPOSITORY: "pingdotgg/t3code" } }), ), ), ), ); it("omits bundled workspace packages from staged desktop dependencies", () => { assert.deepStrictEqual( resolveDesktopRuntimeDependencies( { "@effect/platform-node": "catalog:", "@t3tools/contracts": "workspace:*", "@t3tools/shared": "workspace:*", "@t3tools/ssh": "workspace:*", "@t3tools/tailscale": "workspace:*", effect: "catalog:", electron: "41.5.0", }, { "@effect/platform-node": "4.0.0-beta.59", effect: "4.0.0-beta.59", }, ), { "@effect/platform-node": "4.0.0-beta.59", effect: "4.0.0-beta.59", }, ); }); it("carries only staged dependency patch metadata into staged desktop installs", () => { assert.deepStrictEqual( createStagePatchedDependencies( { "@expo/metro-config@56.0.13": "patches/@expo%2Fmetro-config@56.0.13.patch", "@ff-labs/fff-node@0.9.4": "patches/@ff-labs__fff-node@0.9.4.patch", "@pierre/diffs@1.1.20": "patches/@pierre%2Fdiffs@1.1.20.patch", "alchemy@2.0.0-beta.49": "patches/alchemy@2.0.0-beta.49.patch", "effect@4.0.0-beta.73": "patches/effect@4.0.0-beta.73.patch", }, { "@ff-labs/fff-node": "0.9.4", "@pierre/diffs": "1.1.20", effect: "4.0.0-beta.73", }, ), { "@ff-labs/fff-node@0.9.4": "patches/@ff-labs__fff-node@0.9.4.patch", "@pierre/diffs@1.1.20": "patches/@pierre%2Fdiffs@1.1.20.patch", "effect@4.0.0-beta.73": "patches/effect@4.0.0-beta.73.patch", }, ); assert.deepStrictEqual( createStagePatchedDependencies( { "@expo/metro-config@56.0.13": "patches/@expo%2Fmetro-config@56.0.13.patch", }, { effect: "4.0.0-beta.73" }, ), {}, ); }); it("installs optional native dependencies for the target desktop architecture", () => { assert.deepStrictEqual(STAGE_INSTALL_ARGS, ["install", "--prod"]); assert.deepStrictEqual(createStageWorkspaceConfig({ platform: "mac", arch: "x64" }), { supportedArchitectures: { os: ["darwin"], cpu: ["x64"], }, }); assert.deepStrictEqual(createStageWorkspaceConfig({ platform: "linux", arch: "x64" }), { supportedArchitectures: { os: ["linux"], cpu: ["x64"], libc: ["glibc"], }, }); // The Windows app stage only serves the desktop main process; the server // sidecar stage is the one that needs Linux natives (below). assert.deepStrictEqual(createStageWorkspaceConfig({ platform: "win", arch: "x64" }), { supportedArchitectures: { os: ["win32"], cpu: ["x64"], }, }); // The server sidecar stage bundles the same-architecture WSL (Linux, // glibc) backend, so its install must fetch Linux native optional deps // (e.g. ffi-rs) too — and must be hoisted so the tree survives asar // packing and runtime extraction without symlinks. assert.deepStrictEqual( createStageWorkspaceConfig({ platform: "win", arch: "x64", linuxServerBackend: true }), { supportedArchitectures: { os: ["win32", "linux"], cpu: ["x64"], libc: ["glibc"], }, nodeLinker: "hoisted", }, ); assert.deepStrictEqual( createStageWorkspaceConfig({ platform: "win", arch: "arm64", linuxServerBackend: true }), { supportedArchitectures: { os: ["win32", "linux"], cpu: ["arm64"], libc: ["glibc"], }, nodeLinker: "hoisted", }, ); assert.deepStrictEqual(createStageWorkspaceConfig({ platform: "mac", arch: "universal" }), { supportedArchitectures: { os: ["darwin"], cpu: ["arm64", "x64"], }, }); }); it("stages pnpm 11 allowBuilds and patchedDependencies in the workspace yaml", () => { assert.deepStrictEqual( createStageWorkspaceConfig({ platform: "linux", arch: "x64", allowBuilds: { electron: true, "node-pty": true, "browser-tabs-lock": false, }, patchedDependencies: { "effect@4.0.0-beta.73": "patches/effect@4.0.0-beta.73.patch", }, overrides: { effect: "4.0.0-beta.73", },Lines 1–500 of 2353. Load more
// @effect-diagnostics nodeBuiltinImport:off - Tests use Node's glob matcher to verify electron-builder exclusions. import * as NodeCrypto from "node:crypto"; import * as NodePath from "node:path"; import * as NodeServices from "@effect/platform-node/NodeServices"; import { assert, it } from "@effect/vitest"; import * as ConfigProvider from "effect/ConfigProvider"; import * as FileSystem from "effect/FileSystem"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; import * as Option from "effect/Option"; import * as Path from "effect/Path"; import * as Sink from "effect/Sink"; import * as Stream from "effect/Stream"; import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; import { BundleNotSelfContainedError, BuildCommandFailedError, buildWslRuntimeArchiveArgs, parseWslRuntimeArchiveMembers, DesktopDmgBackgroundSourceMissingError, createStageWorkspaceConfig, createStagePatchedDependencies, createBuildConfig, DESKTOP_ELECTRON_LANGUAGES, DESKTOP_FILE_EXCLUSIONS, DESKTOP_EXTRA_RESOURCES, LINUX_CAPTURE_EXTRA_RESOURCES, LINUX_BROWSER_SECRET_EXTRA_RESOURCES, MAC_FILE_EXCLUSIONS, InvalidMacPasskeyRpDomainError, InvalidMacPasskeyPublishableKeyError, InvalidMockUpdateServerPortError, UnsupportedDesktopBuildArchitectureError, isMacPasskeySigningConfigurationError, LinuxIconResizeError, LinuxDesktopBuildPrerequisitesMissingError, MacDesktopBuildPrerequisitesMissingError, MacPasskeySigningConfigurationResolutionError, MissingMacPasskeyProvisioningProfileError, packWindowsServerAsar, preflightLinuxDesktopBuild, preflightMacDesktopBuild, preflightWindowsDesktopBuild, renderMacPasskeyEntitlements, resolveClerkPasskeyNativeArtifacts, resolveMacPasskeySigningConfiguration, resolveDesktopRuntimeDependencies, resolveMacStageDependencies, resolveFffNativeDependencies, resolveBuildOptions, resolveDesktopBuildIconAssets, resolveDesktopProductName, resolveDesktopUpdateChannel, resolveDesktopWebAssetBrand, resolveResourceMonitorRustTargets, resolveWindowsServerAsarIgnoreGlobs, resourceMonitorExecutableName, resolveGitHubPublishConfig, resolveMockUpdateServerPort, resolveMockUpdateServerUrl, resolvePackageManagerUserAgent, stageLinuxIconSize, stageDesktopDmgBackground, stageResourceMonitor, stageLinuxCaptureHelper, stageWslRuntimeArchive, bundlesWslRuntime, STAGE_INSTALL_ARGS, ancestorNodeModulesPaths, copyDirectoryPreservingSymlinks, LinuxBrowserSecretHostError, stageBrowserSecret, validateWindowsPackagedPayload, WindowsPrimaryNativeProbeError, WindowsDesktopBuildPrerequisitesMissingError, WindowsPackagedPayloadValidationError, WINDOWS_NATIVE_ASAR_UNPACK_GLOB, WINDOWS_PACKAGED_PAYLOAD_FILE_LIMIT, WINDOWS_SERVER_ASAR_IGNORE_GLOBS, WINDOWS_SERVER_EXTRA_RESOURCES, WINDOWS_SERVER_ASAR_RESOURCE, WINDOWS_SERVER_RESOURCE_SOURCE_DIR, WSL_RUNTIME_ARCHIVE_EXTRA_RESOURCE, WSL_RUNTIME_ARCHIVE_HASH_EXTRA_RESOURCE, WSL_RUNTIME_ARCHIVE_HASH_NAME, WSL_RUNTIME_ARCHIVE_NAME, WSL_RUNTIME_EXTRA_RESOURCES, wslRuntimeArchiveTarTarget, } from "./build-desktop-artifact.ts"; import { BRAND_ASSET_PATHS } from "./lib/brand-assets.ts"; import { HostProcessArchitecture, HostProcessPlatform } from "@t3tools/shared/hostProcess"; import { symlinksSupported } from "@t3tools/shared/testing/symlinks"; // A minimal stand-in for the staged sidecar roots packed into the WSL archive. const stageWslRuntimeTreeFixture = Effect.fn("stageWslRuntimeTreeFixture")(function* ( root: string, serverSource: string, ) { const fs = yield* FileSystem.FileSystem; const path = yield* Path.Path; yield* fs.makeDirectory(path.join(root, "apps/server/dist"), { recursive: true }); yield* fs.writeFileString(path.join(root, "apps/server/dist/bin.mjs"), serverSource); yield* fs.makeDirectory(path.join(root, "node_modules/node-pty/prebuilds/linux-x64"), { recursive: true, }); yield* fs.writeFileString( path.join(root, "node_modules/node-pty/package.json"), '{"name":"node-pty"}\n', ); yield* fs.writeFileString( path.join(root, "node_modules/node-pty/prebuilds/linux-x64/pty.node"), "pty", ); }); function mockProcess(exitCode: number, stdout = "") { const encodedStdout = new TextEncoder().encode(stdout); return ChildProcessSpawner.makeHandle({ pid: ChildProcessSpawner.ProcessId(1), exitCode: Effect.succeed(ChildProcessSpawner.ExitCode(exitCode)), isRunning: Effect.succeed(false), kill: () => Effect.void, unref: Effect.succeed(Effect.void), stdin: Sink.drain, stdout: stdout ? Stream.make(encodedStdout) : Stream.empty, stderr: Stream.empty, all: Stream.empty, getInputFd: () => Sink.drain, getOutputFd: () => Stream.empty, }); } function iconResizeSpawnerLayer( commands: Array<{ readonly command: string; readonly args: ReadonlyArray<string> }>, exitCodes: ReadonlyArray<number>, ) { let commandIndex = 0; return Layer.succeed( ChildProcessSpawner.ChildProcessSpawner, ChildProcessSpawner.make((command) => { const childProcess = command as unknown as { readonly command: string; readonly args: ReadonlyArray<string>; }; commands.push({ command: childProcess.command, args: childProcess.args, }); return Effect.succeed(mockProcess(exitCodes[commandIndex++] ?? 0)); }), ); } const makeWindowsPayloadFixture = Effect.fn("test.makeWindowsPayloadFixture")(function* (input: { readonly copyUnpackedNatives: boolean; readonly serverEntrySource?: string; readonly wslRuntime?: "valid" | "forbidden" | "bad-digest"; }) { const fs = yield* FileSystem.FileSystem; const path = yield* Path.Path; const tempDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-windows-payload-test-", }); const sourceDir = path.join(tempDir, "server-source"); const serverEntryPath = path.join(sourceDir, "apps/server/dist/bin.mjs"); const nativePath = path.join(sourceDir, "node_modules/native/addon.node"); yield* fs.makeDirectory(path.dirname(serverEntryPath), { recursive: true }); yield* fs.makeDirectory(path.dirname(nativePath), { recursive: true }); yield* fs.writeFileString(serverEntryPath, input.serverEntrySource ?? "console.log('server');\n"); yield* fs.writeFileString(nativePath, "native-binary"); const generatedAsarPath = path.join(tempDir, WINDOWS_SERVER_ASAR_RESOURCE); yield* packWindowsServerAsar({ sourceDir, asarPath: generatedAsarPath, arch: "x64" }); const stageDistDir = path.join(tempDir, "dist"); const packagedAppDir = path.join(stageDistDir, "win-unpacked"); const resourcesDir = path.join(packagedAppDir, "resources"); yield* fs.makeDirectory(path.join(resourcesDir, "resource-monitor"), { recursive: true }); yield* fs.copyFile(generatedAsarPath, path.join(resourcesDir, WINDOWS_SERVER_ASAR_RESOURCE)); if (input.copyUnpackedNatives) { yield* fs.copy( `${generatedAsarPath}.unpacked`, path.join(resourcesDir, `${WINDOWS_SERVER_ASAR_RESOURCE}.unpacked`), ); } yield* fs.writeFileString( path.join(resourcesDir, "resource-monitor/t3-resource-monitor.exe"), "monitor", ); const appExecutableName = "t3code.exe"; yield* fs.writeFileString(path.join(packagedAppDir, appExecutableName), "electron"); yield* fs.writeFileString(path.join(packagedAppDir, "chrome_crashpad_handler.exe"), "crashpad"); if (input.wslRuntime !== undefined) { const wslSourceDir = path.join(tempDir, "wsl-source"); const linuxPrebuildDir = path.join(wslSourceDir, "node_modules/node-pty/prebuilds/linux-x64"); yield* fs.makeDirectory(path.join(wslSourceDir, "apps/server/dist"), { recursive: true }); yield* fs.makeDirectory(linuxPrebuildDir, { recursive: true }); yield* fs.writeFileString( path.join(wslSourceDir, "apps/server/dist/bin.mjs"), "console.log('wsl server');\n", ); yield* fs.writeFileString( path.join(wslSourceDir, "node_modules/node-pty/package.json"), '{"name":"node-pty"}', ); yield* fs.writeFileString(path.join(linuxPrebuildDir, "pty.node"), "linux-pty"); yield* fs.writeFileString( path.join(linuxPrebuildDir, "t3code-wsl-node-pty.json"), '{"arch":"x64"}', ); if (input.wslRuntime === "forbidden") { const windowsPrebuildDir = path.join( wslSourceDir, "node_modules/node-pty/prebuilds/win32-x64", ); yield* fs.makeDirectory(windowsPrebuildDir, { recursive: true }); yield* fs.writeFileString(path.join(windowsPrebuildDir, "pty.node"), "windows-pty"); } const archivePath = path.join(resourcesDir, WSL_RUNTIME_ARCHIVE_NAME); const hashPath = path.join(resourcesDir, WSL_RUNTIME_ARCHIVE_HASH_NAME); const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; const tar = yield* spawner.spawn( ChildProcess.make( "tar", [ "-czf", wslRuntimeArchiveTarTarget(path.relative(wslSourceDir, archivePath)), "apps/server/dist", "node_modules", ], { cwd: wslSourceDir, stdin: "ignore", stdout: "ignore", stderr: "pipe" }, ), ); assert.equal(Number(yield* tar.exitCode), 0); const archiveDigest = NodeCrypto.createHash("sha256"); yield* fs .stream(archivePath) .pipe(Stream.runForEach((chunk) => Effect.sync(() => archiveDigest.update(chunk)))); yield* fs.writeFileString( hashPath, input.wslRuntime === "bad-digest" ? `${"0".repeat(64)}\n` : `${archiveDigest.digest("hex")}\n`, ); } return { stageDistDir, packagedAppDir, sourceDir, generatedAsarPath, appExecutableName, } as const; }); it.layer(NodeServices.layer)("build-desktop-artifact", (it) => { it("resolves the dedicated nightly updater channel from nightly versions", () => { assert.equal(resolveDesktopUpdateChannel("0.0.17-nightly.20260413.42"), "nightly"); assert.equal(resolveDesktopUpdateChannel("0.0.17"), "latest"); }); it("switches desktop packaging product names to nightly for nightly builds", () => { assert.equal(resolveDesktopProductName("0.0.17"), "T3 Code (Alpha)"); assert.equal(resolveDesktopProductName("0.0.17-nightly.20260413.42"), "T3 Code (Nightly)"); }); it("switches desktop packaging icons to the nightly artwork for nightly versions", () => { assert.deepStrictEqual(resolveDesktopBuildIconAssets("0.0.17"), { macIconPng: BRAND_ASSET_PATHS.productionMacIconPng, linuxIconPng: BRAND_ASSET_PATHS.productionLinuxIconPng, windowsIconIco: BRAND_ASSET_PATHS.productionWindowsIconIco, }); assert.deepStrictEqual(resolveDesktopBuildIconAssets("0.0.17-nightly.20260413.42"), { macIconPng: BRAND_ASSET_PATHS.nightlyMacIconPng, linuxIconPng: BRAND_ASSET_PATHS.nightlyLinuxIconPng, windowsIconIco: BRAND_ASSET_PATHS.nightlyWindowsIconIco, }); }); it("switches the bundled splash and favicon branding for nightly versions", () => { assert.equal(resolveDesktopWebAssetBrand("0.0.17"), "production"); assert.equal(resolveDesktopWebAssetBrand("0.0.17-nightly.20260413.42"), "nightly"); }); it.effect("resolves GitHub desktop publish config from Effect config", () => Effect.gen(function* () { const latestConfig = yield* resolveGitHubPublishConfig("latest").pipe( Effect.provide( ConfigProvider.layer( ConfigProvider.fromEnv({ env: { T3CODE_DESKTOP_UPDATE_REPOSITORY: "pingdotgg/t3code", }, }), ), ), ); const nightlyConfig = yield* resolveGitHubPublishConfig("nightly").pipe( Effect.provide( ConfigProvider.layer( ConfigProvider.fromEnv({ env: { GITHUB_REPOSITORY: "pingdotgg/t3code", }, }), ), ), ); assert.deepStrictEqual(latestConfig, { provider: "github", owner: "pingdotgg", repo: "t3code", releaseType: "release", }); assert.deepStrictEqual(nightlyConfig, { provider: "github", owner: "pingdotgg", repo: "t3code", releaseType: "prerelease", channel: "nightly", }); }), ); it.effect("omits update feeds for pull request preview builds", () => Effect.gen(function* () { const preview = yield* createBuildConfig( "mac", "dmg", "0.0.33-pr.8182.1", false, false, undefined, undefined, ); const release = yield* createBuildConfig( "mac", "dmg", "0.0.33", false, false, undefined, undefined, ); assert.notProperty(preview, "publish"); assert.deepStrictEqual(release.publish, [ { provider: "github", owner: "pingdotgg", repo: "t3code", releaseType: "release", }, ]); }).pipe( Effect.provide( ConfigProvider.layer( ConfigProvider.fromEnv({ env: { GITHUB_REPOSITORY: "pingdotgg/t3code" } }), ), ), ), ); it("omits bundled workspace packages from staged desktop dependencies", () => { assert.deepStrictEqual( resolveDesktopRuntimeDependencies( { "@effect/platform-node": "catalog:", "@t3tools/contracts": "workspace:*", "@t3tools/shared": "workspace:*", "@t3tools/ssh": "workspace:*", "@t3tools/tailscale": "workspace:*", effect: "catalog:", electron: "41.5.0", }, { "@effect/platform-node": "4.0.0-beta.59", effect: "4.0.0-beta.59", }, ), { "@effect/platform-node": "4.0.0-beta.59", effect: "4.0.0-beta.59", }, ); }); it("carries only staged dependency patch metadata into staged desktop installs", () => { assert.deepStrictEqual( createStagePatchedDependencies( { "@expo/metro-config@56.0.13": "patches/@expo%2Fmetro-config@56.0.13.patch", "@ff-labs/fff-node@0.9.4": "patches/@ff-labs__fff-node@0.9.4.patch", "@pierre/diffs@1.1.20": "patches/@pierre%2Fdiffs@1.1.20.patch", "alchemy@2.0.0-beta.49": "patches/alchemy@2.0.0-beta.49.patch", "effect@4.0.0-beta.73": "patches/effect@4.0.0-beta.73.patch", }, { "@ff-labs/fff-node": "0.9.4", "@pierre/diffs": "1.1.20", effect: "4.0.0-beta.73", }, ), { "@ff-labs/fff-node@0.9.4": "patches/@ff-labs__fff-node@0.9.4.patch", "@pierre/diffs@1.1.20": "patches/@pierre%2Fdiffs@1.1.20.patch", "effect@4.0.0-beta.73": "patches/effect@4.0.0-beta.73.patch", }, ); assert.deepStrictEqual( createStagePatchedDependencies( { "@expo/metro-config@56.0.13": "patches/@expo%2Fmetro-config@56.0.13.patch", }, { effect: "4.0.0-beta.73" }, ), {}, ); }); it("installs optional native dependencies for the target desktop architecture", () => { assert.deepStrictEqual(STAGE_INSTALL_ARGS, ["install", "--prod"]); assert.deepStrictEqual(createStageWorkspaceConfig({ platform: "mac", arch: "x64" }), { supportedArchitectures: { os: ["darwin"], cpu: ["x64"], }, }); assert.deepStrictEqual(createStageWorkspaceConfig({ platform: "linux", arch: "x64" }), { supportedArchitectures: { os: ["linux"], cpu: ["x64"], libc: ["glibc"], }, }); // The Windows app stage only serves the desktop main process; the server // sidecar stage is the one that needs Linux natives (below). assert.deepStrictEqual(createStageWorkspaceConfig({ platform: "win", arch: "x64" }), { supportedArchitectures: { os: ["win32"], cpu: ["x64"], }, }); // The server sidecar stage bundles the same-architecture WSL (Linux, // glibc) backend, so its install must fetch Linux native optional deps // (e.g. ffi-rs) too — and must be hoisted so the tree survives asar // packing and runtime extraction without symlinks. assert.deepStrictEqual( createStageWorkspaceConfig({ platform: "win", arch: "x64", linuxServerBackend: true }), { supportedArchitectures: { os: ["win32", "linux"], cpu: ["x64"], libc: ["glibc"], }, nodeLinker: "hoisted", }, ); assert.deepStrictEqual( createStageWorkspaceConfig({ platform: "win", arch: "arm64", linuxServerBackend: true }), { supportedArchitectures: { os: ["win32", "linux"], cpu: ["arm64"], libc: ["glibc"], }, nodeLinker: "hoisted", }, ); assert.deepStrictEqual(createStageWorkspaceConfig({ platform: "mac", arch: "universal" }), { supportedArchitectures: { os: ["darwin"], cpu: ["arm64", "x64"], }, }); }); it("stages pnpm 11 allowBuilds and patchedDependencies in the workspace yaml", () => { assert.deepStrictEqual( createStageWorkspaceConfig({ platform: "linux", arch: "x64", allowBuilds: { electron: true, "node-pty": true, "browser-tabs-lock": false, }, patchedDependencies: { "effect@4.0.0-beta.73": "patches/effect@4.0.0-beta.73.patch", }, overrides: { effect: "4.0.0-beta.73", },