packaging-release
Skill9 starsChanged 4 days agoMITView on GitHub
Packaging and release patterns: pnpm/Electron install quirks, native binaries and asarUnpack, single instance per userData, the generated walph launcher, auto update with electron-updater and the per-OS release workflow. Use when changing package.json dependencies, electron-builder.yml, electron.vite.config.ts, src/main/index.ts startup, ipc/cli.ts, ipc/update.ts or the release pipeline.
- Reads credentials
In this repository17 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- app-testingSkill
- claude-panelSkill
- commands-settingsSkill
- containersSkill
- debuggerSkill
- files-git-searchSkill
- i18nSkill
- lspSkill
- main-ipcSkill
- main-processesSkill
- renderer-componentsSkill
- renderer-editorSkill
- renderer-storeSkill
- renderer-stylesSkill
- renderer-terminalSkill
- workspacesSkill
The file
We split this skill into the rules it gives an agent
1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 8
Run /release to ship; pnpm dist builds the installer for the current OS into dist/.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Packaging and release
Run /release to ship; pnpm dist builds the installer for the current OS into dist/.
Install and dependencies
- Electron 45 doesn't download its binary on install:
postinstallrunsinstall-electron. - pnpm (
packageManagerpinned):pnpm-workspace.yamlsetsnodeLinker: hoisted(flatnode_moduleslike npm; electron-builder andasarUnpackexpect it) andallowBuilds. A new dependency with install scripts is ignored until it's approved there (pnpm approve-builds). Never commit apackage-lock.json. - ESM-only deps in main that break with
requiremust be bundled viamain.build.externalizeDeps.excludeinelectron.vite.config.ts(none today). - Renderer-only packages (CodeMirror,
emmet,@emmetio/html-matcher) are bundled by Vite and live indevDependencies; only what main loads at runtime goes independencies.emmet'sexportshas notypes, sotsconfig.web.jsonmaps it inpathstonode_modules/emmet/dist/index.d.ts. @types/nodefollows the Node bundled by Electron (Electron 45 = Node 24.x, so the^24major), not the latest major.- Bumping
@codemirror/*can leave nested copies of@codemirror/view(typecheck fails with "separate declarations of a private property"): runpnpm dedupe, then reinstall and delete the*.tsbuildinfofiles. - Native binaries (node-pty, ripgrep, the Claude CLI) must be listed in
asarUnpackinelectron-builder.yml. - electron-builder always drops
*.d.ts(and otherexcludedExts) fromnode_modules; afilespattern can't bring them back, only theonNodeModuleFilehook (scripts/keep-tsserver-libs.mjskeeps the tsserverlib.*.d.ts; without them every built-in type is missing).e2e/packaged.spec.tschecks they are packaged.
Packaging
- The app is single-instance per userData (
requestSingleInstanceLockinindex.ts): a second launch forwards its argv tosecond-instance(Chromium injects flags BEFORE the script path in unpackaged runs;folderFromArgvdrops flags, then skips the entry) and exits; this is what makeswalph .open the folder in the running app. - Unpackaged runs without
--user-data-diruse<appData>/Walph-dev(the installed app keepsWalph). - The packaged app (macOS/Linux) merges the login-shell PATH into
process.env.PATHbefore restoring windows (env/loginPath.ts, 2 s cap, applied later if slower). - The
walphlauncher (cli/launcherScript.ts,ipc/cli.ts) is a GENERATED script with a marker embedding the executable path ($APPIMAGEon Linux); a file without the marker is never overwritten without confirmation nor removed; macOS admin writes go throughosascriptwith paths as argv; installing from a DMG/translocated path is refused. - Auto update (
ipc/update.ts,electron-updaterloaded lazily) exists only when packaged with the user-onlyupdate.enabled/update.channel;update:installarms a flag and callsapp.quit()(the dirty guard can veto;onQuitCancelledclears the flag) andquitAndInstall(true, true)runs inwill-quit. - Setting
autoUpdater.channelforcesallowDowngrade = true; reset it. - Native binaries of other platforms/arches don't get bundled: each OS is built on its own runner (
release.yml, draft created once, then published). The draft job first waits for the tag commit'sci.ymlrun and fails unless it issuccess(it filters--event push, so the nightly runs never count); theci.ymlunit jobs on macOS/Windows also runpnpm build. ci.ymllayout:check(typecheck, lint, knip, docs, coverage with thresholds),e2e-linux(3 Playwright shards),unit(macOS/Windowspnpm test+pnpm build); nightly andworkflow_dispatchadde2e-desktop(full E2E on macOS/Windows) andpackaged(electron-builder --linux --dir+e2e/packaged.spec.ts). Shared setup lives in.github/actions/setup/action.yml(electron-display: 'true'for Linux jobs that open the app). The concurrency group includes the event name so a nightly run never cancels the push run the release gate needs.- Tests of the packaged app:
WALPH_PACKAGED_EXE=<exe> pnpm exec playwright test e2e/packaged.spec.ts.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

