From 258132286673a1e343b0cf3adf51beb5b3e32227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Primo=C5=BE=20Ajdi=C5=A1ek?= Date: Thu, 16 Jul 2026 21:12:52 +0000 Subject: [PATCH 1/4] feat(packaging): add deb and rpm desktop targets --- .gitignore | 1 + docs/reference/scripts.md | 43 +++++++++++++++++--------- package.json | 2 ++ scripts/build-desktop-artifact.test.ts | 37 ++++++++++++++++++++++ scripts/build-desktop-artifact.ts | 33 ++++++++++++++++++-- 5 files changed, 99 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index ef6067824f2..79993ae06b8 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ build/ .logs/ release/ release-mock/ +packaging-output/ .t3 .idea/ apps/web/.playwright diff --git a/docs/reference/scripts.md b/docs/reference/scripts.md index d4d2b96869e..6813afacdc6 100644 --- a/docs/reference/scripts.md +++ b/docs/reference/scripts.md @@ -1,20 +1,33 @@ # Scripts -- `bun run dev` — Starts contracts, server, and web in `turbo watch` mode. -- `bun run dev:server` — Starts just the WebSocket server (uses Bun TypeScript execution). -- `bun run dev:web` — Starts just the Vite dev server for the web app. +- `vp run dev` — Starts contracts, server, and web in watch mode. +- `vp run dev:server` — Starts just the WebSocket server. +- `vp run dev:web` — Starts just the Vite dev server for the web app. - Dev commands default `T3CODE_STATE_DIR` to `~/.t3/dev` to keep dev state isolated from desktop/prod state. - Override server CLI-equivalent flags from root dev commands with `--`, for example: - `bun run dev -- --base-dir ~/.t3-2` -- `bun run start` — Runs the production server (serves built web app as static files). -- `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 dist:desktop:artifact -- --platform --target --arch ` — Builds a desktop artifact for a specific platform/target/arch. -- `bun run dist:desktop:dmg` — Builds a shareable macOS `.dmg` into `./release`. -- `bun run dist:desktop:dmg:x64` — Builds an Intel macOS `.dmg`. -- `bun run dist:desktop:linux` — Builds a Linux AppImage into `./release`. -- `bun run dist:desktop:win` — Builds a Windows NSIS installer into `./release`. + `vp run dev -- --base-dir ~/.t3-2` +- `vp run start` — Runs the production server (serves built web app as static files). +- `vp run build` — Builds the workspace applications and packages. +- `vp run typecheck` — Strict TypeScript checks for all packages. +- `vp run test` — Runs workspace tests. +- `vp run dist:desktop:artifact -- --platform --target --arch ` — Builds a desktop artifact for a specific platform/target/arch. +- `vp run dist:desktop:dmg` — Builds a shareable macOS `.dmg` into `./release`. +- `vp run dist:desktop:dmg:x64` — Builds an Intel macOS `.dmg`. +- `vp run dist:desktop:linux` — Builds a Linux AppImage into `./release`. +- `vp run dist:desktop:deb` — Builds a Debian/Ubuntu package into `./packaging-output`. +- `vp run dist:desktop:rpm` — Builds a Fedora/RHEL package into `./packaging-output`. +- `vp run dist:desktop:win` — Builds a Windows NSIS installer into `./release`. + +## Linux `.deb` and `.rpm` packaging + +The package scripts build `x64` by default. Use the existing desktop artifact builder to customize a build: + +```bash +vp run dist:desktop:artifact -- --platform linux --target deb --arch arm64 --build-version 1.2.3 --output-dir out +vp run dist:desktop:artifact -- --platform linux --target rpm --arch arm64 --build-version 1.2.3 --output-dir out +``` + +Pass `--skip-build` to reuse existing desktop, server, and web build outputs. ## Desktop `.dmg` packaging notes @@ -23,7 +36,7 @@ - Desktop production windows load the bundled UI from `t3code://app/index.html` (not a `127.0.0.1` document URL). - Desktop packaging includes `apps/server/dist` (the `t3` backend) and starts it on loopback with an auth token for WebSocket/API traffic. - Your tester can still open it on macOS by right-clicking the app and choosing **Open** on first launch. -- To keep staging files for debugging package contents, run: `bun run dist:desktop:dmg -- --keep-stage` +- To keep staging files for debugging package contents, run: `vp run dist:desktop:dmg -- --keep-stage` - To allow code-signing/notarization when configured in CI/secrets, add: `--signed`. - Signed macOS builds also require `T3CODE_APPLE_TEAM_ID` and `T3CODE_MACOS_PROVISIONING_PROFILE`. The passkey RP domain is derived from @@ -40,6 +53,6 @@ Set `T3CODE_DEV_INSTANCE` to any value to deterministically shift all dev ports - Default ports: server `3773`, web `5733` - Shifted ports: `base + offset` (offset is hashed from `T3CODE_DEV_INSTANCE`) -- Example: `T3CODE_DEV_INSTANCE=branch-a bun run dev:desktop` +- Example: `T3CODE_DEV_INSTANCE=branch-a vp run dev:desktop` If you want full control instead of hashing, set `T3CODE_PORT_OFFSET` to a numeric offset. diff --git a/package.json b/package.json index 5e5365d2c1a..3b49d3e79be 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,8 @@ "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:deb": "node scripts/build-desktop-artifact.ts --platform linux --target deb --arch x64 --output-dir packaging-output", + "dist:desktop:rpm": "node scripts/build-desktop-artifact.ts --platform linux --target rpm --arch x64 --output-dir packaging-output", "dist:desktop:win": "node scripts/build-desktop-artifact.ts --platform win --target nsis", "dist:desktop:win:arm64": "node scripts/build-desktop-artifact.ts --platform win --target nsis --arch arm64", "dist:desktop:win:x64": "node scripts/build-desktop-artifact.ts --platform win --target nsis --arch x64", diff --git a/scripts/build-desktop-artifact.test.ts b/scripts/build-desktop-artifact.test.ts index c79fc4797be..06ced0b740e 100644 --- a/scripts/build-desktop-artifact.test.ts +++ b/scripts/build-desktop-artifact.test.ts @@ -492,6 +492,43 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => { }).pipe(Effect.provide(ConfigProvider.layer(ConfigProvider.fromEnv({ env: {} })))), ); + it.effect("includes distribution metadata in Linux package builds", () => + Effect.gen(function* () { + const config = yield* createBuildConfig( + "linux", + "deb", + "1.2.3", + false, + false, + undefined, + undefined, + ); + + const linux = config.linux as Record; + assert.deepStrictEqual(linux.target, ["deb"]); + assert.equal(linux.executableName, "t3code"); + assert.equal(linux.category, "Development"); + assert.equal(linux.maintainer, "T3 Tools "); + assert.equal(linux.vendor, "T3 Tools"); + assert.equal(linux.synopsis, "A desktop GUI for AI coding agents"); + assert.equal(linux.syncDesktopName, true); + + const deb = config.deb as Record; + assert.deepStrictEqual(deb.depends, [ + "libgtk-3-0", + "libnotify4", + "libnss3", + "libxss1", + "libxtst6", + "xdg-utils", + "libatspi2.0-0", + "libuuid1", + "libsecret-1-0", + "libasound2t64 | libasound2", + ]); + }).pipe(Effect.provide(ConfigProvider.layer(ConfigProvider.fromEnv({ env: {} })))), + ); + it("promotes target fff binaries to direct staged dependencies", () => { assert.deepStrictEqual(resolveFffNativeDependencies("mac", "arm64", "0.9.4"), { "@ff-labs/fff-bin-darwin-arm64": "0.9.4", diff --git a/scripts/build-desktop-artifact.ts b/scripts/build-desktop-artifact.ts index bac3ef3df85..67533c8030c 100644 --- a/scripts/build-desktop-artifact.ts +++ b/scripts/build-desktop-artifact.ts @@ -107,6 +107,19 @@ const PLATFORM_CONFIG: Record = { }, }; +const DEB_DEPENDENCIES = [ + "libgtk-3-0", + "libnotify4", + "libnss3", + "libxss1", + "libxtst6", + "xdg-utils", + "libatspi2.0-0", + "libuuid1", + "libsecret-1-0", + "libasound2t64 | libasound2", +] as const; + interface BuildCliInput { readonly platform: Option.Option; readonly target: Option.Option; @@ -565,6 +578,9 @@ interface StagePackageJson { readonly packageManager: string; readonly description: string; readonly author: string; + readonly homepage: string; + readonly license: string; + readonly desktopName: string; readonly main: string; readonly build: Record; readonly dependencies: Record; @@ -1438,12 +1454,22 @@ export const createBuildConfig = Effect.fn("createBuildConfig")(function* ( executableName: "t3code", icon: "icons", category: "Development", + maintainer: "T3 Tools ", + vendor: "T3 Tools", + synopsis: "A desktop GUI for AI coding agents", + syncDesktopName: true, desktop: { entry: { StartupWMClass: "t3code", }, }, }; + + if (target === "deb") { + buildConfig.deb = { + depends: [...DEB_DEPENDENCIES], + }; + } } if (platform === "win") { @@ -1748,8 +1774,11 @@ const buildDesktopArtifact = Effect.fn("buildDesktopArtifact")(function* ( t3codeCommitHash: commitHash, private: true, packageManager: rootPackageJson.packageManager, - description: "T3 Code desktop build", - author: "T3 Tools", + description: "A desktop GUI for AI coding agents such as Codex, Claude, Cursor, and OpenCode.", + author: "T3 Tools ", + homepage: "https://github.com/pingdotgg/t3code", + license: "MIT", + desktopName: "t3code.desktop", main: "apps/desktop/dist-electron/main.cjs", build: yield* createBuildConfig( options.platform, From 03b684c9944cabc4bcdbe83ac1a02da367f12473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Primo=C5=BE=20Ajdi=C5=A1ek?= Date: Fri, 17 Jul 2026 01:36:30 +0000 Subject: [PATCH 2/4] docs: revert scripts reference changes --- docs/reference/scripts.md | 43 ++++++++++++++------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/docs/reference/scripts.md b/docs/reference/scripts.md index 6813afacdc6..d4d2b96869e 100644 --- a/docs/reference/scripts.md +++ b/docs/reference/scripts.md @@ -1,33 +1,20 @@ # Scripts -- `vp run dev` — Starts contracts, server, and web in watch mode. -- `vp run dev:server` — Starts just the WebSocket server. -- `vp run dev:web` — Starts just the Vite dev server for the web app. +- `bun run dev` — Starts contracts, server, and web in `turbo watch` mode. +- `bun run dev:server` — Starts just the WebSocket server (uses Bun TypeScript execution). +- `bun run dev:web` — Starts just the Vite dev server for the web app. - Dev commands default `T3CODE_STATE_DIR` to `~/.t3/dev` to keep dev state isolated from desktop/prod state. - Override server CLI-equivalent flags from root dev commands with `--`, for example: - `vp run dev -- --base-dir ~/.t3-2` -- `vp run start` — Runs the production server (serves built web app as static files). -- `vp run build` — Builds the workspace applications and packages. -- `vp run typecheck` — Strict TypeScript checks for all packages. -- `vp run test` — Runs workspace tests. -- `vp run dist:desktop:artifact -- --platform --target --arch ` — Builds a desktop artifact for a specific platform/target/arch. -- `vp run dist:desktop:dmg` — Builds a shareable macOS `.dmg` into `./release`. -- `vp run dist:desktop:dmg:x64` — Builds an Intel macOS `.dmg`. -- `vp run dist:desktop:linux` — Builds a Linux AppImage into `./release`. -- `vp run dist:desktop:deb` — Builds a Debian/Ubuntu package into `./packaging-output`. -- `vp run dist:desktop:rpm` — Builds a Fedora/RHEL package into `./packaging-output`. -- `vp run dist:desktop:win` — Builds a Windows NSIS installer into `./release`. - -## Linux `.deb` and `.rpm` packaging - -The package scripts build `x64` by default. Use the existing desktop artifact builder to customize a build: - -```bash -vp run dist:desktop:artifact -- --platform linux --target deb --arch arm64 --build-version 1.2.3 --output-dir out -vp run dist:desktop:artifact -- --platform linux --target rpm --arch arm64 --build-version 1.2.3 --output-dir out -``` - -Pass `--skip-build` to reuse existing desktop, server, and web build outputs. + `bun run dev -- --base-dir ~/.t3-2` +- `bun run start` — Runs the production server (serves built web app as static files). +- `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 dist:desktop:artifact -- --platform --target --arch ` — Builds a desktop artifact for a specific platform/target/arch. +- `bun run dist:desktop:dmg` — Builds a shareable macOS `.dmg` into `./release`. +- `bun run dist:desktop:dmg:x64` — Builds an Intel macOS `.dmg`. +- `bun run dist:desktop:linux` — Builds a Linux AppImage into `./release`. +- `bun run dist:desktop:win` — Builds a Windows NSIS installer into `./release`. ## Desktop `.dmg` packaging notes @@ -36,7 +23,7 @@ Pass `--skip-build` to reuse existing desktop, server, and web build outputs. - Desktop production windows load the bundled UI from `t3code://app/index.html` (not a `127.0.0.1` document URL). - Desktop packaging includes `apps/server/dist` (the `t3` backend) and starts it on loopback with an auth token for WebSocket/API traffic. - Your tester can still open it on macOS by right-clicking the app and choosing **Open** on first launch. -- To keep staging files for debugging package contents, run: `vp run dist:desktop:dmg -- --keep-stage` +- To keep staging files for debugging package contents, run: `bun run dist:desktop:dmg -- --keep-stage` - To allow code-signing/notarization when configured in CI/secrets, add: `--signed`. - Signed macOS builds also require `T3CODE_APPLE_TEAM_ID` and `T3CODE_MACOS_PROVISIONING_PROFILE`. The passkey RP domain is derived from @@ -53,6 +40,6 @@ Set `T3CODE_DEV_INSTANCE` to any value to deterministically shift all dev ports - Default ports: server `3773`, web `5733` - Shifted ports: `base + offset` (offset is hashed from `T3CODE_DEV_INSTANCE`) -- Example: `T3CODE_DEV_INSTANCE=branch-a vp run dev:desktop` +- Example: `T3CODE_DEV_INSTANCE=branch-a bun run dev:desktop` If you want full control instead of hashing, set `T3CODE_PORT_OFFSET` to a numeric offset. From bfd02013d61f2be675748b50ea255324ba78d798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Primo=C5=BE=20Ajdi=C5=A1ek?= Date: Mon, 20 Jul 2026 05:30:26 +0000 Subject: [PATCH 3/4] feat(packaging): expose bundled headless server CLI Install a t3 launcher in DEB and RPM artifacts that runs the bundled server through Electron's Node mode, while preserving t3code as the desktop command. Cover both package mappings and production/nightly install paths with tests. --- scripts/build-desktop-artifact.test.ts | 35 +++++++++++++++++++++++++ scripts/build-desktop-artifact.ts | 36 ++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/scripts/build-desktop-artifact.test.ts b/scripts/build-desktop-artifact.test.ts index 7be718f6dbf..e30d462f649 100644 --- a/scripts/build-desktop-artifact.test.ts +++ b/scripts/build-desktop-artifact.test.ts @@ -31,6 +31,7 @@ import { resolveDesktopProductName, resolveDesktopUpdateChannel, resolveDesktopWebAssetBrand, + renderLinuxHeadlessLauncher, resolveGitHubPublishConfig, resolveMockUpdateServerPort, resolveMockUpdateServerUrl, @@ -508,6 +509,7 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => { false, undefined, undefined, + "/tmp/t3", ); const linux = config.linux as Record; @@ -532,9 +534,42 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => { "libsecret-1-0", "libasound2t64 | libasound2", ]); + assert.deepStrictEqual(deb.fpm, ["/tmp/t3=/usr/bin/t3"]); }).pipe(Effect.provide(ConfigProvider.layer(ConfigProvider.fromEnv({ env: {} })))), ); + it.effect("maps the headless launcher into RPM packages", () => + Effect.gen(function* () { + const config = yield* createBuildConfig( + "linux", + "rpm", + "1.2.3", + false, + false, + undefined, + undefined, + "/tmp/t3", + ); + + const rpm = config.rpm as Record; + assert.deepStrictEqual(rpm.fpm, ["/tmp/t3=/usr/bin/t3"]); + }).pipe(Effect.provide(ConfigProvider.layer(ConfigProvider.fromEnv({ env: {} })))), + ); + + it("renders a headless launcher for production and nightly packages", () => { + assert.equal( + renderLinuxHeadlessLauncher("1.2.3"), + [ + "#!/bin/sh", + "set -eu", + "export ELECTRON_RUN_AS_NODE=1", + `exec '/opt/T3 Code (Alpha)/t3code' '/opt/T3 Code (Alpha)/resources/app.asar.unpacked/apps/server/dist/bin.mjs' "$@"`, + "", + ].join("\n"), + ); + assert.match(renderLinuxHeadlessLauncher("1.2.3-nightly.20260720.1"), /T3 Code \(Nightly\)/); + }); + it("promotes target fff binaries to direct staged dependencies", () => { assert.deepStrictEqual(resolveFffNativeDependencies("mac", "arm64", "0.9.4"), { "@ff-labs/fff-bin-darwin-arm64": "0.9.4", diff --git a/scripts/build-desktop-artifact.ts b/scripts/build-desktop-artifact.ts index 16c759ab13a..5d20493d5e8 100644 --- a/scripts/build-desktop-artifact.ts +++ b/scripts/build-desktop-artifact.ts @@ -1388,6 +1388,24 @@ export function resolveDesktopProductName(version: string): string { : (desktopPackageJson.productName ?? "T3 Code"); } +function quotePosixShellArgument(value: string): string { + return `'${value.replaceAll("'", `'\\''`)}'`; +} + +export function renderLinuxHeadlessLauncher(version: string): string { + const installDir = `/opt/${resolveDesktopProductName(version)}`; + const desktopExecutable = `${installDir}/t3code`; + const serverEntry = `${installDir}/resources/app.asar.unpacked/apps/server/dist/bin.mjs`; + + return [ + "#!/bin/sh", + "set -eu", + "export ELECTRON_RUN_AS_NODE=1", + `exec ${quotePosixShellArgument(desktopExecutable)} ${quotePosixShellArgument(serverEntry)} "$@"`, + "", + ].join("\n"); +} + export const createBuildConfig = Effect.fn("createBuildConfig")(function* ( platform: typeof BuildPlatform.Type, target: string, @@ -1401,6 +1419,7 @@ export const createBuildConfig = Effect.fn("createBuildConfig")(function* ( readonly provisioningProfilePath: string; } | undefined, + linuxHeadlessLauncherPath?: string, ) { const buildConfig: Record = { appId: DESKTOP_APP_ID, @@ -1477,6 +1496,13 @@ export const createBuildConfig = Effect.fn("createBuildConfig")(function* ( if (target === "deb") { buildConfig.deb = { depends: [...DEB_DEPENDENCIES], + ...(linuxHeadlessLauncherPath ? { fpm: [`${linuxHeadlessLauncherPath}=/usr/bin/t3`] } : {}), + }; + } + + if (target === "rpm" && linuxHeadlessLauncherPath) { + buildConfig.rpm = { + fpm: [`${linuxHeadlessLauncherPath}=/usr/bin/t3`], }; } } @@ -1755,6 +1781,15 @@ const buildDesktopArtifact = Effect.fn("buildDesktopArtifact")(function* ( yield* fs.writeFileString(macEntitlementsPath, renderMacPasskeyEntitlements(macPasskeySigning)); } + const linuxHeadlessLauncherPath = + options.platform === "linux" && (options.target === "deb" || options.target === "rpm") + ? path.join(stageRoot, "t3") + : undefined; + if (linuxHeadlessLauncherPath) { + yield* fs.writeFileString(linuxHeadlessLauncherPath, renderLinuxHeadlessLauncher(appVersion)); + yield* fs.chmod(linuxHeadlessLauncherPath, 0o755); + } + const stageDependencies = { ...resolvedServerDependencies, ...resolvedDesktopRuntimeDependencies, @@ -1805,6 +1840,7 @@ const buildDesktopArtifact = Effect.fn("buildDesktopArtifact")(function* ( provisioningProfilePath: macPasskeySigning.provisioningProfilePath, } : undefined, + linuxHeadlessLauncherPath, ), dependencies: stageDependencies, devDependencies: { From ab03901f988d9fdf28a16f7ce923a53b24626e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Primo=C5=BE=20Ajdi=C5=A1ek?= Date: Mon, 20 Jul 2026 06:10:15 +0000 Subject: [PATCH 4/4] fix(packaging): declare RPM runtime dependencies Pin electron-builder's standard RPM requirements and add alsa-lib, libsecret, and mesa-libgbm so desktop and headless commands work on minimal installations without relying on weak dependencies. --- scripts/build-desktop-artifact.test.ts | 15 ++++++++++++++- scripts/build-desktop-artifact.ts | 19 +++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/scripts/build-desktop-artifact.test.ts b/scripts/build-desktop-artifact.test.ts index e30d462f649..e381333aa58 100644 --- a/scripts/build-desktop-artifact.test.ts +++ b/scripts/build-desktop-artifact.test.ts @@ -538,7 +538,7 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => { }).pipe(Effect.provide(ConfigProvider.layer(ConfigProvider.fromEnv({ env: {} })))), ); - it.effect("maps the headless launcher into RPM packages", () => + it.effect("includes runtime dependencies and the headless launcher in RPM packages", () => Effect.gen(function* () { const config = yield* createBuildConfig( "linux", @@ -552,6 +552,19 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => { ); const rpm = config.rpm as Record; + assert.deepStrictEqual(rpm.depends, [ + "gtk3", + "libnotify", + "nss", + "libXScrnSaver", + "(libXtst or libXtst6)", + "xdg-utils", + "at-spi2-core", + "(libuuid or libuuid1)", + "alsa-lib", + "libsecret", + "mesa-libgbm", + ]); assert.deepStrictEqual(rpm.fpm, ["/tmp/t3=/usr/bin/t3"]); }).pipe(Effect.provide(ConfigProvider.layer(ConfigProvider.fromEnv({ env: {} })))), ); diff --git a/scripts/build-desktop-artifact.ts b/scripts/build-desktop-artifact.ts index 5d20493d5e8..f984d112fe7 100644 --- a/scripts/build-desktop-artifact.ts +++ b/scripts/build-desktop-artifact.ts @@ -125,6 +125,20 @@ const DEB_DEPENDENCIES = [ "libasound2t64 | libasound2", ] as const; +const RPM_DEPENDENCIES = [ + "gtk3", + "libnotify", + "nss", + "libXScrnSaver", + "(libXtst or libXtst6)", + "xdg-utils", + "at-spi2-core", + "(libuuid or libuuid1)", + "alsa-lib", + "libsecret", + "mesa-libgbm", +] as const; + interface BuildCliInput { readonly platform: Option.Option; readonly target: Option.Option; @@ -1500,9 +1514,10 @@ export const createBuildConfig = Effect.fn("createBuildConfig")(function* ( }; } - if (target === "rpm" && linuxHeadlessLauncherPath) { + if (target === "rpm") { buildConfig.rpm = { - fpm: [`${linuxHeadlessLauncherPath}=/usr/bin/t3`], + depends: [...RPM_DEPENDENCIES], + ...(linuxHeadlessLauncherPath ? { fpm: [`${linuxHeadlessLauncherPath}=/usr/bin/t3`] } : {}), }; } }