13 KiB
Contributing to TuxMate
Quick Navigation
- Project Overview
- Development Workflow
- Adding Applications
- Adding Distributions
- Pull Request Checklist
- Templates
Project Overview
src/lib/data.ts: Main registry for applications and distributions.src/lib/aur-packages.json: Whitelist for AUR packages that lack standard suffixes.src/lib/nix-unfree.json: Registry for unfree Nix packages.src/lib/verified-flatpaks.json: Auto-generated list of verified Flathub apps. Do not edit.src/lib/verified-snaps.json: Manual whitelist of verified Snap publishers.
Development Workflow
Initial Setup
git clone https://github.com/abusoww/tuxmate.git
cd tuxmate
npm install
npm run dev
The app will be available at http://localhost:3000.
Running with Docker
You can run the full application using the official Docker image:
docker run -p 3000:80 ghcr.io/abusoww/tuxmate:latest
Quality Assurance
Always run these before pushing:
npm run lint: Check for code style issues.npm run test: Run unit test suite.npm run build: Verify production build.
Verifying Install Scripts
To verify that the scripts generated by TuxMate work correctly, run them in a clean container environment. This prevents messing up your local system.
- Generate a script in the TuxMate UI (Dev mode).
- Copy the script.
- Run the corresponding distro container commands below and paste the script.
# Arch Linux
docker run -it --rm archlinux:latest bash -c "pacman -Sy && bash"
# Ubuntu
docker run -it --rm ubuntu:latest bash -c "apt update && bash"
# Fedora
docker run -it --rm fedora:latest bash -c "dnf check-update; bash"
Adding Applications
All applications are defined in src/lib/data.ts.
1. Mandatory Research Protocol
You MUST verify every package on these official sources before submitting:
| Source | Scope | URL |
|---|---|---|
| Repology | Global Index | repology.org |
| Arch Linux | Official Repos | archlinux.org/packages |
| AUR | User Repo | aur.archlinux.org |
| Debian | Official Repos | packages.debian.org |
| Ubuntu | Official Repos | packages.ubuntu.com |
| Fedora | Official Repos | packages.fedoraproject.org |
| OpenSUSE | Official Repos | software.opensuse.org |
| Nix | Nixpkgs | search.nixos.org |
| Flathub | Flatpaks | flathub.org |
| Snapcraft | Snaps | snapcraft.io |
| Homebrew | CLI & Casks | formulae.brew.sh |
2. Entry Structure
{
id: 'app-id', // Unique, lowercase, kebab-case
name: 'App Name', // Official display name
description: 'Short description', // Max ~60 characters
category: 'Category', // Must match valid categories
iconUrl: si('icon-slug', '#color'), // See Icon System section
targets: {
ubuntu: 'exact-package-name', // apt package (official repos ONLY)
arch: 'exact-package-name', // pacman OR AUR package name
flatpak: 'com.vendor.AppId', // FULL Flatpak App ID (reverse DNS)
snap: 'snap-name', // Add --classic if needed
homebrew: 'formula-name', // Formula (CLI) or '--cask name' (GUI)
// ... add other distros
},
unavailableReason?: 'Markdown install instructions'
}
3. Unavailable Reason Guidelines
This field renders Markdown when a target is missing. It serves as the manual fallback instruction.
Requirements:
- Actionable: Avoid "Not available". State the alternative (e.g., "Install via Flatpak").
- Linked: Hard-link the solution (Flathub page, upstream .deb URL, or Wiki guide).
- Format: Use standard Markdown for links
[text](url)and code`cmd`.
Examples:
| Status | Message | Why? |
|---|---|---|
| ❌ Bad | 'Not available.' |
Dead end. No solution provided. |
| ❌ Bad | 'Download from website.' |
Dead end. No solution provided. |
| ✅ Good | 'Not in official repos. Use the [Flatpak version](https://flathub.org/apps/com.spotify.Client) instead.' |
Directs to the preferred supported alternative. |
| ✅ Good | 'Arch requires [multilib](https://wiki.archlinux.org/title/Official_repositories#multilib) enabled: uncomment `[multilib]` in `/etc/pacman.conf`, run `sudo pacman -Syu`, then `sudo pacman -S steam`.' |
Exact steps to enable the required repo. |
4. Platform Specific Rules
Arch Linux
- Official Packages: Use the package name directly if found in
coreorextra(e.g.,firefox). - Automatic AUR Detection:
src/lib/aur.tsautomatically detects suffixes-bin,-git, or-appimage. Use the name directly (e.g.,brave-bin). - Manual AUR Detection: For AUR packages without suffixes (e.g.,
google-chrome), you must add the name tosrc/lib/aur-packages.json. - Prefer
-binsuffix packages in AUR (pre-built, faster install)
NixOS
Nixpkgs requires explicit user consent for unfree software.
- Check the license on search.nixos.org.
- If the license is unfree, add it to
src/lib/nix-unfree.jsonif missing. - Add the package to
data.tsnormally.
Ubuntu/Debian
Strict Repository Policy: The generation scripts do not enable extra repositories (like PPAs or non-free by default). Packages must be available in the standard enabled repositories.
- Allowed:
- Ubuntu: Main, Restricted
- Debian: Main
- Prohibited:
- PPAs (Personal Package Archives).
- External
.debURLs. - Packages requiring manual
sources.listmodification (unless detailed inunavailableReason).
Flatpak
- ID Format: Always use the full Application ID (reverse-DNS style).
- ✅ Correct:
org.mozilla.firefox - ❌ Wrong:
firefox
- ✅ Correct:
- Verification: Find the exact ID at the bottom of the app's Flathub page.
- Note:
verified-flatpaks.jsonis auto-generated; do not edit it manually.
Snap
- Classic Confinement: If the snap requires classic confinement (access to host system files), append
--classic.- Example:
code --classic - Check the install command on snapcraft.io to confirm.
- Example:
- Verification: If the publisher has a "Verified" badge on Snapcraft:
- Add the publisher name to
src/lib/verified-snaps.json. - This enables the "Verified" badge in the TuxMate UI.
- Add the publisher name to
Homebrew
Homebrew (macOS/Linux) has two package types. Check formulae.brew.sh to find the correct one.
- Formula: Standard CLI tools and libraries.
- Usage: Use the package name directly.
- Example:
'wget','node','python@3.12'
- Cask: GUI applications and large binaries (macOS only).
- Usage: Prefix with
--cask(note the space). - Example:
'--cask firefox','--cask visual-studio-code'
- Usage: Prefix with
- Validation:
- Run
brew search <name>locally to confirm type. - We skip
--casktargets on Linux installs automatically.
- Run
5. Icon System
We use Iconify.
Helper Functions:
si('slug', '#color')for Simple Icons (Brands).lo('slug')for Logos (Multi-colored).mdi('name', '#color')for Material Design.
External URLs Rules: If an icon is missing from Iconify:
- Use a Direct SVG URL (preferred) or high-res PNG (min 64x64).
- Must be hosted on a stable domain (Wikimedia, GitHub Raw, Official Site).
- Do not use temporary URLs or hotlink-protected sites.
6. Valid Categories
Use exactly one of these:
- Web Browsers • Communication • Media • Creative • Gaming • Office
- Dev: Languages • Dev: Editors • Dev: Tools
- Terminal • CLI Tools • VPN & Network • Security • File Sharing • System
Adding Distributions
Adding a new distribution involves three main steps:
1. Register the Distribution
Edit src/lib/data.ts:
- Add the new ID to the
DistroIdtype definition. - Add a new object to the
distrosarray with:id: unique identifier.name: Display name.iconUrl: Icon for the distro selector.color: Brand color.installPrefix: The default command prefix (e.g.,sudo dnf install -y).
2. Create the Generator Script
Create a new file src/lib/scripts/<distroId>.ts. This file must export a function (e.g., generateFedoraScript) that takes PackageInfo[] and returns the generated shell script string.
- Use helpers from
shared.tslikegenerateAsciiHeaderandPackageInfo. - Implement logic to check if a package is already installed.
- Implement the installation command loop using
with_retryfor robustness. - See
src/lib/scripts/fedora.tsorubuntu.tsfor clean examples.
3. Integrate the Generator
- Export your new function in
src/lib/scripts/index.ts. - Import it in
src/lib/generateInstallScript.ts. - Add a case for your
distroIdin theswitchstatement insidegenerateInstallScript. - Also add the simple one-liner command logic in
generateSimpleCommandwithin the same file.
🔀 Pull Request Checklist
Core Principles
Important
Your PR will be rejected if you violate these rules:
- Verify Everything: Submit only verified package names. Guessing is prohibited.
- Official First: Use official repository packages over third-party options.
- No Unofficial Repos: Do not include PPAs, COPRs, or unofficial repositories.
- Full IDs: Use full IDs for Flatpaks (e.g.,
org.mozilla.firefox).- Strict Casing: Package names are case-sensitive.
- Link Integrity: Ensure all links in
unavailableReasonare direct and working.
Verification Steps
Verify before submitting:
- Package names verified on official search pages (Repology, Arch, etc).
- Case sensitivity checked (especially openSUSE).
- Arch packages verified (Official vs AUR).
- No PPAs used for Debian/Ubuntu; Main/Universe only.
- Flatpak IDs are full reverse-DNS style.
- Snap
--classicflag verification. - Nix unfree packages added to JSON.
- Homebrew Casks prefixed correctly.
npm run lint&npm run testpassed.
📝 Templates
Pull Request Template
## Summary
Brief description of changes.
## Changes
| App Name | Category | Sources |
|----------|----------|---------|
| Example | Dev: Tool| apt, pacman |
## Verification
> Package names verified against official sources.
| Source | Link |
|--------|------|
| Repology | [Link](...) |
| Arch | [Link](...) |
| ... | ... |
## Testing
- [ ] `npm run dev` working
- [ ] `npm run build` passed
## Screenshots (if applicable)
<!-- Add screenshots for UI changes -->
Issue Template (Bug Report)
## 🐛 Bug Report
**Environment**:
- OS: [e.g. Arch Linux]
- Browser: [e.g. Firefox 120]
**Steps to Reproduce**:
1. ...
2. ...
**Details**:
**Logs/Screenshots**:
[Paste console logs or attach screenshots]