mirror of
https://github.com/Cheviiot/Nivora.git
synced 2026-08-03 15:51:12 +00:00
feat(max): add MAX messenger package, sandboxed with Firejail
MAX is the Russian state-affiliated messenger; the official Qt6 client is repacked from download.max.ru with no independent security track record, so it never runs unsandboxed. /usr/bin/max is a wrapper (not a symlink) that always launches through `firejail --profile=max`; the .desktop Exec goes through the same wrapper so there's no launch path that bypasses it. The profile hides the rest of the home directory behind private ~/.config, ~/.cache and ~/.local/share/max subdirectories, drops capabilities, enables seccomp, blocks system D-Bus, and blacklists the standalone crashpad_handler crash-report uploader. Full elimination of first-party telemetry isn't claimed or possible from the sandbox layer alone — documented in LICENSE. Also wires up repo-wide bookkeeping now that all three package changes (telegram-desktop -> telegram rename, vk-messenger, max) are in: README package count/catalog rows, docs/maintenance.md naming table and directory count, and tools/package_updates.sh + tools/validate_repo.py package lists.
This commit is contained in:
@@ -11,7 +11,7 @@ Nivora предлагает открытые рецепты упаковки д
|
||||
официальный репозиторий Stapler и не официальные пакеты upstream-проектов.
|
||||
|
||||
<!-- package-count -->
|
||||
**22 пакета** · **6 категорий** · `amd64`, `arm64` и `all`
|
||||
**24 пакета** · **6 категорий** · `amd64`, `arm64` и `all`
|
||||
|
||||
[](https://github.com/Cheviiot/Nivora/actions/workflows/quality.yml)
|
||||
|
||||
@@ -47,9 +47,11 @@ stplr info nivora/codex
|
||||
|:--|:--:|:--:|:--|
|
||||
| [Clash Verge Rev](https://github.com/clash-verge-rev/clash-verge-rev) | `2.5.2` | `amd64`, `arm64` | `stplr install nivora/clash-verge-rev` |
|
||||
| [Happ](https://happ.su/) | `3.3.6` | `amd64`, `arm64` | `stplr install nivora/happ` |
|
||||
| [MAX](https://max.ru/) (в песочнице Firejail) | `26.24.0~75261` | `amd64` | `stplr install nivora/max` |
|
||||
| [NetBird](https://netbird.io/) | `0.75.0` | `amd64`, `arm64` | `stplr install nivora/netbird` |
|
||||
| [Tailscale](https://tailscale.com/) | `1.98.9` | `amd64`, `arm64` | `stplr install nivora/tailscale` |
|
||||
| [Telegram Desktop](https://desktop.telegram.org/) | `7.0.5` | `amd64` | `stplr install nivora/telegram-desktop` |
|
||||
| [Telegram](https://desktop.telegram.org/) | `7.0.5` | `amd64` | `stplr install nivora/telegram` |
|
||||
| [VK Messenger](https://vk.me/app) | `6.0.57` | `amd64` | `stplr install nivora/vk-messenger` |
|
||||
| [Яндекс Браузер](https://browser.yandex.ru/) | `26.4.1.1110` | `amd64` | `stplr install nivora/yandex-browser-stable` |
|
||||
|
||||
### Удалённый доступ
|
||||
|
||||
+3
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
## Инварианты
|
||||
|
||||
- В репозитории ровно 20 каталогов с `Staplerfile`.
|
||||
- В репозитории ровно 24 каталога с `Staplerfile`.
|
||||
- Каталог совпадает с `name` и командой в README.
|
||||
- Upstream-версия не меняется из-за патча рецепта; для этого повышается `release`.
|
||||
- Desktop-id, AppStream component-id, units и пути данных не меняются без отдельной миграции.
|
||||
@@ -20,7 +20,9 @@ Stapler сам добавляет текущее `name` в generated `Provides`
|
||||
| `claude` | Upstream DEB: `Package: claude-desktop`; desktop-id `com.anthropic.Claude` сохранён; старое имя пакета `claude-desktop` заменяется |
|
||||
| `codex` | Отображаемое имя `Codex`; команда и desktop-id `codex-app` сохранены |
|
||||
| `github-desktop` | Официальный upstream `desktop/desktop`; Linux-сборка без стороннего форка |
|
||||
| `max` | Upstream package name `max`; версия хранится как `VERSION~BUILD` (совпадает с номером сборки в имени deb-файла, как у ALT eepm) для воспроизводимости; пакет всегда запускает бинарник через Firejail (`/etc/firejail/max.profile`), `/usr/bin/max` — не симлинк, а обёртка с `exec firejail` |
|
||||
| `nivora-cli` | Многоязычная оболочка Nivora для Stapler |
|
||||
| `telegram` | Upstream-тарбол не даёт своего package ID; desktop-id `org.telegram.desktop` сохранён; каталог и package ID переименованы с `telegram-desktop`. В отличие от `claude`/`claude-desktop`, `replaces` не включает старое имя (это разрешено только для `claude` в `validate_repo.py`) — у кого установлен `telegram-desktop`, нужно вручную `stplr install telegram` и `stplr remove telegram-desktop` |
|
||||
|
||||
## Локальные проверки
|
||||
|
||||
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
package_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
repo_root="$(cd "${package_dir}/.." && pwd)"
|
||||
exec "${repo_root}/tools/package_updates.sh" check "$(basename "$package_dir")"
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
Сведения о лицензии пакета max
|
||||
|
||||
Лицензия: Custom (проприетарная).
|
||||
Исходный продукт: https://max.ru/
|
||||
Официальный deb-репозиторий: https://download.max.ru/linux/deb/
|
||||
|
||||
Нюансы пакета:
|
||||
- Пакет перепаковывает официальный Linux deb-артефакт MAX Messenger Client
|
||||
из deb-репозитория max.ru; отдельного публичного репозитория исходников
|
||||
или GitHub-релиза у продукта нет.
|
||||
- Приложение собрано на Qt6 и распространяется полностью самодостаточным
|
||||
бандлом (собственные библиотеки Qt в `lib64/`).
|
||||
- Пакет запускает приложение только через Firejail-песочницу (профиль
|
||||
`/etc/firejail/max.profile`): домашний каталог пользователя виден
|
||||
приложению только через отдельные `~/.config/max`, `~/.cache/max`,
|
||||
`~/.local/share/max`; capabilities сброшены, seccomp включён,
|
||||
системная D-Bus недоступна. Отдельный процесс `crashpad_handler`
|
||||
(сбор и отправка крэш-дампов) заблокирован явным `blacklist`, чтобы
|
||||
ограничить исходящую телеметрию, не относящуюся к функциям обмена
|
||||
сообщениями.
|
||||
- Полная гарантия отсутствия любой сетевой телеметрии невозможна:
|
||||
трафик самого мессенджера к серверам max.ru неотличим от служебного
|
||||
на уровне песочницы. Firejail ограничивает доступ к системе и файлам,
|
||||
а не содержимое протокола приложения.
|
||||
- Для полноценной работы требуется учетная запись, привязанная к
|
||||
российскому номеру телефона.
|
||||
- Использование мессенджера, учетной записи и сетевых функций
|
||||
регулируется условиями MAX.
|
||||
- Пакет помечен как несвободный через `nonfree=1`.
|
||||
|
||||
Официальные условия:
|
||||
https://legal.max.ru/ps
|
||||
https://legal.max.ru/pp
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
name='max'
|
||||
version='26.24.0~75261'
|
||||
release=1
|
||||
summary='MAX messenger client, sandboxed with Firejail'
|
||||
summary_ru='Клиент мессенджера MAX в песочнице Firejail'
|
||||
group='Networking/Instant messaging'
|
||||
desc='MAX is the Russian state-affiliated instant messaging client. This package always launches it inside a Firejail sandbox that hides the rest of the home directory and blocks the standalone crash-report uploader, since the app has no independent security track record and no reason to see the whole system.'
|
||||
desc_ru='MAX — российский государственно-аффилированный клиент мгновенных сообщений. Пакет всегда запускает его в песочнице Firejail, которая скрывает остальной домашний каталог и блокирует отдельный процесс отправки крэш-дампов — у приложения нет независимой истории аудита безопасности и нет причин видеть всю систему.'
|
||||
homepage='https://max.ru/'
|
||||
maintainer='max.ru <https://max.ru/>'
|
||||
|
||||
architectures=('amd64')
|
||||
|
||||
license=('Custom')
|
||||
nonfree=1
|
||||
nonfree_msg='MAX является проприетарным приложением. Использование мессенджера, учетной записи и сетевых функций регулируется условиями MAX.'
|
||||
nonfree_url='https://legal.max.ru/ps'
|
||||
|
||||
provides=()
|
||||
replaces=('max')
|
||||
conflicts=()
|
||||
|
||||
auto_reqprov_method="dirty"
|
||||
auto_req=0
|
||||
auto_prov=0
|
||||
|
||||
deps=('firejail')
|
||||
deps_debian=('firejail' 'libxcb-xinerama0' 'libxcb-composite0' 'libxcb-ewmh2' 'libva-x11-2' 'libva-drm2' 'libvdpau1' 'libnotify4' 'libxcb-dri2-0' 'libopengl0' 'libxcb-cursor0' 'libxkbcommon-x11-0' 'libxcb-icccm4' 'libxcb-keysyms1' 'libxss1' 'libglib2.0-0' 'gsettings-desktop-schemas' 'ca-certificates')
|
||||
deps_ubuntu=("${deps_debian[@]}")
|
||||
deps_fedora=('firejail' 'libxcb' 'libva' 'libvdpau' 'libnotify' 'libglvnd-opengl' 'xcb-util-cursor' 'libxkbcommon-x11' 'xcb-util-wm' 'xcb-util-keysyms' 'libXScrnSaver' 'glib2' 'gsettings-desktop-schemas' 'ca-certificates')
|
||||
deps_arch=('firejail' 'libxcb' 'libva' 'libvdpau' 'libnotify' 'libglvnd' 'xcb-util-cursor' 'libxkbcommon-x11' 'xcb-util-wm' 'xcb-util-keysyms' 'libxss' 'glib2' 'gsettings-desktop-schemas' 'ca-certificates')
|
||||
deps_opensuse=('firejail' 'libxcb1' 'libva2' 'libvdpau1' 'libnotify4' 'libxcb-cursor0' 'libxkbcommon-x11-0' 'xcb-util-wm0' 'xcb-util-keysyms0' 'libXss1' 'libglib-2_0-0' 'gsettings-desktop-schemas' 'ca-certificates')
|
||||
deps_altlinux=('firejail' 'libxcb' 'libxcbutil-cursor' 'libxcbutil-icccm' 'libxcbutil-keysyms' 'libXScrnSaver' 'libva' 'libvdpau' 'libnotify' 'libOpenGL' 'libxkbcommon-x11' 'glib2' 'gsettings-desktop-schemas' 'ca-certificates')
|
||||
|
||||
opt_deps=()
|
||||
opt_deps_debian=('desktop-file-utils' 'hicolor-icon-theme' 'pipewire')
|
||||
opt_deps_ubuntu=("${opt_deps_debian[@]}")
|
||||
opt_deps_fedora=('desktop-file-utils' 'hicolor-icon-theme' 'pipewire')
|
||||
opt_deps_arch=('desktop-file-utils' 'hicolor-icon-theme' 'pipewire')
|
||||
opt_deps_opensuse=('desktop-file-utils' 'hicolor-icon-theme' 'pipewire')
|
||||
opt_deps_altlinux=('desktop-file-utils' 'icon-theme-hicolor' 'pipewire')
|
||||
|
||||
build_deps=('binutils')
|
||||
|
||||
sources=(
|
||||
"https://download.max.ru/linux/deb/pool/main/m/max/MAX-26.24.0.75261.deb?~archive=false&~name=max.deb"
|
||||
'local:///max.desktop'
|
||||
'local:///max.profile'
|
||||
'local:///LICENSE'
|
||||
)
|
||||
|
||||
checksums=(
|
||||
'sha256:7151aa2559e5fe22dd4dd6cf037b5d5cd38d302f84e49d4c4be94e1c4fe1f7d5'
|
||||
'sha256:80ec5c0f4777ab00c433c25ffa70ef23d1752785e6584288d189518b8b43d613'
|
||||
'sha256:cf8c986f7f1a9841be33b43cfd8e34e6c75dac6ffea07aad07869177fc7768c7'
|
||||
'sha256:ddfcad273084c8b5690f6276fb29d8990ff4a7114db8a89b3f46255f8675e6b6'
|
||||
)
|
||||
|
||||
scripts=(
|
||||
['postinstall']='postinstall.sh'
|
||||
['postremove']='postremove.sh'
|
||||
)
|
||||
|
||||
package() {
|
||||
cd "${srcdir}"
|
||||
|
||||
mkdir -p "${srcdir}/extracted"
|
||||
ar x max.deb
|
||||
tar -xf data.tar.* -C "${srcdir}/extracted"
|
||||
|
||||
install -dm755 "${pkgdir}/usr/share"
|
||||
cp -a "${srcdir}/extracted/usr/share/max" "${pkgdir}/usr/share/max"
|
||||
install -Dm644 "${srcdir}/extracted/usr/share/pixmaps/max.png" \
|
||||
"${pkgdir}/usr/share/pixmaps/max.png"
|
||||
|
||||
for icon in "${srcdir}"/extracted/usr/share/icons/hicolor/*/apps/max.png; do
|
||||
size="$(basename "$(dirname "$(dirname "$icon")")")"
|
||||
install -Dm644 "$icon" \
|
||||
"${pkgdir}/usr/share/icons/hicolor/${size}/apps/max.png"
|
||||
done
|
||||
|
||||
install -Dm644 max.profile "${pkgdir}/etc/firejail/max.profile"
|
||||
|
||||
# The desktop file and every other launch path go through this wrapper —
|
||||
# MAX never runs unsandboxed regardless of how it's started.
|
||||
install -Dm755 /dev/stdin "${pkgdir}/usr/bin/max" <<'EOF'
|
||||
#!/bin/sh
|
||||
exec firejail --profile=max -- /usr/share/max/bin/max "$@"
|
||||
EOF
|
||||
|
||||
install -Dm644 max.desktop "${pkgdir}/usr/share/applications/max.desktop"
|
||||
|
||||
install-license "${srcdir}/LICENSE" "max/LICENSE.nivora"
|
||||
}
|
||||
|
||||
files() {
|
||||
files-find-binary
|
||||
files-find-desktop
|
||||
files-find-license
|
||||
files-find \
|
||||
"/etc/firejail/max.profile" \
|
||||
"/usr/share/max/**/*" \
|
||||
"/usr/share/pixmaps/max.png" \
|
||||
"/usr/share/icons/hicolor/*/apps/max.png"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Terminal=false
|
||||
Name=MAX
|
||||
Exec=/usr/bin/max %U
|
||||
Icon=max
|
||||
MimeType=x-scheme-handler/max;
|
||||
Comment=MAX Messenger Client Application
|
||||
Comment[ru]=Клиентское приложение мессенджера MAX
|
||||
StartupWMClass=max
|
||||
Categories=Chat;Network;InstantMessaging;Qt;
|
||||
Keywords=max;chat;im;messaging;messenger;sms;
|
||||
DBusActivatable=false
|
||||
SingleMainWindow=true
|
||||
X-GNOME-UsesNotifications=true
|
||||
X-GNOME-SingleWindow=true
|
||||
@@ -0,0 +1,53 @@
|
||||
# Firejail profile for MAX Messenger (Nivora package)
|
||||
# MAX is a proprietary Russian messenger; this profile keeps it away from
|
||||
# the rest of the user's files and system, and blocks its standalone
|
||||
# crash-report uploader.
|
||||
|
||||
include max.local
|
||||
include globals.local
|
||||
|
||||
noblacklist ${HOME}/.config/max
|
||||
noblacklist ${HOME}/.cache/max
|
||||
noblacklist ${HOME}/.local/share/max
|
||||
|
||||
include disable-common.inc
|
||||
include disable-devel.inc
|
||||
include disable-exec.inc
|
||||
include disable-interpreters.inc
|
||||
include disable-programs.inc
|
||||
include landlock-common.inc
|
||||
|
||||
mkdir ${HOME}/.config/max
|
||||
mkdir ${HOME}/.cache/max
|
||||
mkdir ${HOME}/.local/share/max
|
||||
whitelist ${HOME}/.config/max
|
||||
whitelist ${HOME}/.cache/max
|
||||
whitelist ${HOME}/.local/share/max
|
||||
include whitelist-common.inc
|
||||
include whitelist-run-common.inc
|
||||
include whitelist-usr-share-common.inc
|
||||
include whitelist-var-common.inc
|
||||
|
||||
caps.drop all
|
||||
netfilter
|
||||
nodvd
|
||||
nogroups
|
||||
nonewprivs
|
||||
noroot
|
||||
notv
|
||||
nou2f
|
||||
protocol unix,inet,inet6
|
||||
seccomp
|
||||
restrict-namespaces
|
||||
|
||||
disable-mnt
|
||||
private-dev
|
||||
private-tmp
|
||||
|
||||
# Chromium/Qt-style standalone crash uploader: no messaging function, only
|
||||
# phones home with crash dumps. Block it outright rather than trust a
|
||||
# network-level filter.
|
||||
blacklist /usr/share/max/bin/crashpad_handler
|
||||
blacklist /usr/share/max/bin/max-service/bin/crashpad_handler
|
||||
|
||||
dbus-system none
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
optional_refresh() {
|
||||
local label=$1
|
||||
shift
|
||||
if ! "$@"; then
|
||||
echo "Предупреждение: не удалось обновить ${label}." >&2
|
||||
fi
|
||||
}
|
||||
|
||||
if command -v update-desktop-database >/dev/null 2>&1; then
|
||||
optional_refresh "desktop-базу" update-desktop-database -q /usr/share/applications
|
||||
fi
|
||||
|
||||
if command -v gtk-update-icon-cache >/dev/null 2>&1; then
|
||||
optional_refresh "кэш иконок" gtk-update-icon-cache -f -q /usr/share/icons/hicolor
|
||||
fi
|
||||
|
||||
if command -v kbuildsycoca6 >/dev/null 2>&1; then
|
||||
optional_refresh "кэш KDE" kbuildsycoca6 --noincremental
|
||||
elif command -v kbuildsycoca5 >/dev/null 2>&1; then
|
||||
optional_refresh "кэш KDE" kbuildsycoca5 --noincremental
|
||||
fi
|
||||
|
||||
if ! command -v firejail >/dev/null 2>&1; then
|
||||
echo "Предупреждение: firejail не найден в PATH — MAX запускается только через firejail, пакет firejail должен быть установлен." >&2
|
||||
fi
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
optional_refresh() {
|
||||
local label=$1
|
||||
shift
|
||||
if ! "$@"; then
|
||||
echo "Предупреждение: не удалось обновить ${label}." >&2
|
||||
fi
|
||||
}
|
||||
|
||||
if command -v update-desktop-database >/dev/null 2>&1; then
|
||||
optional_refresh "desktop-базу" update-desktop-database -q /usr/share/applications
|
||||
fi
|
||||
|
||||
if command -v gtk-update-icon-cache >/dev/null 2>&1; then
|
||||
optional_refresh "кэш иконок" gtk-update-icon-cache -f -q /usr/share/icons/hicolor
|
||||
fi
|
||||
|
||||
if command -v kbuildsycoca6 >/dev/null 2>&1; then
|
||||
optional_refresh "кэш KDE" kbuildsycoca6 --noincremental
|
||||
elif command -v kbuildsycoca5 >/dev/null 2>&1; then
|
||||
optional_refresh "кэш KDE" kbuildsycoca5 --noincremental
|
||||
fi
|
||||
@@ -0,0 +1 @@
|
||||
include = "../stapler-repo.toml"
|
||||
@@ -13,15 +13,17 @@ readonly -a PACKAGES=(
|
||||
fisher
|
||||
github-desktop
|
||||
happ
|
||||
max
|
||||
netbird
|
||||
nivora-cli
|
||||
opencode
|
||||
parsec
|
||||
pineconemc
|
||||
tailscale
|
||||
telegram-desktop
|
||||
telegram
|
||||
ventoy
|
||||
vintner
|
||||
vk-messenger
|
||||
vual
|
||||
yandex-browser-stable
|
||||
)
|
||||
@@ -214,6 +216,51 @@ latest_yandex_browser() {
|
||||
printf '%s\n' "$version"
|
||||
}
|
||||
|
||||
latest_max() {
|
||||
local filename ver build
|
||||
filename="$(
|
||||
curl --retry 3 --retry-delay 2 --retry-all-errors \
|
||||
--connect-timeout 30 --max-time 120 -fsSL \
|
||||
'https://download.max.ru/linux/deb/dists/stable/main/binary-amd64/Packages.gz' |
|
||||
gzip -dc |
|
||||
awk '
|
||||
/^Package: max$/ { selected = 1; next }
|
||||
/^Package: / { selected = 0 }
|
||||
selected && /^Filename: / { print $2 }
|
||||
' |
|
||||
sort -V |
|
||||
tail -1
|
||||
)"
|
||||
[[ -n "$filename" ]] || die 'cannot determine latest MAX version'
|
||||
filename="$(basename "$filename")"
|
||||
filename="${filename#MAX-}"
|
||||
filename="${filename%.deb}"
|
||||
ver="${filename%.*}"
|
||||
build="${filename##*.}"
|
||||
[[ -n "$ver" && -n "$build" ]] || die 'cannot parse latest MAX filename'
|
||||
printf '%s~%s\n' "$ver" "$build"
|
||||
}
|
||||
|
||||
latest_vk_messenger() {
|
||||
local temp_dir version
|
||||
temp_dir="$(mktemp -d)"
|
||||
curl --retry 3 --retry-delay 2 --retry-all-errors \
|
||||
--connect-timeout 30 --max-time 300 -fsSL \
|
||||
-o "${temp_dir}/vk-messenger.deb" \
|
||||
'https://upload.object2.vk-apps.com/vk-me-desktop-dev-5837a06d-5f28-484a-ac22-045903cb1b1a/latest/vk-messenger.deb'
|
||||
(
|
||||
cd "$temp_dir"
|
||||
ar x vk-messenger.deb
|
||||
tar -xOf control.tar.* ./control
|
||||
) >"${temp_dir}/control"
|
||||
version="$(awk '$1 == "Version:" {print $2; exit}' "${temp_dir}/control")"
|
||||
version="${version%-*}"
|
||||
[[ -n "$version" ]] || die 'cannot determine latest VK Messenger version'
|
||||
printf '%s\n' "$version"
|
||||
find "$temp_dir" -mindepth 1 -delete
|
||||
rmdir "$temp_dir"
|
||||
}
|
||||
|
||||
latest_version() {
|
||||
case "$1" in
|
||||
adwyra) github_latest_release Cheviiot/Adwyra ;;
|
||||
@@ -228,15 +275,17 @@ latest_version() {
|
||||
github_latest_release desktop/desktop | sed 's/^release-//'
|
||||
;;
|
||||
happ) github_latest_release Happ-proxy/happ-desktop ;;
|
||||
max) latest_max ;;
|
||||
netbird) github_latest_release netbirdio/netbird ;;
|
||||
nivora-cli) current_version nivora-cli ;;
|
||||
opencode) github_latest_release anomalyco/opencode ;;
|
||||
parsec) latest_parsec ;;
|
||||
pineconemc) github_latest_release ElyPrismLauncher/Launcher ;;
|
||||
tailscale) latest_tailscale ;;
|
||||
telegram-desktop) github_latest_release telegramdesktop/tdesktop ;;
|
||||
telegram) github_latest_release telegramdesktop/tdesktop ;;
|
||||
ventoy) github_latest_release ventoy/Ventoy ;;
|
||||
vintner) github_latest_release Cheviiot/vintner ;;
|
||||
vk-messenger) latest_vk_messenger ;;
|
||||
vual) github_latest_release Cheviiot/Vual ;;
|
||||
yandex-browser-stable) latest_yandex_browser ;;
|
||||
*) die "unknown package: $1" ;;
|
||||
|
||||
@@ -23,15 +23,17 @@ EXPECTED_PACKAGES = (
|
||||
"fisher",
|
||||
"github-desktop",
|
||||
"happ",
|
||||
"max",
|
||||
"netbird",
|
||||
"nivora-cli",
|
||||
"opencode",
|
||||
"parsec",
|
||||
"pineconemc",
|
||||
"tailscale",
|
||||
"telegram-desktop",
|
||||
"telegram",
|
||||
"ventoy",
|
||||
"vintner",
|
||||
"vk-messenger",
|
||||
"vual",
|
||||
"yandex-browser-stable",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user