use pnpm for Desktop Electron App (#7679)

This commit is contained in:
Lifei Zhou
2026-03-11 08:46:05 -04:00
committed by GitHub
parent a28c306b23
commit 02bc7ed745
20 changed files with 13856 additions and 21417 deletions
+4 -1
View File
@@ -1 +1,4 @@
registry=https://registry.npmjs.org/
registry=https://registry.npmjs.org/
node-linker=hoisted
supportedArchitectures.os=current,linux,darwin,win32
supportedArchitectures.cpu=current,x64,arm64
+8 -8
View File
@@ -10,8 +10,8 @@ git clone git@github.com:block/goose.git
cd goose
source ./bin/activate-hermit
cd ui/desktop
npm install
npm run start
pnpm install
pnpm run start
```
## Platform-specific build requirements
@@ -41,9 +41,9 @@ This is an electron forge app, using vite and react.js. `goosed` runs as multi p
## Building for different platforms
### macOS
`npm run bundle:default` will give you a goose.app/zip which is signed/notarized but only if you set up the env vars as per `forge.config.ts` (you can empty out the section on osxSign if you don't want to sign it) - this will have all defaults.
`pnpm run bundle:default` will give you a goose.app/zip which is signed/notarized but only if you set up the env vars as per `forge.config.ts` (you can empty out the section on osxSign if you don't want to sign it) - this will have all defaults.
`npm run bundle:preconfigured` will make a goose.app/zip signed and notarized, but use the following:
`pnpm run bundle:preconfigured` will make a goose.app/zip signed and notarized, but use the following:
```python
f" process.env.GOOSE_PROVIDER__TYPE = '{os.getenv("GOOSE_BUNDLE_TYPE")}';",
@@ -71,13 +71,13 @@ cp ../../target/release/goosed src/bin/
3. Build the application:
```bash
# For ZIP distribution (works on all Linux distributions)
npm run make -- --targets=@electron-forge/maker-zip
pnpm run make -- --targets=@electron-forge/maker-zip
# For DEB package (Debian/Ubuntu)
npm run make -- --targets=@electron-forge/maker-deb
pnpm run make -- --targets=@electron-forge/maker-deb
# For Flatpak (requires flatpak and flatpak-builder)
npm run make -- --targets=@electron-forge/maker-flatpak
pnpm run make -- --targets=@electron-forge/maker-flatpak
```
The built application will be available in:
@@ -94,5 +94,5 @@ Use the existing Windows build process as documented.
Set `VITE_START_EMBEDDED_SERVER=yes` to no in `.env`.
Run `cargo run -p goose-server` from parent dir.
`npm run start` will then run against this.
`pnpm run start` will then run against this.
You can try server directly with `./test.sh`
-21277
View File
File diff suppressed because it is too large Load Diff
+29 -21
View File
@@ -5,30 +5,30 @@
"description": "Goose App",
"engines": {
"node": "^24.10.0",
"npm": "^11.6.1"
"pnpm": ">=10.30.0"
},
"main": ".vite/build/main.js",
"scripts": {
"typecheck": "tsc --noEmit",
"generate-api": "openapi-ts",
"start-gui": "npm run generate-api && electron-forge start",
"start-gui-debug": "npm run generate-api && electron-forge start -- --inspect=9229",
"start-gui": "pnpm run generate-api && electron-forge start",
"start-gui-debug": "pnpm run generate-api && electron-forge start -- --inspect=9229",
"start": "cd ../.. && just run-ui",
"start:test-error": "GOOSE_TEST_ERROR=true electron-forge start",
"package": "electron-forge package",
"make": "electron-forge make",
"bundle:default": "node scripts/prepare-platform-binaries.js && npm run make && BUNDLE_NAME=\"${GOOSE_BUNDLE_NAME:-Goose}\" && APP_DIR=\"out/${BUNDLE_NAME}-darwin-arm64\" && APP_BUNDLE=\"${APP_DIR}/${BUNDLE_NAME}.app\" && (cd \"$APP_DIR\" && ditto -c -k --sequesterRsrc --keepParent \"${BUNDLE_NAME}.app\" \"${BUNDLE_NAME}.zip\") || echo \"${APP_BUNDLE} not found; either the binary is not built or you are not on macOS\"",
"bundle:alpha": "ALPHA=true node scripts/prepare-platform-binaries.js && ALPHA=true npm run make && BUNDLE_NAME=\"${GOOSE_BUNDLE_NAME:-Goose}\" && APP_DIR=\"out/${BUNDLE_NAME}-darwin-arm64\" && APP_BUNDLE=\"${APP_DIR}/${BUNDLE_NAME}.app\" && (cd \"$APP_DIR\" && ditto -c -k --sequesterRsrc --keepParent \"${BUNDLE_NAME}.app\" \"${BUNDLE_NAME}_alpha.zip\") || echo \"${APP_BUNDLE} not found; either the binary is not built or you are not on macOS\"",
"bundle:intel": "node scripts/prepare-platform-binaries.js && npm run make -- --arch=x64 && BUNDLE_NAME=\"${GOOSE_BUNDLE_NAME:-Goose}\" && APP_DIR=\"out/${BUNDLE_NAME}-darwin-x64\" && APP_BUNDLE=\"${APP_DIR}/${BUNDLE_NAME}.app\" && (cd \"$APP_DIR\" && ditto -c -k --sequesterRsrc --keepParent \"${BUNDLE_NAME}.app\" \"${BUNDLE_NAME}_intel_mac.zip\")",
"bundle:default": "node scripts/prepare-platform-binaries.js && pnpm run make && BUNDLE_NAME=\"${GOOSE_BUNDLE_NAME:-Goose}\" && APP_DIR=\"out/${BUNDLE_NAME}-darwin-arm64\" && APP_BUNDLE=\"${APP_DIR}/${BUNDLE_NAME}.app\" && (cd \"$APP_DIR\" && ditto -c -k --sequesterRsrc --keepParent \"${BUNDLE_NAME}.app\" \"${BUNDLE_NAME}.zip\") || echo \"${APP_BUNDLE} not found; either the binary is not built or you are not on macOS\"",
"bundle:alpha": "ALPHA=true node scripts/prepare-platform-binaries.js && ALPHA=true pnpm run make && BUNDLE_NAME=\"${GOOSE_BUNDLE_NAME:-Goose}\" && APP_DIR=\"out/${BUNDLE_NAME}-darwin-arm64\" && APP_BUNDLE=\"${APP_DIR}/${BUNDLE_NAME}.app\" && (cd \"$APP_DIR\" && ditto -c -k --sequesterRsrc --keepParent \"${BUNDLE_NAME}.app\" \"${BUNDLE_NAME}_alpha.zip\") || echo \"${APP_BUNDLE} not found; either the binary is not built or you are not on macOS\"",
"bundle:intel": "node scripts/prepare-platform-binaries.js && pnpm run make -- --arch=x64 && BUNDLE_NAME=\"${GOOSE_BUNDLE_NAME:-Goose}\" && APP_DIR=\"out/${BUNDLE_NAME}-darwin-x64\" && APP_BUNDLE=\"${APP_DIR}/${BUNDLE_NAME}.app\" && (cd \"$APP_DIR\" && ditto -c -k --sequesterRsrc --keepParent \"${BUNDLE_NAME}.app\" \"${BUNDLE_NAME}_intel_mac.zip\")",
"debug": "echo 'run --remote-debugging-port=8315' && BUNDLE_NAME=\"${GOOSE_BUNDLE_NAME:-Goose}\" && lldb \"out/${BUNDLE_NAME}-darwin-arm64/${BUNDLE_NAME}.app\"",
"test-e2e": "npm run generate-api && playwright test",
"test-e2e:dev": "npm run generate-api && playwright test --reporter=list --retries=0 --max-failures=1",
"test-e2e:ui": "npm run generate-api && playwright test --ui",
"test-e2e:debug": "npm run generate-api && playwright test --debug",
"test-e2e": "pnpm run generate-api && playwright test",
"test-e2e:dev": "pnpm run generate-api && playwright test --reporter=list --retries=0 --max-failures=1",
"test-e2e:ui": "pnpm run generate-api && playwright test --ui",
"test-e2e:debug": "pnpm run generate-api && playwright test --debug",
"test-e2e:report": "playwright show-report",
"test-e2e:single": "npm run generate-api && playwright test -g",
"test-e2e:single": "pnpm run generate-api && playwright test -g",
"lint": "eslint \"src/**/*.{ts,tsx}\" --fix --no-warn-ignored",
"lint:check": "npm run typecheck && eslint \"src/**/*.{ts,tsx}\" --max-warnings 0 --no-warn-ignored",
"lint:check": "pnpm run typecheck && eslint \"src/**/*.{ts,tsx}\" --max-warnings 0 --no-warn-ignored",
"format": "prettier --write \"src/**/*.{ts,tsx,css,json}\"",
"format:check": "prettier --check \"src/**/*.{ts,tsx,css,json}\"",
"test": "vitest",
@@ -39,10 +39,9 @@
"test:integration:watch": "vitest --config vitest.integration.config.ts",
"test:integration:debug": "DEBUG=1 vitest run --config vitest.integration.config.ts",
"prepare": "husky",
"start-alpha-gui": "ALPHA=true npm run start-gui"
"start-alpha-gui": "ALPHA=true pnpm run start-gui"
},
"dependencies": {
"goose-acp-types": "file:../acp",
"@mcp-ui/client": "^6.1.0",
"@modelcontextprotocol/ext-apps": "^1.1.1",
"@radix-ui/react-accordion": "^1.2.12",
@@ -56,7 +55,7 @@
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/themes": "^3.3.0",
"@tanstack/react-form": "1.28.3",
"@tanstack/react-form": "^1.28.3",
"@types/react-router-dom": "^5.3.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
@@ -71,7 +70,8 @@
"electron-window-state": "^5.0.3",
"express": "^5.2.1",
"framer-motion": "^12.34.3",
"katex": "0.16.33",
"goose-acp-types": "file:../acp",
"katex": "^0.16.33",
"lodash": "^4.17.23",
"lucide-react": "^0.575.0",
"qrcode.react": "^4.2.0",
@@ -110,7 +110,7 @@
"@electron/fuses": "^1.8.0",
"@electron/remote": "^2.1.3",
"@eslint/js": "^9.39.2",
"@hey-api/openapi-ts": "0.93.0",
"@hey-api/openapi-ts": "^0.93.0",
"@modelcontextprotocol/sdk": "^1.27.0",
"@playwright/test": "^1.58.2",
"@tailwindcss/line-clamp": "^0.4.4",
@@ -152,13 +152,21 @@
},
"keywords": [],
"license": "Apache-2.0",
"overrides": {
"react": "^19.2.4",
"react-dom": "^19.2.4"
"pnpm": {
"overrides": {
"react": "^19.2.4",
"react-dom": "^19.2.4"
},
"onlyBuiltDependencies": [
"@modelcontextprotocol/ext-apps",
"electron",
"electron-winstaller",
"esbuild"
]
},
"lint-staged": {
"src/**/*.{ts,tsx}": [
"bash -c 'npm run typecheck'",
"bash -c 'pnpm run typecheck'",
"eslint --fix --max-warnings 0 --no-warn-ignored",
"prettier --write"
],
+13733
View File
File diff suppressed because it is too large Load Diff
@@ -1,30 +0,0 @@
#!/usr/bin/env bash
# Verify package-lock.json has cross-platform optional dependency entries.
#
# npm has a bug where running `npm install` with an existing node_modules/
# prunes platform-specific entries from the lockfile, breaking CI on other platforms.
# See: https://github.com/npm/cli/issues/4828
#
set -euo pipefail
LOCKFILE="${1:-package-lock.json}"
fail=0
grep -q '"node_modules/@esbuild/win32-x64"' "$LOCKFILE" || { echo "MISSING: @esbuild/win32-x64"; fail=1; }
grep -q '"node_modules/@esbuild/linux-x64"' "$LOCKFILE" || { echo "MISSING: @esbuild/linux-x64"; fail=1; }
if [ "$fail" -eq 1 ]; then
echo ""
echo "ERROR: package-lock.json is missing cross-platform optional dependencies."
echo "This happens when 'npm install' is run with an existing node_modules/ directory."
echo ""
echo "To fix, run from ui/desktop/:"
echo " rm -rf node_modules package-lock.json"
echo " npm install"
echo ""
echo "Then commit the regenerated package-lock.json."
exit 1
fi
echo "OK: package-lock.json has cross-platform entries"
+1 -1
View File
@@ -42,7 +42,7 @@ export const test = base.extend<GooseTestFixtures>({
// Start the electron-forge process with Playwright remote debugging enabled
// Use detached mode on Unix to create a process group we can kill together
appProcess = spawn('npm', ['run', 'start-gui'], {
appProcess = spawn('pnpm', ['run', 'start-gui'], {
cwd: join(__dirname, '../..'),
stdio: 'pipe',
detached: process.platform !== 'win32',