ytdl-desktop
Triggered rules
llm_review
The static rules flagged this MEDIUM, but an AI model (anthropic/claude-4.6-sonnet-20260217) reviewed the full PKGBUILD and judged it LOW (confidence 75%): The `yarn add -D @electron-forge/plugin-local-electron` call installs a package from the npm registry that isn't pinned in the source's yarn.lock. However, `@electron-forge/plugin-local-electron` is a well-known, official package from the Electron Forge project (published by the Electron maintainers on the official npm registry), not from a personal or unofficial host. Its purpose here is legitimate: it allows using the system-installed Electron binary instead of downloading one. The pattern of adding it dynamically rather than having it in package.json is sloppy packaging practice (no version pin, no integrity check), but the package itself is from a trusted, well-maintained ecosystem source. This is a low-severity concern (unpinned dependency from npm) rather than a medium supply-chain risk, since the npm registry and the Electron Forge organization are not 'unofficial or personal hosts'. The overall PKGBUILD also uses nvm to manage Node versions locally, uses git+tag source, and the build flow is standard for Electron Forge projects targeting system Electron.
1 higher static finding superseded - not the current verdict (shown for transparency)
npm_install_external
Runs `npm/yarn/pnpm install <package>` for a package not in source=(), pulling unpinned, unreviewed code at build time. Severity downgraded: the package declares/looks like a Node.js consumer, where build-time installs are expected.
-
PKGBUILD:76
NODE_ENV=development yarn add -D @electron-forge/plugin-local-electron
PKGBUILD
1 offending line(s) highlighted# Maintainer: zxp19821005 <zxp19821005 at 163 dot com>
pkgname=ytdl-desktop
_pkgname='Youtube Downloader Desktop'
pkgver=1.0.0
_electronversion=25
_nodeversion=20
pkgrel=10
pkgdesc="Youtube Downloader Desktop.(Use system-wide electron)"
arch=('x86_64')
url="https://github.com/kayy0812/ytdl-desktop"
license=('MIT')
conflicts=("${pkgname}")
depends=(
"electron${_electronversion}"
)
makedepends=(
'gendesk'
'npm'
'yarn'
'nvm'
'curl'
'git'
)
source=(
"${pkgname}-${pkgver}::git+${url}#tag=v${pkgver}"
"${pkgname}.sh"
)
sha256sums=('c2e680a19f780b512728a8d142b4fab89a9c6f492936234f4470cf04dc1c4c3c'
'291f50480f5a61bc9c68db7d44cd0412071128706baa868a9cb854f8779a1980')
_ensure_local_nvm() {
local NVM_DIR="${srcdir}/.nvm"
source /usr/share/nvm/init-nvm.sh || [[ $? != 1 ]]
nvm install "${_nodeversion}"
nvm use "${_nodeversion}"
}
prepare() {
cd "${srcdir}/${pkgname}-${pkgver}"
sed -i -e "
s/@electronversion@/${_electronversion}/g
s/@appname@/${pkgname}/g
s/@runname@/app.asar/g
s/@cfgdirname@/${pkgname}/g
s/@options@//g
" "${srcdir}/${pkgname}.sh"
_ensure_local_nvm
gendesk -f -n -q \
--pkgname="${pkgname}" \
--pkgdesc="${pkgdesc}" \
--categories="Utility" \
--name="${_pkgname}" \
--exec="${pkgname} %U"
export ELECTRON_SKIP_BINARY_DOWNLOAD=1
export SYSTEM_ELECTRON_VERSION="$(electron${_electronversion} -v | sed 's/v//g')"
HOME="${srcdir}/.electron-gyp"
mkdir -p "${srcdir}/.electron-gyp"
if [[ "$(curl -s ipinfo.io/country)" == *"CN"* ]]; then
{
echo -e '\n'
echo 'registry "https://registry.npmmirror.com"'
echo 'electron_mirror "https://registry.npmmirror.com/-/binary/electron/"'
echo 'electron_builder_binaries_mirror "https://registry.npmmirror.com/-/binary/electron-builder-binaries/"'
echo "cacheFolder "${srcdir}"/.yarn/cache"
echo "pluginsFolder "${srcdir}"/.yarn/plugins"
echo "globalFolder "${srcdir}"/.yarn/global"
echo 'useHardlinks true'
#echo 'buildFromSource true'
echo 'linkWorkspacePackages true'
echo 'fetchRetries 3'
echo 'fetchRetryTimeout 10000'
echo 'networkConcurrency 10'
} >> .yarnrc
find ./ -type f -name "yarn.lock" -exec sed -i "s/registry.yarnpkg.com/registry.npmmirror.com/g" {} +
fi
sed -i "s/\"electron\": \"[^\"]*\"/\"electron\": \"${SYSTEM_ELECTRON_VERSION}\"/g" package.json
NODE_ENV=development yarn install --cache-folder "${srcdir}/.yarn_cache"
NODE_ENV=development yarn add -D @electron-forge/plugin-local-electron
}
build() {
cd "${srcdir}/${pkgname}-${pkgver}"
local electronDist="/usr/lib/electron${_electronversion}"
sed -i -e "/^[[:space:]]*plugins:[[:space:]]*\[.*\$/a\\
{\\
name: \"@electron-forge/plugin-local-electron\",\\
config: {\\
electronPath: \"${electronDist}\"\\
}\\
}," forge.config.js
NODE_ENV=production yarn run package
}
package() {
install -Dm755 "${srcdir}/${pkgname}.sh" "${pkgdir}/usr/bin/${pkgname}"
install -Dm644 "${srcdir}/${pkgname}-${pkgver}/out/${pkgname}-linux-"*/resources/app.asar -t "${pkgdir}/usr/lib/${pkgname}"
cp -Pr --no-preserve=ownership "${srcdir}/${pkgname}-${pkgver}/out/${pkgname}-linux-"*/resources/app.asar.unpacked "${pkgdir}/usr/lib/${pkgname}"
install -Dm644 "${srcdir}/${pkgname}-${pkgver}/${pkgname}.desktop" -t "${pkgdir}/usr/share/applications"
install -Dm644 "${srcdir}/${pkgname}-${pkgver}/out/${pkgname}-linux-"*/LICENSE* -t "${pkgdir}/usr/share/licenses/${pkgname}"
}
Scan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 2026-08-03 00:08:14 | LOW | 2 |
| 2026-08-02 00:16:08 | LOW | 2 |
| 2026-08-01 00:11:18 | LOW | 2 |
| 2026-07-31 00:14:10 | LOW | 2 |
| 2026-07-30 00:17:23 | LOW | 2 |
| 2026-07-29 00:25:53 | LOW | 2 |
| 2026-07-28 00:07:28 | LOW | 2 |
| 2026-07-27 00:24:32 | LOW | 2 |
| 2026-07-26 00:07:32 | LOW | 2 |
| 2026-07-25 00:13:44 | LOW | 2 |
| 2026-07-24 00:02:28 | LOW | 2 |
| 2026-07-23 00:14:47 | LOW | 2 |
| 2026-07-22 00:29:32 | LOW | 2 |
| 2026-07-21 00:24:15 | LOW | 2 |
| 2026-07-20 00:19:49 | LOW | 2 |
| 2026-07-19 00:17:08 | LOW | 2 |
| 2026-07-18 00:14:48 | LOW | 2 |
| 2026-07-17 00:06:16 | LOW | 2 |
| 2026-07-16 00:05:41 | LOW | 2 |
| 2026-07-15 00:09:25 | LOW | 2 |