Files
open-science/electron-builder.yml

273 lines
14 KiB
YAML

appId: com.aipoch.open-science
productName: Open-Science
copyright: Copyright © 2026 AIPOCH
directories:
buildResources: build
# Apply a valid deep ad-hoc signature on macOS (no Developer ID available). Without this,
# electron-builder ships an incompletely-signed bundle that Gatekeeper flags as "damaged"
# on downloaded/quarantined copies, so the app won't launch on other machines. See the hook.
afterPack: build/adhoc-sign.cjs
afterSign: build/sign-windows.cjs
files:
- '!**/.vscode/*'
# Agent/AI tooling state lives in the project (.claude holds git worktrees — full nested repo
# copies, easily >1GB — plus memory/logs; .codex is similar). electron-builder sweeps in everything
# under the project root by default, so without this it bundles all of that into app.asar, bloating
# the app to multiple GB AND leaking local agent state into the shipped bundle.
- '!.claude{,/**/*}'
- '!.codex{,/**/*}'
- '!**/{.worktree,.worktrees,.codegraph,.agents}{,/**/*}'
- '!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}'
- '!packages/open-science{,/**/*}'
- '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}'
# Prisma is shipped via extraResources (see below), not inside the asar. Exclude it here so that at
# runtime `require('@prisma/client')` resolves the real copy in Contents/Resources/node_modules
# (app.asar's parent dir) instead of a broken in-asar copy that can't find its generated `.prisma`
# client — which otherwise crashes the main process at startup with
# "Cannot find module '.prisma/client/default'" (window never opens; dock icon bounces and quits).
- '!node_modules/@prisma/client{,/**/*}'
- '!node_modules/.prisma{,/**/*}'
# The bundled Claude native binary (~220MB) is never executed: the app spawns the ACP agent with
# CLAUDE_CODE_EXECUTABLE pointing at the user's system-installed claude, and claude-agent-acp only
# resolves this optional platform package when that env var is unset. Excluding it drops ~220MB.
# Wildcard every platform variant (darwin-arm64/-x64, linux-*, win32-*) so the exclusion holds no
# matter which OS the release job builds on — npm only installs the one matching the build host.
- '!node_modules/@anthropic-ai/claude-agent-sdk-*{,/**/*}'
# The internal Notebook sandbox is bundled into the main process by electron-vite. Keep its
# vendored source/native trees out of app.asar; the executable resources are copied explicitly per
# platform below so path resolution and code signing remain deterministic.
- '!node_modules/@aipoch/notebook-network-sandbox{,/**/*}'
- '!packages/notebook-network-sandbox{,/**/*}'
# pdfjs-dist ships several redundant copies. The main process only loads `legacy/build` (text
# extraction) and needs `cmaps`/`standard_fonts` for CJK/CID PDFs; the renderer bundles its own
# copy via Vite. Drop the modern build, viewer, image decoders, TS types, and source maps
# (~16MB) so the packaged app carries only what runs.
- '!node_modules/pdfjs-dist/build{,/**/*}'
- '!node_modules/pdfjs-dist/web{,/**/*}'
- '!node_modules/pdfjs-dist/image_decoders{,/**/*}'
- '!node_modules/pdfjs-dist/types{,/**/*}'
- '!node_modules/pdfjs-dist/**/*.map'
# Micromamba is copied from this staging tree to the resources root by the platform-specific
# extraResources entries below. Keep the staging copies out of app.asar and avoid shipping a
# second, unused copy under app.asar.unpacked/resources/bin.
- '!resources/bin{,/**/*}'
asarUnpack:
- resources/**
- '!resources/bin{,/**/*}'
- node_modules/@aipoch/credential-identity-probe-native/build/Release/credential_*
- node_modules/@aipoch/process-tree-native/build/Release/*.node
- node_modules/@aipoch/safe-file-publisher-native/build/Release/*.node
# sharp loads its platform N-API binding and libvips shared libraries by physical path.
- node_modules/pdfjs-dist/**
- node_modules/@napi-rs/**
- node_modules/detect-libc/**
- node_modules/semver/**
- node_modules/sharp/**
- node_modules/@img/**
# The ACP agent runs as a spawned child process, so its entry must live outside the asar.
- node_modules/@agentclientprotocol/claude-agent-acp/**
# The Prisma generated client (`node_modules/.prisma`) is produced by `prisma generate` and is NOT a
# declared dependency, so electron-builder's node_modules collector never bundles it into the asar.
# It also loads a native query engine (.dylib.node) by path, which can't run from inside an asar. Ship
# the client + generated code as plain files under Contents/Resources/node_modules; Node's normal
# directory walk from app.asar finds them there. (@prisma/client v6 has zero runtime deps, so the
# client + .prisma pair is self-contained.)
# The micromamba binary is added per-platform below (mac/win/linux extraResources), not here, so
# the two extraResources lists don't collide.
extraResources:
# Keep the project license readable outside app.asar on every platform.
- from: LICENSE
to: LICENSE.txt
# Keep the copied third-party provider icon paths' MIT notice readable in every packaged app.
- from: src/renderer/src/assets/provider-icons/LobeHub-icons-LICENSE
to: LobeHub-icons-LICENSE
- from: node_modules/.prisma
to: node_modules/.prisma
- from: node_modules/@prisma/client
to: node_modules/@prisma/client
# Ship the `open-science` CLI as plain files (not in the asar) so the installed command-line launcher
# can run it with the app's own Electron in Node mode. Only the runtime .mjs files; tests are excluded.
- from: cli
to: cli
filter:
- '**/*.mjs'
- from: packages/open-science
to: packages/open-science
filter:
- '*.mjs'
- '*.d.ts'
- 'LICENSE'
- 'package.json'
# Windows: stable releases use Azure Artifact Signing; nightly and other builds remain unsigned.
# The afterSign hook supplements missing bundled PE signatures for Store submissions after
# electron-builder edits/signs the launcher. Existing helper/vendor signatures are preserved.
win:
# Windows ProgID is a persisted association identity; other platforms use a display name.
fileAssociations:
- ext: science
name: Open Science Session package
description: Open-Science Session package
mimeType: application/x-open-science-session
role: Viewer
rank: Default
executableName: open-science
icon: build/icon.ico
artifactName: aipoch-${name}-${version}-win-${arch}.${ext}
# AppContainer profiles and firewall rules require a product uninstaller, so Windows ships only
# through NSIS. A portable ZIP could be deleted without releasing those durable resources.
target:
- nsis
extraResources:
# Staged per-arch micromamba binary, copied to the resources root (Task 2's resolveMicromamba
# looks for it there via process.resourcesPath).
- from: resources/bin/win/${arch}/micromamba.exe
to: micromamba.exe
# A separately pinned final-1.x build gives the app an independently built runner when the
# primary executable cannot even pass `--version` on a particular Windows machine.
- from: resources/bin/win/${arch}/micromamba-compat.exe
to: micromamba-compat.exe
- from: build/windows-runtime-cache-uninstall.ps1
to: windows-runtime-cache-uninstall.ps1
- from: build/windows-notebook-sandbox-uninstall.ps1
to: windows-notebook-sandbox-uninstall.ps1
- from: packages/notebook-network-sandbox/vendor/windows/${arch}/notebook-appcontainer-host.exe
to: notebook-network-sandbox/windows/${arch}/notebook-appcontainer-host.exe
- from: packages/notebook-network-sandbox/vendor/wsl2/manifest.json
to: notebook-network-sandbox/wsl2/manifest.json
nsis:
artifactName: aipoch-${name}-${version}-win-${arch}-setup.${ext}
shortcutName: ${productName}
uninstallDisplayName: ${productName}
createDesktopShortcut: always
oneClick: false
# AppContainer profiles are per-user. The custom install-mode hook forces CurrentUser, while
# these options keep electron-builder from offering or internally preparing an elevation path.
perMachine: false
allowElevation: false
allowToChangeInstallationDirectory: true
license: LICENSE
include: build/installer-license.nsh
mac:
# Windows ProgID is a persisted association identity; other platforms use a display name.
fileAssociations:
- ext: science
name: Open-Science Session package
description: Open-Science Session package
mimeType: application/x-open-science-session
role: Viewer
rank: Default
# Compile the Icon Composer package into the app bundle (Assets.car + an ICNS fallback for
# pre-Tahoe macOS). This is intentionally separate from dmg.icon below: the mounted installer
# volume still uses the legacy, explicitly-designed ICNS artwork.
icon: build/icon.icon
darkModeSupport: true
artifactName: aipoch-${name}-${version}-mac-${arch}.${ext}
# Minimum macOS to run the app (written to Info.plist LSMinimumSystemVersion). macOS 12 (Monterey)
# and up; below this the OS refuses to launch. Independent of the CI build runner's macOS version.
minimumSystemVersion: '12.0.0'
entitlementsInherit: build/entitlements.mac.plist
extendInfo:
# Electron locates its Helper bundles using this internal name. Keep it aligned with productName.
CFBundleName: Open-Science
CFBundleDisplayName: Open-Science
NSCameraUsageDescription: Application requests access to the device's camera.
NSMicrophoneUsageDescription: Application requests access to the device's microphone.
NSDesktopFolderUsageDescription: Open-Science needs access to Desktop files to browse, open, and save your research files.
NSDocumentsFolderUsageDescription: Open-Science needs access to Documents files to browse, open, and save your research files.
NSDownloadsFolderUsageDescription: Open-Science needs access to Downloads files to browse, open, and save your research files.
NSNetworkVolumesUsageDescription: Open-Science needs access to network volumes to browse, open, and save your research files.
NSRemovableVolumesUsageDescription: Open-Science needs access to removable volumes to browse, open, and save your research files.
NSLocalNetworkUsageDescription: Open-Science needs local network access to connect to compute hosts and services you configure.
notarize: false
extraResources:
# Ship the ad-hoc-signed micromamba mach-O at Contents/Resources/micromamba, where
# resolveMicromamba() finds it via process.resourcesPath. Envs materialize in ~/.open-science
# (never in the signed .app), so only this one binary needs signing (spec §10).
- from: resources/bin/mac/${arch}/micromamba
to: micromamba
dmg:
title: Open-Science
background: build/dmg-background.png
iconSize: 88
iconTextSize: 12
contents:
- x: 130
y: 286
name: Open-Science.app
- x: 530
y: 286
type: link
path: /Applications
- x: 530
y: 75
type: file
path: LICENSE
name: LICENSE.txt
# The DMG volume icon does not consume the app's Icon Composer asset catalog. Keep the existing
# ICNS dedicated to the mounted disk image instead of electron-builder's generated app fallback.
icon: build/icon.icns
# Stable macOS releases require a primary signature on the outer DMG in addition to the signed app
# and notarization ticket. Nightly and certificate-free builds override this to false in build.yml.
sign: true
artifactName: aipoch-${name}-${version}-mac-${arch}.${ext}
linux:
# Windows ProgID is a persisted association identity; other platforms use a display name.
fileAssociations:
- ext: science
name: Open-Science Session package
description: Open-Science Session package
mimeType: application/x-open-science-session
role: Viewer
rank: Default
# Keep the installed launcher filename aligned with Electron's Linux app_id/WM_CLASS so desktop
# environments associate urgency requests with the existing dock/taskbar entry.
syncDesktopName: true
# snap is intentionally omitted: building it on a stock GitHub runner needs snapcraft + LXD and
# is flaky in CI. AppImage (portable, runs anywhere) + deb (Debian/Ubuntu) cover the common cases.
target:
- AppImage
- deb
maintainer: aipoch
category: Utility
extraResources:
# Staged per-arch micromamba binary, copied to the resources root (Task 2's resolveMicromamba
# looks for it there via process.resourcesPath).
- from: resources/bin/linux/${arch}/micromamba
to: micromamba
# Debian registers this CLI entry; AppImage retains its explicit user launcher workflow.
- from: build/deb-cli-launcher
to: open-science-cli
appImage:
artifactName: aipoch-${name}-${version}-linux-${arch}.${ext}
deb:
fpm:
- build/deb-copyright=/usr/share/doc/open-science/copyright
afterInstall: build/deb-after-install.tpl
afterRemove: build/deb-after-remove.tpl
artifactName: aipoch-${name}_${version}_${arch}.${ext}
depends:
- libgtk-3-0
- libnotify4
- libnss3
- libxss1
- libxtst6
- xdg-utils
- libatspi2.0-0
- libuuid1
- libsecret-1-0
- bubblewrap
npmRebuild: false
# electron-updater feed. Win/Linux/macOS auto-update reads app-update.yml (generated from this block)
# and fetches its feed from <url>. Each installed app uses the default latest channel. macOS
# builds preserve uniquely named per-arch feed artifacts; release.yml merges them into latest-mac.yml
# after optional notarization. --publish never means this configuration does not upload anything.
publish:
provider: generic
url: https://statics.aipoch.com/open-science/app/stable
channel: latest
electronDownload:
mirror: https://npmmirror.com/mirrors/electron/