forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathelectron-builder.config.mjs
More file actions
164 lines (161 loc) · 8.51 KB
/
Copy pathelectron-builder.config.mjs
File metadata and controls
164 lines (161 loc) · 8.51 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
// electron-builder configuration (was electron-builder.yml — converted to a JS
// config in PR-D2 so the pi-mono asarUnpack closure can be spread in
// programmatically).
//
// WHY JS, not YAML: pi-mono (@earendil-works/pi-coding-agent) is spawned as a
// plain-Node child (ELECTRON_RUN_AS_NODE) by src/main/codingAgent/piMono.ts, so
// every package in its ~128-package runtime closure must be asarUnpacked (a
// plain-Node child cannot read from asar). Hand-listing that many globs in YAML
// silently drifts on a pi-mono version bump. Instead we compute the closure by
// walking pi's dependency graph at pack time (computeUnpackGlobs, drift-proof by
// construction — it reads the ACTUAL installed tree every build) and spread it
// into asarUnpack. See scripts/gen-pimono-unpack.mjs and verify-pimono-unpack.mjs.
//
// electron-builder v26 supports .mjs config files (do NOT name it
// electron-builder.js — that name conflicts with the package itself).
// IMPORTANT: electron-builder only AUTO-detects electron-builder.<ext> (yml/json/
// js/cjs/mjs/ts), NOT the electron-builder.config.* name, so every build:* script
// in package.json MUST pass `--config electron-builder.config.mjs` explicitly.
// Removing that flag silently drops this whole config (and the pi-mono closure).
import { computeUnpackGlobs } from './scripts/gen-pimono-unpack.mjs'
import { KGWORKER_NATIVE_UNPACK_GLOBS } from './scripts/kgworker-native-closure.mjs'
// Fresh at every pack: the closure is recomputed from the installed node_modules,
// so it can never be stale relative to what is actually on disk.
const { globs: pimonoUnpackGlobs } = computeUnpackGlobs()
export default {
appId: 'com.omiwindows.app',
productName: 'Omi for Windows',
directories: {
buildResources: 'build'
},
files: [
// Explicit default; positive patterns below would otherwise replace it.
'**/*',
'!**/.vscode/*',
'!src/*',
'!electron.vite.config.{js,ts,mjs,cjs}',
'!{.eslintcache,eslint.config.mjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}',
'!{.env,.env.*,.npmrc,pnpm-lock.yaml}',
'!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}',
'!{tailwind.config.ts,postcss.config.js}',
'!resources/win-ocr-helper/*.pdb',
'!resources/win-automation-helper/*.pdb',
'!resources/win-audio-helper/*.pdb'
],
asarUnpack: [
'resources/**',
// koffi loads its native .node at runtime, resolved relative to its own package
// dir — it must live outside the asar archive or the foreground monitor fails.
'node_modules/koffi/**',
// kgWorker.js is loaded via new Worker(path) which bypasses Electron's asar
// virtual-fs patch — it must be a real file on disk.
'out/main/kgWorker.js',
// ...and so must its native-module runtime closure: the worker's module
// resolution is plain real-fs anchored at app.asar.unpacked and never crosses
// back into app.asar, so better-sqlite3 + its pure-JS deps (bindings,
// file-uri-to-path) must all be unpacked or the worker dies with
// "Cannot find module 'bindings'". See scripts/kgworker-native-closure.mjs.
...KGWORKER_NATIVE_UNPACK_GLOBS,
// The coding-agent ACP entry is spawned as a plain Node child process
// (ELECTRON_RUN_AS_NODE), which cannot read scripts out of the asar archive —
// both the entry (emitted under out/main/chunks by the ?asset import) and the
// packages it needs at runtime must be real files on disk. The transitive
// entries are claude-agent-acp's own runtime imports (electron-builder
// flattens resolved deps into the package's node_modules).
'out/main/chunks/*.mjs',
'node_modules/@agentclientprotocol/claude-agent-acp/**',
'node_modules/@agentclientprotocol/sdk/**',
'node_modules/@anthropic-ai/claude-agent-sdk/**',
'node_modules/@anthropic-ai/claude-agent-sdk-win32-x64/**',
// zod is the only remaining runtime import of the closure above (verified by
// spawning the entry from a packaged build; the sdk resolves it hoisted).
'node_modules/zod/**',
// pi-mono (@earendil-works/pi-coding-agent) is spawned as a plain-Node child
// (ELECTRON_RUN_AS_NODE) by src/main/codingAgent/piMono.ts, so — like the ACP
// entry above — every file it require()s at runtime must live outside the asar
// archive. The four @earendil-works packages are its core; jiti (in the closure
// below) is what loads the .ts provider extension on the fly.
'node_modules/@earendil-works/**',
// The omi-provider extension is a raw .ts source dir copied next to the main
// bundle by scripts/copy-pimono-extension.mjs (resolveBundledExtension() looks
// there). pi loads it via jiti, so it too must be on disk, not in asar.
'out/main/pi-mono-extension/**',
// pi's FULL transitive runtime closure (dependencies + optionalDependencies),
// computed at pack time by walking its dependency graph — AWS SDK,
// google-auth-library, protobufjs, openai, @mistralai/mistralai, @google/genai,
// jiti, undici, the native @mariozechner/clipboard-* addon, the
// @silvia-odwyer/photon-node WASM, etc. This replaces the hand-maintained list
// the old ⚠️ INCOMPLETE comment warned about.
...pimonoUnpackGlobs
],
win: {
executableName: 'omi-windows',
// Committed multi-size icon (generated by `pnpm gen:app-icon`). Set explicitly
// because it lives in resources/, not the default buildResources dir (build/,
// which is gitignored). NSIS installer/uninstaller/shortcut icons inherit this.
icon: 'resources/icon.ico',
target: [{ target: 'nsis', arch: ['x64'] }]
// --- CODE SIGNING (unsigned today → Windows SmartScreen warns "unknown publisher") ---
// Signing requires a certificate that must be procured separately; until one is
// wired in, leave this out so unsigned builds still succeed. Recommended: Azure
// Trusted Signing (no hardware token, CI-friendly). Once you have an account,
// add azureSignOptions (publisherName / endpoint / certificateProfileName /
// codeSigningAccountName), storing secrets in CI, never here. Traditional OV/EV
// cert alternative: signtoolOptions with certificateSubjectName, or
// certificateFile / certificatePassword via CSC_LINK / CSC_KEY_PASSWORD env.
},
nsis: {
oneClick: false,
perMachine: false,
allowToChangeInstallationDirectory: true,
// No spaces in the artifact name: electron-updater downloads the installer by
// the exact url recorded in latest.yml, and a spaced productName ("Omi for
// Windows") url-encodes to a path that no longer matches the uploaded asset —
// every auto-update would 404. Keep this literal and space-free.
artifactName: 'Omi-for-Windows-Setup-${version}.${ext}',
shortcutName: '${productName}',
uninstallDisplayName: '${productName}',
createDesktopShortcut: 'always'
},
mac: {
entitlementsInherit: 'build/entitlements.mac.plist',
extendInfo: [
{ NSCameraUsageDescription: "Application requests access to the device's camera." },
{ NSMicrophoneUsageDescription: "Application requests access to the device's microphone." },
{
NSDocumentsFolderUsageDescription:
"Application requests access to the user's Documents folder."
},
{
NSDownloadsFolderUsageDescription:
"Application requests access to the user's Downloads folder."
}
],
notarize: false
},
dmg: {
artifactName: '${name}-${version}.${ext}'
},
linux: {
target: ['AppImage', 'snap', 'deb'],
maintainer: 'Based Hardware <team@basedhardware.com>',
category: 'Utility'
},
appImage: {
artifactName: '${name}-${version}.${ext}'
},
npmRebuild: false,
// --- AUTO-UPDATE ---
// electron-updater is wired in src/main/updater.ts (packaged builds only; silent
// download + install-on-next-quit; NSIS differential updates stay default-on).
// The production feed is the GitHub releases where the macOS beta channel lives.
// Local testing uses dev-app-update.yml + OMI_UPDATER_DEV=1 (forceDevUpdateConfig)
// instead of this feed. releaseType 'release' means only non-prerelease GitHub
// releases are served as updates.
//
// NOTE: this block is the UPDATE FEED only — it must never be used as an upload
// target. electron-builder auto-publishes to it when CI + a git tag are detected,
// so every build command must pass `--publish never` (build:win does; the release
// workflow uploads explicitly via `gh release` instead).
publish: [{ provider: 'github', owner: 'BasedHardware', repo: 'omi', releaseType: 'release' }]
}