Files
punktfunk/clients/decky/scripts/package.sh
T
enricobuehler 15d3d423fa
apple / swift (push) Successful in 56s
ci / rust (push) Successful in 1m48s
android / android (push) Successful in 2m11s
ci / web (push) Successful in 27s
ci / docs-site (push) Successful in 28s
deb / build-publish (push) Successful in 2m24s
decky / build-publish (push) Successful in 12s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 7s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 5s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 5s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 3s
ci / bench (push) Successful in 4m32s
flatpak / build-publish (push) Successful in 4m1s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 8m18s
docker / deploy-docs (push) Successful in 18s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 7m43s
feat(decky): full-featured Gaming-Mode client — fullscreen page, pairing, focus-correct launch
The plugin was a QAM launcher whose stream never appeared, with no
pairing. Three fixes, plus a headless --pair mode on the GTK client:

- Stream actually starts (MoonDeck's proven mechanism): gamescope only
  focuses the process tree Steam launched via reaper, so a flatpak
  spawned from the (root) backend is invisible. The frontend now
  registers ONE hidden non-Steam shortcut pointing at bin/punktfunkrun.sh,
  passes the host as the shortcut's Steam launch options, and starts it
  with SteamClient.Apps.RunGame — gamescope then fullscreen-focuses it.
  The wrapper execs `flatpak run io.unom.Punktfunk --connect <host>`.
- Fullscreen page: routerHook.addRoute("/punktfunk") — host list,
  per-host Pair/Stream, and a settings section (resolution/refresh/
  bitrate/gamepad/mic, written to client-gtk-settings.json).
- Pairing: a gamepad-navigable PIN keypad. The host shows the PIN; the
  backend runs the SPAKE2 ceremony headlessly via the client's new
  `--pair <PIN> --connect host` CLI mode (app.rs), persisting the host
  as paired so the stream then connects silently. Same flatpak =>
  shared identity store, verified live (ceremony against a real host).
- Backend (main.py): discover / pair / runner_info / get_settings /
  set_settings / kill_stream; uses DECKY_USER_HOME so paths resolve to
  the deck user's flatpak install regardless of the plugin's root flag.

CI (decky.yml) and the sideload packager now ship bin/punktfunkrun.sh.
The Steam-shortcut launch and headless-pairing env follow MoonDeck
exactly but need a Deck in Gaming Mode to fully confirm.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 09:17:14 +00:00

43 lines
1.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# Assemble the Decky plugin into the canonical store/sideload layout:
#
# out/punktfunk-v<version>.zip -> punktfunk/{dist/index.js,main.py,plugin.json,
# package.json,decky.pyi,LICENSE,README.md}
# out/punktfunk/ (the same tree, unzipped — rsync this with scripts/deploy.sh)
#
# Decky extracts the zip with --strip-components=1, so the single top-level dir MUST equal
# plugin.json "name". Run after `pnpm build` (or use `pnpm run package`). Host-agnostic: needs
# only bash, python3 and zip.
set -euo pipefail
HERE="$(cd "$(dirname "$0")/.." && pwd)"
cd "$HERE"
[ -f dist/index.js ] || { echo "dist/index.js missing — run 'pnpm build' first" >&2; exit 1; }
[ -f LICENSE ] || { echo "LICENSE missing (required by the Decky store)" >&2; exit 1; }
NAME="$(python3 -c 'import json;print(json.load(open("plugin.json"))["name"])')"
VER="$(python3 -c 'import json;print(json.load(open("package.json"))["version"])')"
STAGE="$(mktemp -d)"
DEST="$STAGE/$NAME"
mkdir -p "$DEST/dist" "$DEST/bin"
cp dist/index.js "$DEST/dist/index.js" # ship the bundle only, not the sourcemap
cp main.py plugin.json package.json LICENSE "$DEST/"
# The stream-launch wrapper (target of the Steam shortcut) — must stay executable.
cp bin/punktfunkrun.sh "$DEST/bin/punktfunkrun.sh"
chmod 0755 "$DEST/bin/punktfunkrun.sh"
[ -f decky.pyi ] && cp decky.pyi "$DEST/"
[ -f README.md ] && cp README.md "$DEST/"
OUT="$HERE/out"
mkdir -p "$OUT"
ZIP="$OUT/${NAME}-v${VER}.zip"
rm -f "$ZIP"
( cd "$STAGE" && zip -r -X "$ZIP" "$NAME" >/dev/null )
# Leave an unzipped staging tree for the rsync/sudo deploy path (scripts/deploy.sh).
rm -rf "$OUT/$NAME" && cp -r "$DEST" "$OUT/$NAME"
rm -rf "$STAGE"
echo "built $ZIP"
echo "staged $OUT/$NAME (deploy with: DECK=deck@<ip> bash scripts/deploy.sh)"