Add Darwin desktop package to flake
This commit is contained in:
@@ -21,6 +21,19 @@ Root checkout dev is intentionally split across terminals:
|
|||||||
|
|
||||||
`npm run dev` is only a shorthand for `npm run dev:server`. Keep `127.0.0.1:6767` for the packaged app and production-style `~/.paseo` state.
|
`npm run dev` is only a shorthand for `npm run dev:server`. Keep `127.0.0.1:6767` for the packaged app and production-style `~/.paseo` state.
|
||||||
|
|
||||||
|
## Nix desktop package
|
||||||
|
|
||||||
|
The flake exposes `packages.<system>.desktop` on Linux and macOS:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix build .#desktop
|
||||||
|
```
|
||||||
|
|
||||||
|
Linux produces the `paseo-desktop` launcher and desktop entry. macOS produces
|
||||||
|
`Applications/Paseo.app` plus the `paseo-desktop` launcher. Both use the nixpkgs
|
||||||
|
Electron runtime and the checkout's built daemon, client, and renderer rather
|
||||||
|
than downloading a published desktop release.
|
||||||
|
|
||||||
### PASEO_HOME
|
### PASEO_HOME
|
||||||
|
|
||||||
`PASEO_HOME` is the directory that holds runtime state (agents, worktrees, workspace config, sockets, daemon log). Resolution rules:
|
`PASEO_HOME` is the directory that holds runtime state (agents, worktrees, workspace config, sockets, daemon log). Resolution rules:
|
||||||
|
|||||||
@@ -26,16 +26,10 @@
|
|||||||
let
|
let
|
||||||
pkgs = pkgsFor system;
|
pkgs = pkgsFor system;
|
||||||
paseo = pkgs.callPackage ./nix/package.nix { };
|
paseo = pkgs.callPackage ./nix/package.nix { };
|
||||||
isLinux = nixpkgs.lib.elem system [
|
|
||||||
"x86_64-linux"
|
|
||||||
"aarch64-linux"
|
|
||||||
];
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
default = paseo;
|
default = paseo;
|
||||||
paseo = paseo;
|
paseo = paseo;
|
||||||
}
|
|
||||||
// nixpkgs.lib.optionalAttrs isLinux {
|
|
||||||
desktop = pkgs.callPackage ./nix/desktop-package.nix { inherit paseo; };
|
desktop = pkgs.callPackage ./nix/desktop-package.nix { inherit paseo; };
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
+76
-16
@@ -17,9 +17,47 @@
|
|||||||
paseo,
|
paseo,
|
||||||
}:
|
}:
|
||||||
|
|
||||||
buildNpmPackage rec {
|
let
|
||||||
pname = "paseo-desktop";
|
|
||||||
version = (builtins.fromJSON (builtins.readFile ../package.json)).version;
|
version = (builtins.fromJSON (builtins.readFile ../package.json)).version;
|
||||||
|
darwinInfoPlist = builtins.toFile "Paseo-Info.plist" (
|
||||||
|
lib.generators.toPlist { escape = true; } {
|
||||||
|
CFBundleDisplayName = "Paseo";
|
||||||
|
CFBundleExecutable = "Paseo";
|
||||||
|
CFBundleIconFile = "Paseo.icns";
|
||||||
|
CFBundleIdentifier = "sh.paseo.desktop";
|
||||||
|
CFBundleInfoDictionaryVersion = "6.0";
|
||||||
|
CFBundleName = "Paseo";
|
||||||
|
CFBundlePackageType = "APPL";
|
||||||
|
CFBundleShortVersionString = version;
|
||||||
|
CFBundleURLTypes = [
|
||||||
|
{
|
||||||
|
CFBundleURLName = "Paseo agent link";
|
||||||
|
CFBundleURLSchemes = [ "paseo" ];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
CFBundleVersion = version;
|
||||||
|
LSApplicationCategoryType = "public.app-category.developer-tools";
|
||||||
|
LSEnvironment.MallocNanoZone = "0";
|
||||||
|
LSMinimumSystemVersion = "12.0";
|
||||||
|
NSAppTransportSecurity.NSAllowsArbitraryLoads = true;
|
||||||
|
NSAudioCaptureUsageDescription = "Paseo needs access to audio capture for voice input.";
|
||||||
|
NSBluetoothAlwaysUsageDescription = "Paseo needs access to Bluetooth audio devices.";
|
||||||
|
NSBluetoothPeripheralUsageDescription = "Paseo needs access to Bluetooth audio devices.";
|
||||||
|
NSCameraUsageDescription = "Paseo needs access to the camera for image attachments.";
|
||||||
|
NSHighResolutionCapable = true;
|
||||||
|
NSMainNibFile = "MainMenu";
|
||||||
|
NSMicrophoneUsageDescription = "Paseo needs access to the microphone for voice input.";
|
||||||
|
NSPrefersDisplaySafeAreaCompatibilityMode = false;
|
||||||
|
NSPrincipalClass = "AtomApplication";
|
||||||
|
NSQuitAlwaysKeepsWindows = false;
|
||||||
|
NSRequiresAquaSystemAppearance = false;
|
||||||
|
NSSupportsAutomaticGraphicsSwitching = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
in
|
||||||
|
buildNpmPackage {
|
||||||
|
pname = "paseo-desktop";
|
||||||
|
inherit version;
|
||||||
|
|
||||||
src = lib.cleanSourceWith {
|
src = lib.cleanSourceWith {
|
||||||
src = ./..;
|
src = ./..;
|
||||||
@@ -66,13 +104,14 @@ buildNpmPackage rec {
|
|||||||
# npm rebuild. We manually rebuild only node-pty in buildPhase.
|
# npm rebuild. We manually rebuild only node-pty in buildPhase.
|
||||||
npmRebuildFlags = [ "--ignore-scripts" ];
|
npmRebuildFlags = [ "--ignore-scripts" ];
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs =
|
||||||
|
[
|
||||||
python3 # for node-gyp (node-pty)
|
python3 # for node-gyp (node-pty)
|
||||||
makeWrapper
|
makeWrapper
|
||||||
copyDesktopItems
|
|
||||||
]
|
]
|
||||||
++ lib.optionals stdenv.hostPlatform.isLinux [
|
++ lib.optionals stdenv.hostPlatform.isLinux [
|
||||||
autoPatchelfHook
|
autoPatchelfHook
|
||||||
|
copyDesktopItems
|
||||||
];
|
];
|
||||||
|
|
||||||
buildInputs = lib.optionals stdenv.hostPlatform.isLinux [
|
buildInputs = lib.optionals stdenv.hostPlatform.isLinux [
|
||||||
@@ -153,31 +192,52 @@ buildNpmPackage rec {
|
|||||||
cp -a skills $out/share/paseo-desktop/
|
cp -a skills $out/share/paseo-desktop/
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
${lib.optionalString stdenv.hostPlatform.isLinux ''
|
||||||
# Hicolor icon for desktop environments
|
# Hicolor icon for desktop environments
|
||||||
install -Dm644 packages/desktop/assets/icon.png \
|
install -Dm644 packages/desktop/assets/icon.png \
|
||||||
$out/share/icons/hicolor/512x512/apps/paseo-desktop.png
|
$out/share/icons/hicolor/512x512/apps/paseo-desktop.png
|
||||||
|
|
||||||
# Launcher wraps nixpkgs electron.
|
# Chromium's setuid sandbox cannot live in the immutable Nix store.
|
||||||
# --no-sandbox: Chromium's setuid sandbox can't live in /nix/store
|
|
||||||
# (immutable, no setuid). Acceptable for v1; a follow-up can wire
|
|
||||||
# `security.wrappers` via a NixOS module for users who want the sandbox.
|
|
||||||
#
|
|
||||||
# EXPO_DEV_URL: We run unpackaged via `electron path/to/main.js`, so
|
|
||||||
# `app.isPackaged` is false. In that mode main.ts loads `DEV_SERVER_URL`
|
|
||||||
# (defaults to http://localhost:8081 — the Expo dev server, which doesn't
|
|
||||||
# exist here). Point it at the `paseo://` protocol handler instead, which
|
|
||||||
# serves from `__dirname/../../app/dist` (our install layout matches).
|
|
||||||
makeWrapper ${electron}/bin/electron $out/bin/paseo-desktop \
|
makeWrapper ${electron}/bin/electron $out/bin/paseo-desktop \
|
||||||
--add-flags "$out/share/paseo-desktop/packages/desktop/dist/main.js" \
|
--add-flags "$out/share/paseo-desktop/packages/desktop/dist/main.js" \
|
||||||
--add-flags "--no-sandbox" \
|
--add-flags "--no-sandbox" \
|
||||||
--set EXPO_DEV_URL "paseo://app/"
|
--set EXPO_DEV_URL "paseo://app/"
|
||||||
|
|
||||||
copyDesktopItems
|
copyDesktopItems
|
||||||
|
''}
|
||||||
|
|
||||||
|
${lib.optionalString stdenv.hostPlatform.isDarwin ''
|
||||||
|
app="$out/Applications/Paseo.app"
|
||||||
|
mkdir -p "$app/Contents/MacOS" "$app/Contents/Resources"
|
||||||
|
|
||||||
|
# Reuse nixpkgs' Electron framework through store symlinks so the Paseo
|
||||||
|
# output stays small while still presenting a normal application bundle
|
||||||
|
# to LaunchServices.
|
||||||
|
ln -s ${electron}/Applications/Electron.app/Contents/Frameworks \
|
||||||
|
"$app/Contents/Frameworks"
|
||||||
|
ln -s ${electron}/Applications/Electron.app/Contents/MacOS/Electron \
|
||||||
|
"$app/Contents/MacOS/Electron"
|
||||||
|
for resource in ${electron}/Applications/Electron.app/Contents/Resources/*; do
|
||||||
|
ln -s "$resource" "$app/Contents/Resources/$(basename "$resource")"
|
||||||
|
done
|
||||||
|
|
||||||
|
cp ${darwinInfoPlist} "$app/Contents/Info.plist"
|
||||||
|
cp ${electron}/Applications/Electron.app/Contents/PkgInfo "$app/Contents/PkgInfo"
|
||||||
|
cp packages/desktop/assets/icon.icns "$app/Contents/Resources/Paseo.icns"
|
||||||
|
|
||||||
|
# Keep the same unpackaged runtime layout as the Linux Nix package. The
|
||||||
|
# outer .app supplies native macOS identity, icon, and URL handling while
|
||||||
|
# the wrapper points Electron at the immutable built main process.
|
||||||
|
makeWrapper "$app/Contents/MacOS/Electron" "$app/Contents/MacOS/Paseo" \
|
||||||
|
--add-flags "$out/share/paseo-desktop/packages/desktop/dist/main.js" \
|
||||||
|
--set EXPO_DEV_URL "paseo://app/"
|
||||||
|
ln -s ../Applications/Paseo.app/Contents/MacOS/Paseo "$out/bin/paseo-desktop"
|
||||||
|
''}
|
||||||
|
|
||||||
runHook postInstall
|
runHook postInstall
|
||||||
'';
|
'';
|
||||||
|
|
||||||
desktopItems = [
|
desktopItems = lib.optionals stdenv.hostPlatform.isLinux [
|
||||||
(makeDesktopItem {
|
(makeDesktopItem {
|
||||||
name = "paseo-desktop";
|
name = "paseo-desktop";
|
||||||
desktopName = "Paseo";
|
desktopName = "Paseo";
|
||||||
@@ -195,6 +255,6 @@ buildNpmPackage rec {
|
|||||||
homepage = "https://github.com/getpaseo/paseo";
|
homepage = "https://github.com/getpaseo/paseo";
|
||||||
license = lib.licenses.agpl3Plus;
|
license = lib.licenses.agpl3Plus;
|
||||||
mainProgram = "paseo-desktop";
|
mainProgram = "paseo-desktop";
|
||||||
platforms = lib.platforms.linux;
|
platforms = lib.platforms.linux ++ lib.platforms.darwin;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user