DECKYMUSIC
开发文档Docs › 快速开始Getting started

本地开发

环境

  • Node.js 与 pnpm 11.3.0
  • Python 3.11+ 与 uv(QQ provider 开发)
  • Rust toolchain(本地检查)
  • Docker(构建 SteamOS 兼容的 Rust/QQ provider 发布产物)
  • 可通过 SSH 访问的 Steam Deck(真机部署与验收)

安装前端依赖

git clone https://github.com/jinzhongjia/decky-music.git
cd decky-music
pnpm install
pnpm build

常用命令

命令 用途
pnpm watch 监听并构建前端
pnpm build 构建前端到 dist/
pnpm test:ui 运行前端 Node 测试
pnpm lint TypeScript 类型检查与 Prettier 校验
python3 -m unittest discover -s tests 运行 bridge/protocol Python 测试
cargo test --workspace 运行 Rust workspace 测试
cargo fmt --all && cargo clippy --workspace Rust 格式与静态检查

构建 SteamOS 二进制

发布和真机部署使用 Docker 内的兼容工具链,避免本机 glibc 版本高于 SteamOS:

bash scripts/build-rust.sh -p player -p provider

产物位于 target/release/player 与 target/release/provider。

构建镜像固定到 digest,构建脚本自动运行 scripts/check-binaries.py:检查 x86-64 ELF、 glibc 需求不超过 2.39,以及两个可执行文件的动态依赖白名单。 此检查只能证明二进制 ABI 边界,不能代替音频、手柄、屏幕缩放和睡眠恢复的真机验收。

自动检查与固定构建工具

PR 和分支 push 会运行 Checks:stdlib bridge 单测、 pnpm 9/11 两套 UI 测试/类型检查/构建,以及 Rust fmt/test/clippy(含 provider 的 QQ / 网易云后端)。 运行时和第三方 Actions 使用固定版本或提交;工作流失败不会被忽略,不自动修改分支保护规则。

插件打包统一使用 bash scripts/decky-build.sh。它校验固定版本 Decky CLI 的 SHA-256, 从固定 digest 准备官方 builder,并使用 Git 可见的当前工作区源码建立临时输入目录: 未提交的新源码仍会纳入,target/ 与被忽略的密钥文件不会被复制进构建输入。 默认使用 Docker + sudo;已有 rootless Podman 时可用 DECKY_BUILD_SUDO=0 DECKY_BUILD_ENGINE=podman bash scripts/decky-build.sh --build-as-root。

部署到开发机

DECK_HOST=<user>@<steamos-ip> bash scripts/deploy.sh

scripts/deploy.sh 会构建前端、打包插件、复制已有二进制并重启 plugin_loader。它不会重新构建 player/provider;修改 player/、provider/ 或 wire/ 后,必须先运行上面的构建命令。

DECK_HOST 必填,SSH 登录用户不必名为 deck。脚本在构建前从远端 plugin_loader 服务配置 发现实际插件目录;无法可靠发现时停止,不猜测 /home/deck。可用 DECK_PLUGIN_PATH=/absolute/path/to/plugins 显式指定,目录仍须通过安全检查。 写权限按服务的 UNPRIVILEGED_USER 配置(或可唯一对应的用户 home)设置,不使用 SSH 登录用户。 目录覆盖不能替代账号解析;使用间接环境文件或无法确定账号时,需要先明确服务的非特权用户配置。 侧载前须备齐两个预构建二进制;脚本会先检查 ABI,再开始打包。 远端 sudo 如需口令,通过环境变量 DECK_PASS 提供,勿写入脚本或仓库。

兼容性验收须分别记录:实际用户名/UID 与安装目录、SteamOS/Steam/Decky 版本、内置与外接音频、 睡眠唤醒、屏幕比例/缩放和控制器操作。现有 Steam Deck 回归不等于非 Deck 设备已验收; 后者目前因缺少设备而待验证。

目录

路径 职责
src/ React UI、播放器页面、provider 页面和唯一前端 API 层
main.py Decky Plugin facade:CALLABLES 白名单 + __getattr__ 转发给 bridge
py_modules/ bridge、播放队列、协议和日志实现,只使用 Python 标准库
player/ Rust 音频 player,负责流式拉取、解码、播放、控制与 MPRIS
wire/ bridge ↔ 子进程协议 v1 的 Rust 实现,player 与 provider 共用
provider/ 统一 Rust 音源进程:QQMusicApi-rs 的 QQ 音乐后端 + ncm-api-rs 的网易云后端
tests/ bridge、协议、设置和前端行为测试
docs/ 架构、路线图、队列语义、provider 能力和 UI 规格
scripts/ SteamOS 兼容构建、真机部署,以及 full / CN 发布打包
website/ 项目官网(Steam 商店页风格,Cloudflare Workers 部署),见 website/README.md

贡献

提交改动前请先阅读 AGENTS.md 和相关设计文档。关键约束:

  • callable/emit 契约变化必须同步修改 bridge 与 src/api.ts。
  • bridge ↔ 子进程协议变化必须同步修改四端 protocol 模块和配套测试。
  • 所有用户文案同时维护中文和英文;所有可交互 UI 必须支持手柄焦点导航。
  • 日志不得包含播放 URL、Cookie、凭证或其他敏感信息。
  • 影响 UI 视觉、文案、布局或焦点的改动必须更新对应 provider 的真机截图。
  • Commit 使用 Conventional Commits,主题优先使用中文。

在 GitHub 上查看 / 编辑此文档View or edit this page on GitHub ↗