Skip to content

Add CapyDeploy to Plugin Store#984

Open
lobinuxsoft wants to merge 3 commits intoSteamDeckHomebrew:mainfrom
lobinuxsoft:add-capydeploy
Open

Add CapyDeploy to Plugin Store#984
lobinuxsoft wants to merge 3 commits intoSteamDeckHomebrew:mainfrom
lobinuxsoft:add-capydeploy

Conversation

@lobinuxsoft
Copy link

@lobinuxsoft lobinuxsoft commented Feb 9, 2026

Add CapyDeploy to Plugin Store

CapyDeploy is a game deployment plugin for Steam Deck. It receives games from a desktop Hub app over WebSocket and creates Steam shortcuts automatically — no Steam restart needed.

Key features:

  • Receive game files from CapyDeploy Hub (PC) over local network
  • Create Steam shortcuts instantly via SteamClient.Apps.AddShortcut()
  • Apply artwork (cover, hero, icon) via SteamClient.Apps.SetCustomArtworkForApp()
  • Secure 6-digit pairing code on first connection
  • mDNS auto-discovery — no IP configuration needed
  • Real-time transfer progress and toast notifications

This plugin is unique — no other plugin on the store provides game deployment from a desktop app to Steam Deck in gaming mode.

Main project: lobinuxsoft/capydeploy

Task Checklist

Developer

  • I am the original author or an authorized maintainer of this plugin.
  • I have abided by the licenses of the libraries I am utilizing, including attaching license notices where appropriate.

Plugin

  • I have verified that my plugin works properly on the Stable and Beta update channels of SteamOS.
  • I have verified my plugin is unique or provides more/alternative functionality to a plugin already on the store.

Backend

  • No: I am using a custom backend other than Python.
  • No: I am using a tool or software from a 3rd party FOSS project that does not have it's dependencies statically linked.
  • No: I am using a custom binary that has all of it's dependencies statically linked.

Community

  • I have tested and left feedback on two other pull requests for new or updating plugins.
  • I have commented links to my testing report in this PR.

Testing

  • Tested by a third party on SteamOS Stable or Beta update channel.

@lobinuxsoft lobinuxsoft requested a review from a team as a code owner February 9, 2026 19:49
@github-actions github-actions bot added the plugin-addition Adding a plugin to the Plugin Store label Feb 9, 2026
@github-actions
Copy link

github-actions bot commented Feb 9, 2026

Issues Found

No issues with your PR description were found.

Next Steps

  1. If we found any issues above, please edit your pull request description to resolve them and leave a comment saying you've done so.
  2. For the quickest review, please see the Community section of the pull request template for how you can help other developers.
  3. Once your description is correct, a maintainer will review your pull request as soon as possible.

Thank you for your contribution! If you need any help, please reach out on our Discord server. ❤️

@lobinuxsoft
Copy link
Author

Community testing completed:

@beebls
Copy link
Contributor

beebls commented Feb 12, 2026

Code LGTM but I'm gonna ask for a second review from another reviewer before accepting it because I'm not as familiar with ws/python.

Also, is root necessary for this plugin? If it is, then no worries, I'm just asking for a bit of an explanation as to what you do that requires root.

@EMERALD0874
Copy link
Member

LGTM as well, though I'll wait for an explanation on the root usage before putting on the testing store

@lobinuxsoft
Copy link
Author

Hey @beebls @EMERALD0874, sorry for the late response!

Thanks for the review and for flagging the root usage — that's a fair question.

Initially, root was required because the plugin creates files during game uploads (running as root via Decky), which ended up owned by root:root. Since Steam runs as the regular user (e.g. deck), we needed os.chown() to fix ownership/permissions so Steam could actually read those files. We also used systemctl restart steam which typically requires elevated privileges.

However, after taking a closer look thanks to your feedback, I'm now thinking root might no longer be necessary. If the plugin runs as the regular user, the files would already have the correct ownership and the whole chown workaround becomes unnecessary.

I'm going to do a thorough review to confirm whether we can safely drop the root flag. If it turns out we can, I'll remove it and update the PR. If there's still a legitimate reason it's needed, I'll come back with a detailed explanation of exactly what requires it and why.

Thanks again for the careful review!

@lobinuxsoft
Copy link
Author

lobinuxsoft commented Feb 15, 2026

Hey @beebls @EMERALD0874 — quick update on the root flag discussion:

After a thorough audit, I've confirmed the plugin does not need root. The root flag has been removed in v0.6.2 (7843d3e), which this PR now points to.

Here's what changed:

  • plugin.json: "flags": ["root"]"flags": []
  • Removed fix_permissions(): This function used os.chown() to fix file ownership after uploads. It was only necessary because running as root created files as root:root. Without root, files are created with the correct user ownership natively — the whole workaround was circular.
  • Replaced systemctl restart steam with steam -shutdown: This is a graceful, unprivileged shutdown. In Gaming Mode, the session manager automatically restarts Steam afterward. This is the same approach used by the desktop Go agent.

Everything else (telemetry reads from /sys/ and /proc/, artwork writes to the user's home, os.chmod on uploaded executables) works fine without root since the user already owns those files/paths.

Tested and verified on device — uploads, artwork, and Steam restart all work correctly without root.

@beebls
Copy link
Contributor

beebls commented Feb 18, 2026

Appreciate the changes, will deploy this to testing store now and wait for user reviews

@lobinuxsoft
Copy link
Author

Note: v0.7.2 hotfix

After the v0.7.0 refactor that split ws_server.py into a handlers/ module directory, our automated release workflow (release-please.yml) was not including the new handlers/ directory in the packaged zip. This caused the plugin to fail on load with ModuleNotFoundError: No module named 'handlers'.

v0.7.2 fixes this by adding the handlers/ directory to the release packaging step. The plugin has been tested and verified working on SteamOS.

Removed merge conflict markers and cleaned up submodule entries.
@beebls beebls deployed to testing_env February 25, 2026 22:53 — with GitHub Actions Active
@beebls
Copy link
Contributor

beebls commented Feb 25, 2026

github merge conflict editor had a bit of a goof and so sorry for the double commit there but new version is deploying to the testing store

@lobinuxsoft
Copy link
Author

No need to apologize, and thank you so much for the excellent work you do! I have a question: are updates made in the same PR once it's been published, or should they be done in a separate PR? I'm asking because some users who are testing directly from my project page have been reporting bugs, and I've been fixing them on the fly. So far there are no significant changes, but I'll likely need to make some that could have compatibility issues with the version tied to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plugin-addition Adding a plugin to the Plugin Store

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants