diff --git a/apps/desktop/electron-builder.base.yml b/apps/desktop/electron-builder.base.yml index 3c9e1ee084..b9f25ab066 100644 --- a/apps/desktop/electron-builder.base.yml +++ b/apps/desktop/electron-builder.base.yml @@ -9,8 +9,20 @@ files: - package.json # The staged copy below is compiled JavaScript; leave the checkout's source out. - "!node_modules/@openwork/types/{src,tsconfig*.json,tsup.config.ts}" + # The Swift helper ships under helpers; its build cache is checkout-only. + - "!node_modules/@openwork/computer-use/native/.build" + # Only a debugger or a compiler reads these, and nothing here runs one. + # The staged copy below repeats each rule so it cannot bring them back. + - &noSourceMaps "!**/*.{js,cjs,mjs,ts,cts,mts}.map" + - &noTypeDeclarations "!**/*.d.{ts,cts,mts}" + # Computer use transpiles scripts with lib/typescript.js alone. The compiler + # command, language server and translated messages are never loaded. + - &noTypeScriptTools "!**/typescript/{bin,lib/!(typescript.js)}" + # SQLite loads its prebuilt binary; the C sources only compile one. + - "!**/better-sqlite3/{deps,src}" - from: .electron-runtime/node_modules to: node_modules + filter: ["**/*", *noSourceMaps, *noTypeDeclarations, *noTypeScriptTools] extraResources: - from: .electron-runtime/openwork-sentry.json to: openwork-sentry.json diff --git a/apps/desktop/scripts/electron-after-pack.cjs b/apps/desktop/scripts/electron-after-pack.cjs index 5b00271555..3f6830f6e5 100644 --- a/apps/desktop/scripts/electron-after-pack.cjs +++ b/apps/desktop/scripts/electron-after-pack.cjs @@ -99,6 +99,24 @@ function verifyRuntimeDependencies(context) { } } verifyCompiledTypes(appAsarPath, packagedFiles); + verifyUnusedDependencyFiles(packagedFiles); +} + +// The packaging filters leave out dependency files that only a debugger or a +// compiler reads. Fail the package if they return, or if the filters take the +// one TypeScript file computer use imports. +function verifyUnusedDependencyFiles(packagedFiles) { + const typescript = "/node_modules/typescript"; + if (packagedFiles.has(`${typescript}/package.json`) && !packagedFiles.has(`${typescript}/lib/typescript.js`)) { + throw new Error("Packaged TypeScript is missing lib/typescript.js, which computer use imports."); + } + const unused = [...packagedFiles].filter((entry) => + /\.[cm]?[jt]s\.map$|\.d\.[cm]?ts$/.test(entry) + || /\/typescript\/(?:bin|lib\/(?!typescript\.js$)[^/]+)(?:\/|$)/.test(entry) + || /\/better-sqlite3\/(?:deps|src)(?:\/|$)/.test(entry)); + if (unused.length > 0) { + throw new Error(`Packaged app.asar ships files the app never loads: ${unused.slice(0, 5).join(", ")}`); + } } // The app loads @openwork/types as plain Node, which refuses TypeScript under @@ -209,4 +227,5 @@ module.exports = afterPack; module.exports.default = afterPack; module.exports.normalizeAsarEntryPath = normalizeAsarEntryPath; module.exports.verifyCompiledTypes = verifyCompiledTypes; +module.exports.verifyUnusedDependencyFiles = verifyUnusedDependencyFiles; module.exports.canonicalizeSidecars = canonicalizeSidecars;