From bf98102714ecf8b3a594604ff7b62fc5c2c80b43 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Wed, 29 Jul 2026 01:07:05 +0200 Subject: [PATCH] feat(packaging): ship `punktfunk` everywhere, and deprecate the session's stray pairing flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rest of C1. A CLI that only exists in a dev tree is not a door anyone can use, so it now builds and installs in deb, rpm, arch, nix, flatpak and MSIX alongside the client and the session. On Windows it gets its own `AppListEntry="none"` application with the alias `punktfunk.exe` — a command, not a Start-menu tile — which is what the Playnite importer will shell to for `punktfunk library --json`. `punktfunk-session --pair` prints a deprecation notice and forwards. Pairing is a trust ceremony and belongs to the brain, fronted by `punktfunk pair` or a shell; a renderer owning one is precisely the mixing of concerns this split exists to undo. It keeps working for a release, because someone's provisioning script is calling it today. Decky's invocations are untouched and verified still working (`--list-hosts` JSON shape unchanged, `--reachable` exit codes unchanged): those flags are a frozen compat contract until Decky migrates to the verbs at its own pace. Co-Authored-By: Claude Opus 5 (1M context) --- clients/session/src/main.rs | 12 +++++++++--- clients/windows/packaging/AppxManifest.xml | 21 +++++++++++++++++++++ clients/windows/packaging/pack-msix.ps1 | 2 +- packaging/arch/PKGBUILD | 7 +++++-- packaging/debian/build-client-deb.sh | 5 ++++- packaging/flatpak/io.unom.Punktfunk.yml | 4 ++++ packaging/nix/packages.nix | 2 +- packaging/rpm/punktfunk.spec | 7 +++++-- 8 files changed, 50 insertions(+), 10 deletions(-) diff --git a/clients/session/src/main.rs b/clients/session/src/main.rs index aec0d583..a1706cd9 100644 --- a/clients/session/src/main.rs +++ b/clients/session/src/main.rs @@ -400,10 +400,16 @@ mod session_main { }; } - // `--pair `: enrol this machine against a host and exit. Sits with the other - // non-streaming subcommands, above every graphics call — the box doing this may have - // no display at all. + // `--pair `: enrol this machine against a host and exit. DEPRECATED — pairing is + // a trust ceremony and belongs to the brain, fronted by `punktfunk pair` or a shell + // (design/client-architecture-split.md §5). It still works, with a notice, for the one + // release this needs; a renderer owning a trust ceremony is exactly the mixing of + // concerns the split exists to undo. if let Some(pin) = arg_value("--pair") { + eprintln!( + "note: punktfunk-session --pair is deprecated \u{2014} use `punktfunk pair \ + ` instead (same store, same result)." + ); return headless_pair(&pin); } diff --git a/clients/windows/packaging/AppxManifest.xml b/clients/windows/packaging/AppxManifest.xml index 8c96a691..68985625 100644 --- a/clients/windows/packaging/AppxManifest.xml +++ b/clients/windows/packaging/AppxManifest.xml @@ -106,6 +106,27 @@ + + + + + + + + + + + diff --git a/clients/windows/packaging/pack-msix.ps1 b/clients/windows/packaging/pack-msix.ps1 index 9aac70fa..bc82ebeb 100644 --- a/clients/windows/packaging/pack-msix.ps1 +++ b/clients/windows/packaging/pack-msix.ps1 @@ -72,7 +72,7 @@ New-Item -ItemType Directory -Force -Path (Join-Path $layout 'Assets') | Out-Nul # session client the shell spawns for every stream (sibling resolution — see clients/windows/ # src/spawn.rs); Skia links statically and vulkan-1.dll is a GPU-driver component, so the session # adds no DLLs of its own. -$required = @('punktfunk-client.exe', 'punktfunk-session.exe', 'punktfunk-console.exe', 'Microsoft.WindowsAppRuntime.Bootstrap.dll', 'SDL3.dll', 'resources.pri') +$required = @('punktfunk-client.exe', 'punktfunk-session.exe', 'punktfunk-console.exe', 'punktfunk.exe', 'Microsoft.WindowsAppRuntime.Bootstrap.dll', 'SDL3.dll', 'resources.pri') foreach ($f in $required) { $src = Join-Path $TargetDir $f if (-not (Test-Path $src)) { throw "missing build artifact '$f' in $TargetDir (did 'cargo build --release' run?)" } diff --git a/packaging/arch/PKGBUILD b/packaging/arch/PKGBUILD index f173a670..45a3a8cb 100644 --- a/packaging/arch/PKGBUILD +++ b/packaging/arch/PKGBUILD @@ -96,10 +96,11 @@ build() { # opts back to libav VAAPI), and a failed open falls back to VAAPI so unsupported devices are safe. if [ "$CARCH" = 'aarch64' ]; then # Client-only: no host crate, so none of the encode features below apply. - cargo build --release --locked -p punktfunk-client-linux -p punktfunk-client-session + cargo build --release --locked -p punktfunk-client-linux -p punktfunk-client-session \ + -p punktfunk-cli else cargo build --release --locked --features punktfunk-host/nvenc,punktfunk-host/vulkan-encode \ - -p punktfunk-host -p punktfunk-client-linux -p punktfunk-client-session + -p punktfunk-host -p punktfunk-client-linux -p punktfunk-client-session -p punktfunk-cli # The status tray in its OWN cargo invocation — load-bearing, not tidiness. Cargo unifies features # across everything in one build, so co-building the tray with the host pulls the host's # ashpd -> zbus/tokio onto the tray's shared zbus; the tray (ksni async-io + blocking, no tokio @@ -250,6 +251,8 @@ package_punktfunk-client() { install -Dm0755 "$T/punktfunk-client" "$pkgdir/usr/bin/punktfunk-client" # The session streamer the shell execs for a connect (resolved as its sibling in /usr/bin). install -Dm0755 "$T/punktfunk-session" "$pkgdir/usr/bin/punktfunk-session" + # The headless CLI (design/client-architecture-split.md §4). + install -Dm0755 "$T/punktfunk" "$pkgdir/usr/bin/punktfunk" install -Dm0644 "$R/packaging/linux/io.unom.Punktfunk.desktop" \ "$pkgdir/usr/share/applications/io.unom.Punktfunk.desktop" # DualSense hidraw access (full pad fidelity through SDL's HIDAPI driver). diff --git a/packaging/debian/build-client-deb.sh b/packaging/debian/build-client-deb.sh index 9e6bdfd4..aab5129a 100644 --- a/packaging/debian/build-client-deb.sh +++ b/packaging/debian/build-client-deb.sh @@ -38,9 +38,11 @@ BIN="$OUTDIR/$PKG" # The Vulkan/Skia session streamer the shell execs for a connect — shipped alongside the shell # (the shell resolves it as its /usr/bin sibling), or desktop streaming breaks. SESSION_BIN="$OUTDIR/punktfunk-session" +# The headless CLI (design/client-architecture-split.md §4) ships with every client. +CLI_BIN="$OUTDIR/punktfunk" if [ ! -x "$BIN" ] || [ ! -x "$SESSION_BIN" ]; then echo "==> building $CRATE + punktfunk-client-session (release${TARGET:+ for $TARGET})" - cargo build --release --locked "${CARGO_TARGET_ARGS[@]}" -p "$CRATE" -p punktfunk-client-session + cargo build --release --locked "${CARGO_TARGET_ARGS[@]}" -p "$CRATE" -p punktfunk-client-session -p punktfunk-cli fi STAGE="$(mktemp -d)" @@ -50,6 +52,7 @@ DOCDIR="$STAGE/usr/share/doc/$PKG" # --- file layout -------------------------------------------------------------- install -Dm0755 "$BIN" "$STAGE/usr/bin/$PKG" install -Dm0755 "$SESSION_BIN" "$STAGE/usr/bin/punktfunk-session" +install -Dm0755 "$CLI_BIN" "$STAGE/usr/bin/punktfunk" install -Dm0644 packaging/linux/io.unom.Punktfunk.desktop \ "$STAGE/usr/share/applications/io.unom.Punktfunk.desktop" # DualSense hidraw access (full pad fidelity through SDL's HIDAPI driver). diff --git a/packaging/flatpak/io.unom.Punktfunk.yml b/packaging/flatpak/io.unom.Punktfunk.yml index 2850bf9e..050deae5 100644 --- a/packaging/flatpak/io.unom.Punktfunk.yml +++ b/packaging/flatpak/io.unom.Punktfunk.yml @@ -222,8 +222,12 @@ modules: # unification identical to a workspace build (the pinned skia-binaries archive's # `pdf-textlayout-vulkan` key must match the resolved feature set). - cargo --offline build --release -p punktfunk-client-linux -p punktfunk-client-session + -p punktfunk-cli - install -Dm0755 target/release/punktfunk-client ${FLATPAK_DEST}/bin/punktfunk-client - install -Dm0755 target/release/punktfunk-session ${FLATPAK_DEST}/bin/punktfunk-session + # The headless CLI (design/client-architecture-split.md §4) — reachable as + # `flatpak run --command=punktfunk io.unom.Punktfunk …`. + - install -Dm0755 target/release/punktfunk ${FLATPAK_DEST}/bin/punktfunk # Desktop entry (renamed to the app id; Exec is the in-sandbox binary). - install -Dm0644 packaging/flatpak/io.unom.Punktfunk.desktop ${FLATPAK_DEST}/share/applications/io.unom.Punktfunk.desktop diff --git a/packaging/nix/packages.nix b/packaging/nix/packages.nix index bfa78992..f8f0e74e 100644 --- a/packaging/nix/packages.nix +++ b/packaging/nix/packages.nix @@ -224,7 +224,7 @@ in # so build the session without it. The GTK shell (punktfunk-client-linux) is skia-free and full. # Re-adding the Skia OSD under Nix is tracked in packaging/nix/README.md. cargoExtraArgs = - "--locked -p punktfunk-client-linux -p punktfunk-client-session " + "--locked -p punktfunk-client-linux -p punktfunk-client-session -p punktfunk-cli " + "--no-default-features --features punktfunk-client-session/pyrowave"; # pf-ffvk runs bindgen over libavutil/hwcontext_vulkan.h, which `#include `. diff --git a/packaging/rpm/punktfunk.spec b/packaging/rpm/punktfunk.spec index d1114d56..b95eb7ff 100644 --- a/packaging/rpm/punktfunk.spec +++ b/packaging/rpm/punktfunk.spec @@ -226,10 +226,10 @@ export PUNKTFUNK_BUILD_VERSION="%{version}-%{release}" # back to libav VAAPI), and a failed open falls back to VAAPI so unsupported devices degrade gracefully. %if %{with host} cargo build --release --locked --features punktfunk-host/nvenc,punktfunk-host/vulkan-encode \ - -p punktfunk-host -p punktfunk-client-linux -p punktfunk-client-session + -p punktfunk-host -p punktfunk-client-linux -p punktfunk-client-session -p punktfunk-cli %else # Client-only (aarch64): no host crate, so none of the encode features apply. -cargo build --release --locked -p punktfunk-client-linux -p punktfunk-client-session +cargo build --release --locked -p punktfunk-client-linux -p punktfunk-client-session -p punktfunk-cli %endif # The status tray in its OWN cargo invocation — load-bearing, not tidiness. Cargo unifies features # across everything in one build, so co-building the tray with the host pulls the host's @@ -326,6 +326,9 @@ done install -Dm0755 target/release/punktfunk-client %{buildroot}%{_bindir}/punktfunk-client # The session streamer the shell execs for a connect (resolved as its sibling in %{_bindir}). install -Dm0755 target/release/punktfunk-session %{buildroot}%{_bindir}/punktfunk-session +%{_bindir}/punktfunk +# The headless CLI (design/client-architecture-split.md §4). +install -Dm0755 target/release/punktfunk %{buildroot}%{_bindir}/punktfunk install -Dm0644 packaging/linux/io.unom.Punktfunk.desktop \ %{buildroot}%{_datadir}/applications/io.unom.Punktfunk.desktop # DualSense hidraw access (full pad fidelity through SDL's HIDAPI driver).