-
Notifications
You must be signed in to change notification settings - Fork 79
Expand file tree
/
Copy pathelectron-builder.json5
More file actions
361 lines (360 loc) · 16.1 KB
/
Copy pathelectron-builder.json5
File metadata and controls
361 lines (360 loc) · 16.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
// @see - https://www.electron.build/configuration/configuration
{
"$schema": "https://raw.githubusercontent.com/electron-userland/electron-builder/master/packages/app-builder-lib/scheme.json",
"appId": "com.etiennelescot.openscreen",
"asar": true,
// .node binaries can't be dlopen'd from inside an asar — must live unpacked.
// onnxruntime-node distributes as a `.node` shared object that whisper.cpp
// helpers run from process spawn, so they all unpack via the same glob.
"asarUnpack": [
"**/*.node"
],
"productName": "Openscreen",
// Fails the build when compositor_view.node is older than the crates/ Rust sources. Plain
// `npm run build` does not rebuild the addon, and a stale one fails SILENTLY at runtime
// (unknown scene fields are #[serde(default)]) rather than erroring. See the script header
// and technical-documentation/engineering/build-and-packaging.md.
"beforePack": "scripts/before-pack.cjs",
"npmRebuild": true,
// sharp ships ABI-stable (napi) prebuilt binaries with bundled libvips. Building it from source
// needs a system libvips we don't provide and breaks on CI/local ("vips-cpp.42 not found"), so we
// let electron-builder use the prebuilt instead of recompiling.
"buildDependenciesFromSource": false,
"compression": "normal",
"directories": {
"output": "release/${version}",
// Electron-builder's default, spelled out because the appx target depends on it:
// it looks for Store tile assets in `<buildResources>/appx/` and, when that
// directory is absent, silently packages its own vendored placeholders instead
// (winCodeSign's SampleAppx.*.png — blank white squares). Shipping those failed
// Store certification 10.1.1.11 "On Device Tiles". `build/appx/` is committed and
// regenerated by `npm run assets:appx`.
"buildResources": "build"
},
"files": [
"dist",
"dist-electron",
"!*.png",
"!preview*.png",
"!*.md",
"!README.md",
"!CONTRIBUTING.md",
"!LICENSE"
],
// Asset layout contract: "wallpapers/" and "cursors/" under resourcesPath must
// align with assetBaseDir in electron/preload.ts (packaged branch).
// Native capture helpers + whisper-stt-server binaries (and their ggml
// backend sidecars) live under `electron/native/bin/<platform>-<arch>/`
// and the per-platform sections below limit them to the matching arch in
// each installer.
//
// ponytail: the STT model (ggml-small-q8_0.bin) is downloaded into the
// userData cache on first use by electron/stt/modelManager.ts, so no model
// files are bundled at build time.
"extraResources": [
// Attribution + LGPL source offer for the bundled ffmpeg DLLs and
// whisper.cpp binaries. Redistributing LGPL libraries obliges us to ship
// the notice with them, so it goes in resources/, not just in the repo.
{
"from": "THIRD-PARTY-NOTICES.md",
"to": "THIRD-PARTY-NOTICES.md"
},
{
"from": "LICENSE",
"to": "LICENSE"
},
{
"from": "public/wallpapers",
"to": "wallpapers"
},
{
"from": "public/cursors",
"to": "cursors"
}
],
"mac": {
"notarize": false,
"hardenedRuntime": true,
"entitlements": "macos.entitlements",
"entitlementsInherit": "macos.entitlements",
"target": [
{
"target": "dmg",
"arch": ["x64", "arm64"]
}
],
"icon": "icons/icons/mac/icon.icns",
"artifactName": "${productName}-Mac-${arch}-${version}-Installer.${ext}",
"extraResources": [
{
"from": "electron/native/bin",
"to": "electron/native/bin",
"filter": ["darwin-*/*"]
}
],
"extendInfo": {
"NSAudioCaptureUsageDescription": "OpenScreen needs audio capture permission to record system audio.",
"NSMicrophoneUsageDescription": "OpenScreen needs microphone access to record voice audio.",
"NSCameraUsageDescription": "OpenScreen needs camera access to record webcam video.",
"NSScreenCaptureUsageDescription": "OpenScreen needs screen recording permission to detect and capture windows.",
"NSCameraUseContinuityCameraDeviceType": true
}
},
"linux": {
// Cette liste ne suffit PAS à produire un artefact en CI : `build:linux` passe
// ses cibles en ligne de commande (`electron-builder --linux AppImage deb pacman
// rpm`), et la CLI REMPLACE `linux.target` au lieu de le compléter. Toute cible
// ajoutée ici doit l'être aussi dans le script, sinon elle n'existe que pour un
// `electron-builder --linux` nu, que rien n'exécute.
"target": [
"AppImage",
"deb",
"pacman",
"rpm"
],
"icon": "icons/icons/png",
"artifactName": "${productName}-Linux-${version}.${ext}",
"maintainer": "Etienne Lescot <etiennelescot@gmail.com>",
"category": "AudioVideo",
"extraResources": [
{
"from": "electron/native/bin",
"to": "electron/native/bin",
// `**`, not `*`: the capture helper's ffmpeg libraries live one level
// deeper, in `linux-x64/helper-ffmpeg/`. They are in their own directory
// because `linux-x64/` also holds the compositor addon's copies of the
// same sonames with every symbol renamed to `osff_*`, and the helper
// must not find those — see scripts/build-linux-pipewire-helper.mjs.
// A single-level filter ships a helper that cannot start.
//
// The name is `helper-ffmpeg` rather than `ffmpeg` because that shorter
// name is taken: fetch-ffmpeg.mjs vendors the static ffmpeg executable
// there, and audioPeaks.ts resolves it by that path.
"filter": ["linux-*/**"]
}
]
},
// Le compositeur natif rend via wgpu/Vulkan (crates/compositor/src/d3d_linux.rs).
// Sans AUCUN ICD Vulkan installé, `request_adapter` ne rend rien : pas de pilote
// GPU, et pas non plus le repli logiciel lavapipe — donc `probe()` répond `"none"`
// et l'aperçu s'ouvre sur « Aperçu indisponible sur cette machine ». Le paquet
// Mesa est ce qui garantit qu'au minimum le rastériseur logiciel existe.
//
// `depends` REMPLACE la liste par défaut d'electron-builder au lieu de s'y ajouter
// (app-builder-lib, FpmTarget.getDefaultDepends) : le défaut y est repris verbatim,
// de `libgtk-3-0` à `libsecret-1-0`, et en retirer une casse le paquet silencieusement.
// Ce qui suit est à NOUS, et se lit par nom plutôt que par position — un compteur
// « les N dernières » se périme à chaque ajout, et l'a déjà fait :
// `mesa-vulkan-drivers`, `libgbm1`, `libasound2`, `libgomp1`, `xdg-desktop-portal`.
//
// L'AppImage n'a pas de mécanisme de dépendances et reste donc exposée : c'est
// pour elle que `d3d_linux::diagnose` nomme le paquet à installer.
//
// `libgbm1`, `libasound2` et `libgomp1` comblent des sonames que rien ne déclarait ni
// n'embarquait, mesurés sur la 1.9.1 installée dans une Ubuntu 22.04 nue :
//
// libgbm1 — réclamé par le binaire Electron LUI-MÊME. Sans lui l'app sort en
// 127 sur `libgbm.so.1: cannot open shared object file`, avant toute
// fenêtre. Absent du défaut d'electron-builder, qui n'a jamais suivi
// le passage de Chromium à GBM.
// libasound2 — même binaire, même conséquence. Sur 24.04+ le paquet réel est
// `libasound2t64`, qui `Provides: libasound2` : le nom court résout
// sur les deux, comme `libgtk-3-0` plus haut.
// libgomp1 — l'OpenMP de GCC, réclamé par les 32 ELF de la pile STT
// (whisper-stt-server, les libggml*, libwhisper, libparakeet). Sans
// lui l'app démarre et seule la transcription meurt dans ld.so.
//
// Aucun n'a été vu avant parce que les métapaquets de bureau les tirent tous les
// trois — libgomp1 seulement via libfftw3-single3, libimagequant0 et libsoxr0, trois
// libs média périphériques. Une install minimale ou un WM monté à la main n'a
// aucune de ces garanties. C'est ce que le job `verify-linux-package` prouve
// désormais à chaque build, en interrogeant le loader plutôt que cette liste.
//
// `xdg-desktop-portal` est la MÊME classe de bug, et le job ci-dessus ne la verra
// jamais : il interroge ld.so, or un portail est un service D-Bus et n'apparaît dans
// aucun DT_NEEDED. Toute la capture Linux passe par lui — X11 compris, le helper
// n'a pas d'autre chemin — et sans lui l'app affiche l'erreur zbus brute (#324).
//
// Le déclarer ne suffit PAS à lui seul, et il faut le dire clairement plutôt que
// laisser croire que la ligne referme le sujet : le frontend ne fait que router, et
// l'implémentation de ScreenCast vient d'un backend qui dépend du bureau
// (-gnome, -kde, -hyprland, -wlr, -gtk). On ne peut pas en choisir un ici sans se
// tromper sur la moitié des machines. Ce que la déclaration achète, c'est que la
// contrainte devient explicite au lieu d'être héritée par accident du métapaquet de
// bureau, exactement comme les trois sonames au-dessus. Le reste est fait à
// l'exécution par `portal.rs::portal_unavailable`, qui nomme le backend à installer —
// et c'est la seule moitié qui couvre l'AppImage, qui ne déclare rien.
//
// Nom identique sur les trois distributions, et vérifié plutôt que supposé :
// `verify-linux-package.sh` installe réellement le paquet dans une image nue, où un nom
// inexistant fait échouer la transaction entière — c'est comme ça que `http-parser` a
// été pris sur pacman. Les trois formats répondent `ok install: declared depends
// resolved` sur ubuntu:22.04, fedora:40 et archlinux:latest (run 31391020354).
"deb": {
"depends": [
"libgtk-3-0",
"libnotify4",
"libnss3",
"libxss1",
"libxtst6",
"xdg-utils",
"libatspi2.0-0",
"libuuid1",
"libsecret-1-0",
"mesa-vulkan-drivers",
"libgbm1",
"libasound2",
"libgomp1",
"xdg-desktop-portal"
]
},
"pacman": {
// `vulkan-swrast` est le lavapipe d'Arch ; il tire `vulkan-icd-loader` avec lui.
//
// `mesa`, `alsa-lib` et `libgomp` sont les équivalents Arch des sonames décrits sur
// `deb`, et `xdg-desktop-portal` y porte le même nom. Noms relevés dans un conteneur
// archlinux, pas devinés : `libgomp.so.1` appartient à `libgomp` (core), PAS à
// `gcc-libs` — il en a été sorti.
//
// `http-parser` A ÉTÉ RETIRÉ, et c'est la seule entrée de ce fichier qui s'écarte
// volontairement du défaut d'electron-builder. Arch l'a supprimé de ses dépôts
// (Node est passé à llhttp il y a des années) et RIEN ne le fournit plus, donc
// pacman refusait la transaction entière : « unable to satisfy dependency
// 'http-parser' ». Le paquet Arch de la 1.9.1 est intégralement non installable,
// pour cette seule ligne. Aucun des 49 sonames du payload ne le réclame.
//
// `libappindicator-gtk3` est dans le même état de péremption mais reste correct :
// `libappindicator` le déclare en `Provides` ET en `Replaces`, donc il résout.
"depends": [
"c-ares",
"ffmpeg",
"gtk3",
"libevent",
"libvpx",
"libxslt",
"libxss",
"minizip",
"nss",
"re2",
"snappy",
"libnotify",
"libappindicator-gtk3",
"vulkan-swrast",
"mesa",
"alsa-lib",
"libgomp",
"xdg-desktop-portal"
]
},
"rpm": {
// Même règle que ci-dessus : la liste REMPLACE le défaut d'electron-builder, donc
// celui-ci est repris verbatim de `gtk3` à `(libuuid or libuuid1)`
// (FpmTarget.getDefaultDepends, cas "rpm"). Le reste est à nous, par nom et non par
// position : `libsecret`, `mesa-vulkan-drivers`, `mesa-libgbm`, `alsa-lib`,
// `libgomp`, `xdg-desktop-portal`.
//
// `mesa-vulkan-drivers` porte le même nom sur Fedora que sur Debian : c'est le
// paquet qui garantit lavapipe, sans quoi l'aperçu du compositeur est indisponible.
//
// `libsecret` n'est PAS dans le défaut rpm alors qu'il l'est dans le défaut deb
// (`libsecret-1-0`). `safeStorage` chiffre les clés d'API des fournisseurs LLM
// (electron/ai-edition/llm-config-store.ts) et passe par le Secret Service :
// sans lui, `isEncryptionAvailable()` répond faux et l'enregistrement d'une clé
// lève. Une omission d'electron-builder, pas un choix.
//
// `mesa-libgbm`, `alsa-lib` et `libgomp` sont les équivalents Fedora des sonames
// décrits sur `deb`, relevés par `dnf provides` : `libgbm.so.1` vient de
// `mesa-libgbm` et non du `mesa` d'Arch. `libgomp` fait partie de l'install de base
// sur Fedora, donc le rpm y était moins exposé que le deb — le déclarer reste ce qui
// rend la contrainte vraie plutôt que chanceuse. `xdg-desktop-portal` y porte le même
// nom que sur Debian et Arch.
"depends": [
"gtk3",
"libnotify",
"nss",
"libXScrnSaver",
"(libXtst or libXtst6)",
"xdg-utils",
"at-spi2-core",
"(libuuid or libuuid1)",
"libsecret",
"mesa-vulkan-drivers",
"mesa-libgbm",
"alsa-lib",
"libgomp",
"xdg-desktop-portal"
]
},
"win": {
"target": [
"nsis"
],
"icon": "icons/icons/win/icon.ico",
"artifactName": "${productName}.Setup.${version}.${ext}",
"extraResources": [
{
"from": "electron/native/bin",
"to": "electron/native/bin",
// The static ffmpeg.exe is excluded on purpose. scripts/fetch-ffmpeg.mjs
// vendors two artifacts into this directory: the shared av*.dll set,
// which the D3D11 compositor addon dlopens at require() time and
// therefore MUST ship, and a standalone static ffmpeg.exe that nothing
// in the app spawns. Shipping it added a large binary to every Windows
// installer, plus an LGPL redistribution obligation, for a file no
// shipped code opens.
"filter": ["win32-*/*", "!win32-*/ffmpeg.exe"]
}
],
// The D3D11 compositor addon deliberately does NOT travel through `files` into
// app.asar. It ships with the ffmpeg DLLs it links against, via the
// `extraResources` entry above, because it has to sit in the SAME directory as
// them — exactly like the Metal addon on macOS.
//
// It used to be listed here and unpacked to app.asar.unpacked/…, one directory
// away from `electron/native/bin/win32-x64/*.dll`. That only ever worked because
// `ensureFfmpegSharedDllsOnPath` prepends the DLL directory to PATH before the
// require. MSIX ignores PATH when resolving dependent DLLs — it resolves through
// the package graph — so the Store build of 1.9.0 loaded no compositor at all and
// the editor ran with no preview while audio kept playing.
//
// Node loads .node files with LOAD_WITH_ALTERED_SEARCH_PATH, so the addon's own
// directory is searched for its dependencies; colocation makes the load work with
// no PATH at all, on every Windows packaging format.
},
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true
},
// Microsoft Store packaging identity, from Partner Center's "Product identity" page
// (Applications et jeux > OpenScreen > Product identity).
"appx": {
"identityName": "EtienneLescot.OpenScreen",
"publisher": "CN=03B0FC8C-2067-45D9-BE82-9F15CE264B4A",
"publisherDisplayName": "Etienne Lescot",
"applicationId": "Openscreen",
"displayName": "OpenScreen",
"backgroundColor": "transparent",
"capabilities": ["runFullTrust", "microphone", "webcam"],
// Mirrors SUPPORTED_LOCALES in src/i18n/config.ts. This list is what the Store
// shows as "supported languages" on the product page and what lets the listing
// surface in each language's Store search — declaring only en-US/fr-FR advertised
// 2 of the 13 languages the app actually ships. Bare tags (ar, es, ...) match every
// region of that language, which is what the renderer's locale resolution does too.
"languages": [
"en-US",
"fr-FR",
"ar",
"es",
"it",
"ja-JP",
"ko-KR",
"pt-BR",
"ru",
"tr",
"vi",
"zh-CN",
"zh-TW"
],
"showNameOnTiles": true
}
}