fix(steamdeck): install the plugin runner + harden Deck pad typing + repair update.sh

- scripts/steamdeck/install.sh (§2b) + update.sh: build and install the
  scripting runner user-scoped (~/.local wrapper + pinned bun + bundle) —
  SteamOS's read-only /usr can't take the .deb layout, so the console's
  plugin store reported "the plugin runner isn't installed" on every
  SteamOS host. update.sh retrofits it onto existing installs.
- plugins.rs runner discovery: check the ~/.local layout after the /usr
  ones; mention the SteamOS path in the not-installed error.
- update.sh: define warn() — it was used but never defined, so under
  `set -e` the first warn aborted the update before services restarted.
- pf-client-core gamepad: a Steam Input virtual pad forwarded on a real
  Deck (the only-pad case) now declares the DECK kind in its per-pad
  arrival instead of the wrapper's Xbox 360 identity — the session-level
  auto_pref already resolved SteamDeck, but the arrival overrides it on
  current hosts.
- reject tests: cover SetupFailed; move the foreign-code probe off 0x68.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 10:01:54 +02:00
co-authored by Claude Fable 5
parent 2562663fc6
commit 256aa5f7f2
6 changed files with 89 additions and 8 deletions
+1 -1
View File
@@ -463,7 +463,7 @@ pub(crate) async fn serve(
}
conn_err.close(
punktfunk_core::reject::SETUP_FAILED_CLOSE_CODE.into(),
detail[..cut].as_bytes(),
&detail.as_bytes()[..cut],
);
tracing::warn!(%peer, error = %detail, "session ended with error")
}
+17 -1
View File
@@ -158,9 +158,25 @@ pub(crate) fn runner_command() -> Result<(std::path::PathBuf, Vec<String>)> {
if bun.exists() && runner.exists() {
return Ok((bun, vec![runner.to_string_lossy().into_owned()]));
}
// Immutable-/usr distros (SteamOS): scripts/steamdeck/install.sh lays the SAME payload
// out user-scoped under ~/.local — wrapper, private bun, and bundle mirroring the deb's
// /usr layout — because a system package can't exist there.
if let Ok(home) = std::env::var("HOME") {
let home = std::path::Path::new(&home);
let wrapper = home.join(".local/bin/punktfunk-scripting");
if wrapper.exists() {
return Ok((wrapper, Vec::new()));
}
let bun = home.join(".local/lib/punktfunk-scripting/bun");
let runner = home.join(".local/share/punktfunk-scripting/runner-cli.js");
if bun.exists() && runner.exists() {
return Ok((bun, vec![runner.to_string_lossy().into_owned()]));
}
}
bail!(
"the plugin runner isn't installed — install it first (Debian/Ubuntu: \
`sudo apt install punktfunk-scripting`)"
`sudo apt install punktfunk-scripting`; SteamOS: re-run \
scripts/steamdeck/install.sh)"
)
}
}