authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-06-16 09:12:32-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-06-16 09:12:32-07:00
log85fe62d4021dfabe14572b7a7ef55e3f4f1144f4
tree6100303ebc2c3bbf5b3a24e0c7753c9419ae3777
parent708d5383a9c7415c3795890ca4f664c7b00f9a47
signature Signed by PGP key B5690EEEBB952194

Stage fff native binaries in desktop builds (#3109)


6 files changed, 191 insertions(+), 42 deletions(-)

apps/server/package.json+1-1
...@@ -27,7 +27,7 @@...@@ -27,7 +27,7 @@
27 "@effect/platform-node": "catalog:",27 "@effect/platform-node": "catalog:",
28 "@effect/platform-node-shared": "catalog:",28 "@effect/platform-node-shared": "catalog:",
29 "@effect/sql-sqlite-bun": "catalog:",29 "@effect/sql-sqlite-bun": "catalog:",
30 "@ff-labs/fff-node": "^0.9.4",30 "@ff-labs/fff-node": "0.9.4",
31 "@opencode-ai/sdk": "^1.3.15",31 "@opencode-ai/sdk": "^1.3.15",
32 "@pierre/diffs": "catalog:",32 "@pierre/diffs": "catalog:",
33 "effect": "catalog:",33 "effect": "catalog:",
patches/@ff-labs__fff-node@0.9.4.patch created+37
...@@ -0,0 +1,37 @@
1diff --git a/dist/src/binary.js b/dist/src/binary.js
2index ee181aef5007e4bf34a49479c089ca30f73a320b..327e2c55c83cc4c50d396a3109190ef10af75ca7 100644
3--- a/dist/src/binary.js
4+++ b/dist/src/binary.js
5@@ -7,7 +7,7 @@
6 */
7 import { existsSync, readFileSync } from "node:fs";
8 import { createRequire } from "node:module";
9-import { dirname, join } from "node:path";
10+import { dirname, join, sep } from "node:path";
11 import { fileURLToPath } from "node:url";
12 import { getLibFilename, getNpmPackageName } from "./platform.js";
13 /**
14@@ -46,6 +46,14 @@ function getPackageDir() {
15 // Fallback: assume we're one level deep in src/
16 return dirname(currentDir);
17 }
18+function resolveUnpackedAsarPath(binaryPath) {
19+ const asarSegment = `${sep}app.asar${sep}`;
20+ if (!binaryPath.includes(asarSegment)) {
21+ return binaryPath;
22+ }
23+ const unpackedPath = binaryPath.replace(asarSegment, `${sep}app.asar.unpacked${sep}`);
24+ return existsSync(unpackedPath) ? unpackedPath : binaryPath;
25+}
26 /**
27 * Check if the binary exists in any known location
28 */
29@@ -69,7 +77,7 @@ function resolveFromNpmPackage() {
30 const packageDir = dirname(packageJsonPath);
31 const binaryPath = join(packageDir, getLibFilename());
32 if (existsSync(binaryPath)) {
33- return binaryPath;
34+ return resolveUnpackedAsarPath(binaryPath);
35 }
36 }
37 catch {
pnpm-lock.yaml+6-3
...@@ -66,6 +66,9 @@ patchedDependencies:...@@ -66,6 +66,9 @@ patchedDependencies:
66 '@expo/metro-config@56.0.13':66 '@expo/metro-config@56.0.13':
67 hash: 8cb08b5bb7051ed9d2dbe46a2c293c5a1e17f1bd6ddf30de27909e18c921ff4667 hash: 8cb08b5bb7051ed9d2dbe46a2c293c5a1e17f1bd6ddf30de27909e18c921ff46
68 path: patches/@expo%2Fmetro-config@56.0.13.patch68 path: patches/@expo%2Fmetro-config@56.0.13.patch
69 '@ff-labs/fff-node@0.9.4':
70 hash: 2b16019ce7ab61aec6478dd02f79ef468cc1d5c51e9d00764f7d2ab8167210c8
71 path: patches/@ff-labs__fff-node@0.9.4.patch
69 '@pierre/diffs@1.3.0-beta.4':72 '@pierre/diffs@1.3.0-beta.4':
70 hash: f5d41705ce94bbafc731d92e9cb1671db710df046dd135cb894e3e3e9164a75b73 hash: f5d41705ce94bbafc731d92e9cb1671db710df046dd135cb894e3e3e9164a75b
71 path: patches/@pierre%2Fdiffs@1.3.0-beta.4.patch74 path: patches/@pierre%2Fdiffs@1.3.0-beta.4.patch
...@@ -396,8 +399,8 @@ importers:...@@ -396,8 +399,8 @@ importers:
396 specifier: 4.0.0-beta.78399 specifier: 4.0.0-beta.78
397 version: 4.0.0-beta.78(effect@4.0.0-beta.78(patch_hash=883249d8efbb462e928e21fefef96027b66aec50751178cafdce45f08eee3754))400 version: 4.0.0-beta.78(effect@4.0.0-beta.78(patch_hash=883249d8efbb462e928e21fefef96027b66aec50751178cafdce45f08eee3754))
398 '@ff-labs/fff-node':401 '@ff-labs/fff-node':
399 specifier: ^0.9.4402 specifier: 0.9.4
400 version: 0.9.4403 version: 0.9.4(patch_hash=2b16019ce7ab61aec6478dd02f79ef468cc1d5c51e9d00764f7d2ab8167210c8)
401 '@opencode-ai/sdk':404 '@opencode-ai/sdk':
402 specifier: ^1.3.15405 specifier: ^1.3.15
403 version: 1.15.13406 version: 1.15.13
...@@ -11854,7 +11857,7 @@ snapshots:...@@ -11854,7 +11857,7 @@ snapshots:
11854 '@ff-labs/fff-bin-win32-x64@0.9.4':11857 '@ff-labs/fff-bin-win32-x64@0.9.4':
11855 optional: true11858 optional: true
1185611859
11857 '@ff-labs/fff-node@0.9.4':11860 '@ff-labs/fff-node@0.9.4(patch_hash=2b16019ce7ab61aec6478dd02f79ef468cc1d5c51e9d00764f7d2ab8167210c8)':
11858 dependencies:11861 dependencies:
11859 ffi-rs: 1.3.211862 ffi-rs: 1.3.2
11860 optionalDependencies:11863 optionalDependencies:
pnpm-workspace.yaml+34-36
...@@ -1,22 +1,11 @@...@@ -1,22 +1,11 @@
1packages:1packages:
2 - "apps/*"2 - apps/*
3 - "infra/*"3 - infra/*
4 - "oxlint-plugin-t3code"4 - oxlint-plugin-t3code
5 - "packages/*"5 - packages/*
6 - "scripts"6 - scripts
7
8onlyBuiltDependencies:
9 - electron
10 - esbuild
11 - msgpackr-extract
12 - node-pty
13 - sharp
14
15ignoredBuiltDependencies:
16 - msw
177
18catalog:8catalog:
19 effect: 4.0.0-beta.78
20 "@effect/atom-react": 4.0.0-beta.789 "@effect/atom-react": 4.0.0-beta.78
21 "@effect/openapi-generator": 4.0.0-beta.7810 "@effect/openapi-generator": 4.0.0-beta.78
22 "@effect/platform-bun": 4.0.0-beta.7811 "@effect/platform-bun": 4.0.0-beta.78
...@@ -24,23 +13,33 @@ catalog:...@@ -24,23 +13,33 @@ catalog:
24 "@effect/platform-node-shared": 4.0.0-beta.7813 "@effect/platform-node-shared": 4.0.0-beta.78
25 "@effect/sql-pg": 4.0.0-beta.7814 "@effect/sql-pg": 4.0.0-beta.78
26 "@effect/sql-sqlite-bun": 4.0.0-beta.7815 "@effect/sql-sqlite-bun": 4.0.0-beta.78
27 "@effect/vitest": 4.0.0-beta.78
28 "@effect/tsgo": 0.13.216 "@effect/tsgo": 0.13.2
17 "@effect/vitest": 4.0.0-beta.78
29 "@noble/curves": 1.9.118 "@noble/curves": 1.9.1
30 "@noble/hashes": 1.8.019 "@noble/hashes": 1.8.0
31 "@pierre/diffs": 1.3.0-beta.420 "@pierre/diffs": 1.3.0-beta.4
32 "@vitest/runner": 4.1.8
33 "@types/node": 24.12.421 "@types/node": 24.12.4
34 "@typescript/native-preview": 7.0.0-dev.20260604.122 "@typescript/native-preview": 7.0.0-dev.20260604.1
23 "@vitest/runner": 4.1.8
24 effect: 4.0.0-beta.78
35 jose: 6.2.225 jose: 6.2.2
36 typescript: ~6.0.326 typescript: ~6.0.3
37 vitest: npm:@voidzero-dev/vite-plus-test@0.1.24
38 vite: npm:@voidzero-dev/vite-plus-core@0.1.2427 vite: npm:@voidzero-dev/vite-plus-core@0.1.24
39 vite-plus: 0.1.2428 vite-plus: 0.1.24
29 vitest: npm:@voidzero-dev/vite-plus-test@0.1.24
40 yaml: ^2.9.030 yaml: ^2.9.0
31
32ignoredBuiltDependencies:
33 - msw
34
35onlyBuiltDependencies:
36 - electron
37 - esbuild
38 - msgpackr-extract
39 - node-pty
40 - sharp
41
41overrides:42overrides:
42 # Clerk publishes wallet auth integrations as required dependencies. T3 Code does
43 # not support wallet auth, so keep that unused dependency tree out of installs.
44 "@clerk/clerk-js>@base-org/account": "-"43 "@clerk/clerk-js>@base-org/account": "-"
45 "@clerk/clerk-js>@coinbase/wallet-sdk": "-"44 "@clerk/clerk-js>@coinbase/wallet-sdk": "-"
46 "@clerk/clerk-js>@solana/wallet-adapter-base": "-"45 "@clerk/clerk-js>@solana/wallet-adapter-base": "-"
...@@ -56,22 +55,13 @@ overrides:...@@ -56,22 +55,13 @@ overrides:
56 "@effect/vitest": "catalog:"55 "@effect/vitest": "catalog:"
57 "@effect/vitest>@vitest/runner": "-"56 "@effect/vitest>@vitest/runner": "-"
58 "@effect/vitest>vitest": "-"57 "@effect/vitest>vitest": "-"
59 # Pinned to the version the patch in patchedDependencies targets — a fresh58 "@expo/metro-config": 56.0.13
60 # resolve (e.g. release-smoke regenerating the lockfile) must not drift to a
61 # newer release and orphan the patch (ERR_PNPM_UNUSED_PATCH).
62 "@expo/metro-config": "56.0.13"
63 "@types/node": "catalog:"59 "@types/node": "catalog:"
64 effect: "catalog:"60 effect: "catalog:"
65 vite: "catalog:"61 vite: "catalog:"
66 vitest: "catalog:"62 vitest: "catalog:"
67 yaml: "catalog:"63 yaml: "catalog:"
68peerDependencyRules:64
69 allowAny:
70 - vite
71 - vitest
72 allowedVersions:
73 vite: "*"
74 vitest: "*"
75packageExtensions:65packageExtensions:
76 "@effect/vitest@*":66 "@effect/vitest@*":
77 dependencies:67 dependencies:
...@@ -79,14 +69,22 @@ packageExtensions:...@@ -79,14 +69,22 @@ packageExtensions:
79 peerDependenciesMeta:69 peerDependenciesMeta:
80 vitest:70 vitest:
81 optional: true71 optional: true
82 "vite-plus@*":72 vite-plus@*:
83 dependencies:73 dependencies:
84 vite: "catalog:"74 vite: "catalog:"
75
85patchedDependencies:76patchedDependencies:
86 # Keep non-browser consumers off the root entrypoint, which eagerly imports
87 # DOM-dependent renderers. These utility/type subpaths are safe for mobile.
88 "@pierre/diffs@1.3.0-beta.4": patches/@pierre%2Fdiffs@1.3.0-beta.4.patch
89 "@effect/vitest@4.0.0-beta.78": patches/@effect__vitest@4.0.0-beta.78.patch77 "@effect/vitest@4.0.0-beta.78": patches/@effect__vitest@4.0.0-beta.78.patch
90 "@expo/metro-config@56.0.13": patches/@expo%2Fmetro-config@56.0.13.patch78 "@expo/metro-config@56.0.13": patches/@expo%2Fmetro-config@56.0.13.patch
79 "@ff-labs/fff-node@0.9.4": patches/@ff-labs__fff-node@0.9.4.patch
80 "@pierre/diffs@1.3.0-beta.4": patches/@pierre%2Fdiffs@1.3.0-beta.4.patch
91 effect@4.0.0-beta.78: patches/effect@4.0.0-beta.78.patch81 effect@4.0.0-beta.78: patches/effect@4.0.0-beta.78.patch
92 react-native-nitro-modules@0.35.9: patches/react-native-nitro-modules@0.35.9.patch82 react-native-nitro-modules@0.35.9: patches/react-native-nitro-modules@0.35.9.patch
83
84peerDependencyRules:
85 allowAny:
86 - vite
87 - vitest
88 allowedVersions:
89 vite: "*"
90 vitest: "*"
scripts/build-desktop-artifact.test.ts+50
...@@ -6,8 +6,11 @@ import * as Layer from "effect/Layer";...@@ -6,8 +6,11 @@ import * as Layer from "effect/Layer";
6import * as Option from "effect/Option";6import * as Option from "effect/Option";
77
8import {8import {
9 createStageWorkspaceConfig,
9 createStagePnpmConfig,10 createStagePnpmConfig,
11 DESKTOP_ASAR_UNPACK,
10 resolveDesktopRuntimeDependencies,12 resolveDesktopRuntimeDependencies,
13 resolveFffNativeDependencies,
11 resolveBuildOptions,14 resolveBuildOptions,
12 resolveDesktopBuildIconAssets,15 resolveDesktopBuildIconAssets,
13 resolveDesktopProductName,16 resolveDesktopProductName,
...@@ -15,6 +18,7 @@ import {...@@ -15,6 +18,7 @@ import {
15 resolveGitHubPublishConfig,18 resolveGitHubPublishConfig,
16 resolveMockUpdateServerPort,19 resolveMockUpdateServerPort,
17 resolveMockUpdateServerUrl,20 resolveMockUpdateServerUrl,
21 STAGE_INSTALL_ARGS,
18} from "./build-desktop-artifact.ts";22} from "./build-desktop-artifact.ts";
19import { BRAND_ASSET_PATHS } from "./lib/brand-assets.ts";23import { BRAND_ASSET_PATHS } from "./lib/brand-assets.ts";
20import { HostProcessArchitecture, HostProcessPlatform } from "@t3tools/shared/hostProcess";24import { HostProcessArchitecture, HostProcessPlatform } from "@t3tools/shared/hostProcess";
...@@ -114,17 +118,20 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => {...@@ -114,17 +118,20 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => {
114 createStagePnpmConfig(118 createStagePnpmConfig(
115 {119 {
116 "@expo/metro-config@56.0.13": "patches/@expo%2Fmetro-config@56.0.13.patch",120 "@expo/metro-config@56.0.13": "patches/@expo%2Fmetro-config@56.0.13.patch",
121 "@ff-labs/fff-node@0.9.4": "patches/@ff-labs__fff-node@0.9.4.patch",
117 "@pierre/diffs@1.1.20": "patches/@pierre%2Fdiffs@1.1.20.patch",122 "@pierre/diffs@1.1.20": "patches/@pierre%2Fdiffs@1.1.20.patch",
118 "alchemy@2.0.0-beta.49": "patches/alchemy@2.0.0-beta.49.patch",123 "alchemy@2.0.0-beta.49": "patches/alchemy@2.0.0-beta.49.patch",
119 "effect@4.0.0-beta.73": "patches/effect@4.0.0-beta.73.patch",124 "effect@4.0.0-beta.73": "patches/effect@4.0.0-beta.73.patch",
120 },125 },
121 {126 {
127 "@ff-labs/fff-node": "0.9.4",
122 "@pierre/diffs": "1.1.20",128 "@pierre/diffs": "1.1.20",
123 effect: "4.0.0-beta.73",129 effect: "4.0.0-beta.73",
124 },130 },
125 ),131 ),
126 {132 {
127 patchedDependencies: {133 patchedDependencies: {
134 "@ff-labs/fff-node@0.9.4": "patches/@ff-labs__fff-node@0.9.4.patch",
128 "@pierre/diffs@1.1.20": "patches/@pierre%2Fdiffs@1.1.20.patch",135 "@pierre/diffs@1.1.20": "patches/@pierre%2Fdiffs@1.1.20.patch",
129 "effect@4.0.0-beta.73": "patches/effect@4.0.0-beta.73.patch",136 "effect@4.0.0-beta.73": "patches/effect@4.0.0-beta.73.patch",
130 },137 },
...@@ -142,6 +149,49 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => {...@@ -142,6 +149,49 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => {
142 );149 );
143 });150 });
144151
152 it("installs optional native dependencies for the target desktop architecture", () => {
153 assert.deepStrictEqual(STAGE_INSTALL_ARGS, ["install", "--prod"]);
154 assert.deepStrictEqual(createStageWorkspaceConfig("mac", "x64"), {
155 supportedArchitectures: {
156 os: ["darwin"],
157 cpu: ["x64"],
158 },
159 });
160 assert.deepStrictEqual(createStageWorkspaceConfig("win", "arm64"), {
161 supportedArchitectures: {
162 os: ["win32"],
163 cpu: ["arm64"],
164 },
165 });
166 assert.deepStrictEqual(createStageWorkspaceConfig("mac", "universal"), {
167 supportedArchitectures: {
168 os: ["darwin"],
169 cpu: ["arm64", "x64"],
170 },
171 });
172 });
173
174 it("unpacks the fff shared library for filesystem and FFI access", () => {
175 assert.deepStrictEqual(DESKTOP_ASAR_UNPACK, ["node_modules/@ff-labs/fff-bin-*/**/*"]);
176 });
177
178 it("promotes target fff binaries to direct staged dependencies", () => {
179 assert.deepStrictEqual(resolveFffNativeDependencies("mac", "arm64", "0.9.4"), {
180 "@ff-labs/fff-bin-darwin-arm64": "0.9.4",
181 });
182 assert.deepStrictEqual(resolveFffNativeDependencies("mac", "universal", "0.9.4"), {
183 "@ff-labs/fff-bin-darwin-arm64": "0.9.4",
184 "@ff-labs/fff-bin-darwin-x64": "0.9.4",
185 });
186 assert.deepStrictEqual(resolveFffNativeDependencies("win", "x64", "0.9.4"), {
187 "@ff-labs/fff-bin-win32-x64": "0.9.4",
188 });
189 assert.deepStrictEqual(resolveFffNativeDependencies("linux", "arm64", "0.9.4"), {
190 "@ff-labs/fff-bin-linux-arm64-gnu": "0.9.4",
191 "@ff-labs/fff-bin-linux-arm64-musl": "0.9.4",
192 });
193 });
194
145 it("falls back to the default mock update port when the configured port is blank", () => {195 it("falls back to the default mock update port when the configured port is blank", () => {
146 assert.equal(resolveMockUpdateServerUrl(undefined), "http://localhost:3000");196 assert.equal(resolveMockUpdateServerUrl(undefined), "http://localhost:3000");
147 assert.equal(resolveMockUpdateServerUrl(4123), "http://localhost:4123");197 assert.equal(resolveMockUpdateServerUrl(4123), "http://localhost:4123");
scripts/build-desktop-artifact.ts+63-2
...@@ -38,11 +38,19 @@ const WorkspaceConfig = Schema.Struct({...@@ -38,11 +38,19 @@ const WorkspaceConfig = Schema.Struct({
38});38});
39type WorkspaceConfig = typeof WorkspaceConfig.Type;39type WorkspaceConfig = typeof WorkspaceConfig.Type;
4040
41const StageWorkspaceConfig = Schema.Struct({
42 supportedArchitectures: Schema.Struct({
43 os: Schema.Array(Schema.String),
44 cpu: Schema.Array(Schema.String),
45 }),
46});
47
41const RepoRoot = Effect.service(Path.Path).pipe(48const RepoRoot = Effect.service(Path.Path).pipe(
42 Effect.flatMap((path) => path.fromFileUrl(new URL("..", import.meta.url))),49 Effect.flatMap((path) => path.fromFileUrl(new URL("..", import.meta.url))),
43);50);
44const encodeJsonString = Schema.encodeEffect(Schema.UnknownFromJsonString);51const encodeJsonString = Schema.encodeEffect(Schema.UnknownFromJsonString);
45const decodeWorkspaceConfig = Schema.decodeEffect(fromYaml(WorkspaceConfig));52const decodeWorkspaceConfig = Schema.decodeEffect(fromYaml(WorkspaceConfig));
53const encodeStageWorkspaceConfig = Schema.encodeEffect(fromYaml(StageWorkspaceConfig));
4654
47const readWorkspaceConfig = Effect.fn("readWorkspaceConfig")(function* () {55const readWorkspaceConfig = Effect.fn("readWorkspaceConfig")(function* () {
48 const fs = yield* FileSystem.FileSystem;56 const fs = yield* FileSystem.FileSystem;
...@@ -282,6 +290,47 @@ interface StagePackageJson {...@@ -282,6 +290,47 @@ interface StagePackageJson {
282 };290 };
283}291}
284292
293export const STAGE_INSTALL_ARGS = ["install", "--prod"] as const;
294export const DESKTOP_ASAR_UNPACK = ["node_modules/@ff-labs/fff-bin-*/**/*"] as const;
295
296export function resolveFffNativeDependencies(
297 platform: typeof BuildPlatform.Type,
298 arch: typeof BuildArch.Type,
299 version: string,
300): Record<string, string> {
301 const architectures = arch === "universal" ? (["arm64", "x64"] as const) : [arch];
302
303 if (platform === "mac") {
304 return Object.fromEntries(
305 architectures.map((architecture) => [`@ff-labs/fff-bin-darwin-${architecture}`, version]),
306 );
307 }
308
309 if (platform === "win") {
310 return Object.fromEntries(
311 architectures.map((architecture) => [`@ff-labs/fff-bin-win32-${architecture}`, version]),
312 );
313 }
314
315 return Object.fromEntries(
316 architectures.flatMap((architecture) =>
317 ["gnu", "musl"].map((libc) => [`@ff-labs/fff-bin-linux-${architecture}-${libc}`, version]),
318 ),
319 );
320}
321
322export function createStageWorkspaceConfig(
323 platform: typeof BuildPlatform.Type,
324 arch: typeof BuildArch.Type,
325): typeof StageWorkspaceConfig.Type {
326 return {
327 supportedArchitectures: {
328 os: [platform === "mac" ? "darwin" : platform === "win" ? "win32" : "linux"],
329 cpu: arch === "universal" ? ["arm64", "x64"] : [arch],
330 },
331 };
332}
333
285export function createStagePnpmConfig(334export function createStagePnpmConfig(
286 patchedDependencies: Record<string, string>,335 patchedDependencies: Record<string, string>,
287 dependencies: Record<string, unknown>,336 dependencies: Record<string, unknown>,
...@@ -702,6 +751,7 @@ const createBuildConfig = Effect.fn("createBuildConfig")(function* (...@@ -702,6 +751,7 @@ const createBuildConfig = Effect.fn("createBuildConfig")(function* (
702 appId: "com.t3tools.t3code",751 appId: "com.t3tools.t3code",
703 productName: resolveDesktopProductName(version),752 productName: resolveDesktopProductName(version),
704 artifactName: "T3-Code-${version}-${arch}.${ext}",753 artifactName: "T3-Code-${version}-${arch}.${ext}",
754 asarUnpack: [...DESKTOP_ASAR_UNPACK],
705 directories: {755 directories: {
706 buildResources: "apps/desktop/resources",756 buildResources: "apps/desktop/resources",
707 },757 },
...@@ -909,6 +959,11 @@ const buildDesktopArtifact = Effect.fn("buildDesktopArtifact")(function* (...@@ -909,6 +959,11 @@ const buildDesktopArtifact = Effect.fn("buildDesktopArtifact")(function* (
909 const stageDependencies = {959 const stageDependencies = {
910 ...resolvedServerDependencies,960 ...resolvedServerDependencies,
911 ...resolvedDesktopRuntimeDependencies,961 ...resolvedDesktopRuntimeDependencies,
962 ...resolveFffNativeDependencies(
963 options.platform,
964 options.arch,
965 serverPackageJson.dependencies["@ff-labs/fff-node"],
966 ),
912 };967 };
913 const stagePnpmConfig = createStagePnpmConfig(workspacePatchedDependencies, stageDependencies);968 const stagePnpmConfig = createStagePnpmConfig(workspacePatchedDependencies, stageDependencies);
914 const stagePackageJson: StagePackageJson = {969 const stagePackageJson: StagePackageJson = {
...@@ -939,19 +994,25 @@ const buildDesktopArtifact = Effect.fn("buildDesktopArtifact")(function* (...@@ -939,19 +994,25 @@ const buildDesktopArtifact = Effect.fn("buildDesktopArtifact")(function* (
939994
940 const stagePackageJsonString = yield* encodeJsonString(stagePackageJson);995 const stagePackageJsonString = yield* encodeJsonString(stagePackageJson);
941 yield* fs.writeFileString(path.join(stageAppDir, "package.json"), `${stagePackageJsonString}\n`);996 yield* fs.writeFileString(path.join(stageAppDir, "package.json"), `${stagePackageJsonString}\n`);
997 const stageWorkspaceConfig = createStageWorkspaceConfig(options.platform, options.arch);
998 const stageWorkspaceConfigString = yield* encodeStageWorkspaceConfig(stageWorkspaceConfig);
999 yield* fs.writeFileString(
1000 path.join(stageAppDir, "pnpm-workspace.yaml"),
1001 stageWorkspaceConfigString,
1002 );
9421003
943 if (Object.keys(workspacePatchedDependencies).length > 0) {1004 if (Object.keys(workspacePatchedDependencies).length > 0) {
944 yield* fs.copy(path.join(repoRoot, "patches"), path.join(stageAppDir, "patches"));1005 yield* fs.copy(path.join(repoRoot, "patches"), path.join(stageAppDir, "patches"));
945 }1006 }
9461007
947 yield* Effect.log("[desktop-artifact] Installing staged production dependencies...");1008 yield* Effect.log("[desktop-artifact] Installing staged production dependencies...");
948 const installCommand = yield* resolveSpawnCommand("vp", ["install", "--prod", "--no-optional"]);1009 const installCommand = yield* resolveSpawnCommand("vp", [...STAGE_INSTALL_ARGS]);
949 yield* runCommand(1010 yield* runCommand(
950 ChildProcess.make(installCommand.command, installCommand.args, {1011 ChildProcess.make(installCommand.command, installCommand.args, {
951 cwd: stageAppDir,1012 cwd: stageAppDir,
952 shell: installCommand.shell,1013 shell: installCommand.shell,
953 }),1014 }),
954 { label: "vp install --prod --no-optional", verbose: options.verbose },1015 { label: "vp install --prod", verbose: options.verbose },
955 );1016 );
9561017
957 // electron-builder treats several set-but-empty variables (e.g. CSC_LINK="")1018 // electron-builder treats several set-but-empty variables (e.g. CSC_LINK="")