diff --git a/build/packages/shared.packages b/build/packages/shared.packages index 39888d9..c6b5f61 100644 --- a/build/packages/shared.packages +++ b/build/packages/shared.packages @@ -13,7 +13,7 @@ dropbox dropbox-cli github-copilot-cli hyprshade -lmstudio +lmstudio-bin localsend localsend-bin minecraft-launcher diff --git a/pkgbuilds/shared/lmstudio-bin/.SRCINFO b/pkgbuilds/shared/lmstudio-bin/.SRCINFO new file mode 100644 index 0000000..7901035 --- /dev/null +++ b/pkgbuilds/shared/lmstudio-bin/.SRCINFO @@ -0,0 +1,23 @@ +pkgbase = lmstudio-bin + pkgdesc = LM Studio - A desktop app for exploring and running large language models locally + pkgver = 0.4.2 + pkgrel = 2 + url = https://lmstudio.ai + install = lmstudio-bin.install + arch = x86_64 + license = EULA + depends = fuse2 + depends = zlib + depends = hicolor-icon-theme + depends = gtk3 + depends = nss + depends = libxcrypt-compat + options = !strip + source = https://installers.lmstudio.ai/linux/x64/0.4.2-2/LM-Studio-0.4.2-2-x64.AppImage + source = lmstudio.png + source = lmstudio.desktop + sha256sums = 2711a5aa0b2e2dc5bcd66388727b551521efd7dcd2168b880a1833fde81cf89d + sha256sums = 9f791789c959a11316328692807737a5f1bc1c170ae99ec04c56bfd8ee8263e5 + sha256sums = d5ac11aae025cd1cc0f9aa0713ee427dc6f46e4d1adac2a5948f93d8bbca705f + +pkgname = lmstudio-bin diff --git a/pkgbuilds/shared/lmstudio-bin/.gitignore b/pkgbuilds/shared/lmstudio-bin/.gitignore new file mode 100644 index 0000000..515c66a --- /dev/null +++ b/pkgbuilds/shared/lmstudio-bin/.gitignore @@ -0,0 +1,9 @@ +pkg/ +src/ +*.AppImage +*.tar.gz +*.tar.xz +*.log +squashfs-root/ +__pycache__/ +*.pkg.tar.zst diff --git a/pkgbuilds/shared/lmstudio-bin/LMStudio-bin Blueprint.md b/pkgbuilds/shared/lmstudio-bin/LMStudio-bin Blueprint.md new file mode 100644 index 0000000..cd84b65 --- /dev/null +++ b/pkgbuilds/shared/lmstudio-bin/LMStudio-bin Blueprint.md @@ -0,0 +1,102 @@ +PROJECT BLUEPRINT: lmstudio-bin Maintenance Framework + +1. Executive Summary + +Project Name: lmstudio-bin + +Target Platform: Arch Linux (AUR) + +Upstream Software: LM Studio (Proprietary AppImage) + +This project provides an Arch User Repository (AUR) package for LM Studio. It employs a "Maintenance Bridge" architecture to convert dynamic upstream releases into deterministic, security-verified Arch Linux packages while adhering strictly to Arch Linux packaging standards for binary software. + +2. Core Objectives + +Correct Naming Convention: Utilize the -bin suffix as mandated by AUR guidelines for software distributed as pre-compiled binaries. + +Replacement of Legacy Packages: Explicitly provide and conflict with the abandoned lmstudio package to ensure a clean migration path for the community. + +Security & Determinism: Implement strict SHA256 checksum verification for every release, preventing "moving target" build failures. + +Full Desktop Integration: Ensure high-resolution icon support, XDG-compliant desktop entries, and taskbar grouping (StartupWMClass). + +3. Technical Architecture + +A. The Maintenance Engine (update_package.py) + +The heart of the project is a Python-based automation script that manages the lifecycle of a release. + +URL Resolution: Follows the latest redirect to identify the specific build version. + +Verification: Downloads the AppImage and calculates the SHA256 hash. + +Template Rendering: Injects metadata into PKGBUILD.template to produce a valid PKGBUILD. + +Metadata Generation: Automatically updates .SRCINFO for AUR indexing. + +B. Packaging Logic (PKGBUILD) + +The build process follows a specific lifecycle to ensure stability: + +Extraction Stage: Uses --appimage-extract within a temporary sandbox to access internal assets. + +Icon Strategy (Static Vendoring): +* Static Icon: The high-resolution (512x512) icon is vendored as `lmstudio.png` in the base repository. +* Optimization: Icons must be optimized to stay under the 500KB AUR repository blob limit. +* Rationale: Static vendoring prevents build-time extraction failures and ensures consistent visual presentation across versions without relying on internal AppImage layout stability. + +Binary Placement: Installs the AppImage to /opt/lm-studio/ and provides a symbolic link at /usr/bin/lm-studio. + +C. Lifecycle Management (.install) + +The .install script ensures the host system recognizes changes immediately upon installation, upgrade, or removal by triggering: + +update-desktop-database (Applications menu) + +gtk-update-icon-cache (Visual assets) + +4. Automation Workflow (For Orchestrator Reference) + +When updating to a new version, the orchestrator should follow this sequence: + +Sync: Pull latest changes from the AUR remote. + +Execute: Run ./update_package.py to fetch upstream changes and regenerate files. + +Validate: * Verify PKGBUILD version matches upstream. + +Run makepkg -f to test the build locally. + +Inspect pkg/ directory to ensure icon assets are present at /usr/share/icons/hicolor/512x512/apps/lmstudio-bin.png. + +Publish: * Refresh .SRCINFO (makepkg --printsrcinfo > .SRCINFO). + +Commit PKGBUILD, .SRCINFO, lmstudio.desktop, lmstudio.png, and lmstudio-bin.install. + +Push to origin master. + +5. Git Hygiene & AUR Constraints + +* Blob Limit: The AUR imposes a strict 512KB limit on individual file blobs. All vendored assets (like `lmstudio.png`) must be optimized to comply. +* Tracking Restrictions: Only source-of-truth files and metadata are permitted in the repository. Tracking of `src/` or `pkg/` directories is strictly prohibited. +* Verification: Use `verify_git_hygiene.sh` to audit the repository state before pushing to the AUR remote. + +6. Directory Structure + +. +├── PKGBUILD # Generated Arch Linux build script +├── PKGBUILD.template # Blueprint for the maintenance engine +├── .SRCINFO # AUR metadata index (auto-generated) +├── lmstudio.desktop # Desktop integration file +├── lmstudio.png # Static vendored icon (512x512) +├── lmstudio-bin.install # Post-install hooks for cache clearing +├── update_package.py # The Maintenance Engine script +├── verify_git_hygiene.sh # Hygiene enforcement script +└── LMStudio-bin Blueprint.md # This reference document + + +7. Maintenance Contacts & Authority + +Maintainer: madgoat (AUR) + +Package URL: https://aur.archlinux.org/packages/lmstudio-bin diff --git a/pkgbuilds/shared/lmstudio-bin/PKGBUILD b/pkgbuilds/shared/lmstudio-bin/PKGBUILD new file mode 100644 index 0000000..fd6b746 --- /dev/null +++ b/pkgbuilds/shared/lmstudio-bin/PKGBUILD @@ -0,0 +1,41 @@ +# Maintainer: noureddinex +pkgname=lmstudio-bin +pkgver=0.4.2 +pkgrel=2 +_pkgver=${pkgver}-${pkgrel} +pkgdesc="LM Studio - A desktop app for exploring and running large language models locally" +arch=('x86_64') +url="https://lmstudio.ai" +license=('EULA') +depends=('fuse2' 'zlib' 'hicolor-icon-theme' 'gtk3' 'nss' 'libxcrypt-compat') +options=('!strip') +install=lmstudio-bin.install +source=("https://installers.lmstudio.ai/linux/x64/${_pkgver}/LM-Studio-${_pkgver}-x64.AppImage" + "lmstudio.png" + "lmstudio.desktop") +sha256sums=('2711a5aa0b2e2dc5bcd66388727b551521efd7dcd2168b880a1833fde81cf89d' + '9f791789c959a11316328692807737a5f1bc1c170ae99ec04c56bfd8ee8263e5' + 'd5ac11aae025cd1cc0f9aa0713ee427dc6f46e4d1adac2a5948f93d8bbca705f') + +prepare() { + chmod +x "${srcdir}/${source[0]##*/}" +} + +package() { + # Create installation directory + install -dm755 "$pkgdir/opt/lm-studio" + + # Install AppImage + install -Dm755 "${srcdir}/${source[0]##*/}" "$pkgdir/opt/lm-studio/lm-studio.AppImage" + + # Install static icon + install -Dm644 "${srcdir}/lmstudio.png" "${pkgdir}/usr/share/icons/hicolor/512x512/apps/lmstudio-bin.png" + install -Dm644 "${srcdir}/lmstudio.png" "${pkgdir}/usr/share/pixmaps/lmstudio-bin.png" + + # Desktop entry + install -Dm644 "$srcdir/lmstudio.desktop" "$pkgdir/usr/share/applications/lmstudio.desktop" + + # Symlink to binary + install -dm755 "$pkgdir/usr/bin" + ln -s /opt/lm-studio/lm-studio.AppImage "$pkgdir/usr/bin/lm-studio" +} diff --git a/pkgbuilds/shared/lmstudio-bin/PKGBUILD.template b/pkgbuilds/shared/lmstudio-bin/PKGBUILD.template new file mode 100644 index 0000000..4728874 --- /dev/null +++ b/pkgbuilds/shared/lmstudio-bin/PKGBUILD.template @@ -0,0 +1,39 @@ +pkgname=lmstudio-bin +pkgver={{version}} +pkgrel=1 +pkgdesc="LM Studio - A desktop app for exploring and running large language models locally" +arch=('x86_64') +url="https://lmstudio.ai" +license=('EULA') +depends=('fuse2' 'zlib' 'hicolor-icon-theme' 'gtk3' 'nss' 'libxcrypt-compat') +options=('!strip') +install=lmstudio-bin.install +source=("{{url}}" + "lmstudio.png" + "lmstudio.desktop") +sha256sums=('{{sha256}}' + '{{icon_sha256}}' + 'SKIP') + +prepare() { + chmod +x "${srcdir}/${source[0]##*/}" +} + +package() { + # Create installation directory + install -dm755 "$pkgdir/opt/lm-studio" + + # Install AppImage + install -Dm755 "${srcdir}/${source[0]##*/}" "$pkgdir/opt/lm-studio/lm-studio.AppImage" + + # Install static icon + install -Dm644 "${srcdir}/lmstudio.png" "${pkgdir}/usr/share/icons/hicolor/512x512/apps/lmstudio-bin.png" + install -Dm644 "${srcdir}/lmstudio.png" "${pkgdir}/usr/share/pixmaps/lmstudio-bin.png" + + # Desktop entry + install -Dm644 "$srcdir/lmstudio.desktop" "$pkgdir/usr/share/applications/lmstudio.desktop" + + # Symlink to binary + install -dm755 "$pkgdir/usr/bin" + ln -s /opt/lm-studio/lm-studio.AppImage "$pkgdir/usr/bin/lm-studio" +} diff --git a/pkgbuilds/shared/lmstudio-bin/lmstudio-bin.install b/pkgbuilds/shared/lmstudio-bin/lmstudio-bin.install new file mode 100644 index 0000000..752e987 --- /dev/null +++ b/pkgbuilds/shared/lmstudio-bin/lmstudio-bin.install @@ -0,0 +1,14 @@ +post_install() { + update-desktop-database -q + gtk-update-icon-cache -ftq /usr/share/icons/hicolor +} + +post_upgrade() { + update-desktop-database -q + gtk-update-icon-cache -ftq /usr/share/icons/hicolor +} + +post_remove() { + update-desktop-database -q + gtk-update-icon-cache -ftq /usr/share/icons/hicolor +} diff --git a/pkgbuilds/shared/lmstudio-bin/lmstudio.desktop b/pkgbuilds/shared/lmstudio-bin/lmstudio.desktop new file mode 100644 index 0000000..e007ca8 --- /dev/null +++ b/pkgbuilds/shared/lmstudio-bin/lmstudio.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Name=LM Studio +GenericName=Large Language Model Studio +Comment=A desktop app for exploring and running large language models locally +Exec=lm-studio %U +Icon=lmstudio-bin +Type=Application +Categories=Development;ArtificialIntelligence; +Terminal=false +StartupNotify=true +StartupWMClass=LM Studio +MimeType=text/plain; diff --git a/pkgbuilds/shared/lmstudio-bin/lmstudio.png b/pkgbuilds/shared/lmstudio-bin/lmstudio.png new file mode 100644 index 0000000..082d6d6 Binary files /dev/null and b/pkgbuilds/shared/lmstudio-bin/lmstudio.png differ diff --git a/pkgbuilds/shared/lmstudio-bin/update_package.py b/pkgbuilds/shared/lmstudio-bin/update_package.py new file mode 100644 index 0000000..37bc736 --- /dev/null +++ b/pkgbuilds/shared/lmstudio-bin/update_package.py @@ -0,0 +1,204 @@ +#!/usr/bin/env python3 +""" +LM Studio PKGBUILD Maintenance Engine + +Resolves dynamic upstream link, extracts version, calculates SHA256, +and generates PKGBUILD from template. + +Updated to handle: +- AppImage file with calculated sha256 +- .desktop file with 'SKIP' (locally managed) +- Static icon (lmstudio.png) with calculated sha256 +- .install file staging and template rendering +""" + +import re +import hashlib +import requests +import subprocess +import tarfile +from pathlib import Path +from typing import Tuple, List + + +def resolve_download_url(redirect_url: str = "https://lmstudio.ai/download/latest/linux/x64") -> str: + """ + Follow redirects to resolve the final download URL. + Uses HEAD request to avoid downloading the full file. + """ + print(f"Resolving download URL: {redirect_url}") + + session = requests.Session() + response = session.head(redirect_url, allow_redirects=True) + response.raise_for_status() + + final_url = response.url + print(f"Resolved URL: {final_url}") + return final_url + + +def extract_version(filename: str) -> str: + """ + Extract semantic version from filename using regex. + Expected format: LM-Studio-X.Y.Z-x64.AppImage or LM-Studio-X.Y.Z-R-x64.AppImage + Extracts only X.Y.Z portion (pkgrel handled separately in PKGBUILD). + """ + match = re.search(r'LM-Studio-([\d.]+)-(?:\d+-)?x64\.AppImage', filename) + if match: + return match.group(1) + raise ValueError(f"Could not extract version from filename: {filename}") + + +def calculate_sha256(file_path: str) -> str: + """ + Calculate SHA256 checksum of a file. + Handles both AppImage and icon files with identical hashing logic. + """ + print(f"Calculating SHA256 for: {file_path}") + + sha256_hash = hashlib.sha256() + with open(file_path, "rb") as f: + for byte_block in iter(lambda: f.read(4096), b""): + sha256_hash.update(byte_block) + + checksum = sha256_hash.hexdigest() + print(f"SHA256: {checksum}") + return checksum + + +def download_file(url: str, file_path: str) -> None: + """ + Download file from URL if it doesn't already exist. + """ + path = Path(file_path) + if path.exists(): + print(f"File already exists: {file_path}") + return + + print(f"Downloading: {url}") + response = requests.get(url, stream=True) + response.raise_for_status() + + with open(file_path, "wb") as f: + for chunk in response.iter_content(chunk_size=8192): + if chunk: + f.write(chunk) + + print(f"Downloaded: {file_path}") + + +def stage_install_file() -> None: + """ + Ensure lmstudio-bin.install file exists and is staged. + """ + install_path = Path("/home/madgoat/Documents/LMStudio-bin Aur/lmstudio-bin.install") + + if install_path.exists(): + print(f"✓ Install file present: {install_path}") + else: + print(f"Warning: Install file not found at {install_path}") + + +def render_template(template_path: str, output_path: str, version: str, url: str, sha256: str, icon_sha256: str) -> None: + """ + Render PKGBUILD from template by replacing placeholders. + + Placeholders: + - {{version}}: Semantic version extracted from filename + - {{url}}: Resolved download URL + - {{sha256}}: SHA256 checksum of the AppImage + - {{icon_sha256}}: SHA256 checksum of the static icon (lmstudio.png) + + The template includes sha256sums array with appimage hash, icon hash, and SKIP for .desktop file. + """ + print(f"Rendering template: {template_path} -> {output_path}") + + with open(template_path, "r") as f: + content = f.read() + + content = content.replace("{{version}}", version) + content = content.replace("{{url}}", url) + content = content.replace("{{sha256}}", sha256) + content = content.replace("{{icon_sha256}}", icon_sha256) + + with open(output_path, "w") as f: + f.write(content) + + print(f"Generated: {output_path}") + + +def generate_srcinfo() -> None: + """ + Generate .SRCINFO using makepkg --printsrcinfo. + """ + print("Generating .SRCINFO...") + + result = subprocess.run( + ["makepkg", "--printsrcinfo"], + capture_output=True, + text=True, + cwd="/home/madgoat/Documents/LMStudio-bin Aur" + ) + + if result.returncode != 0: + raise RuntimeError(f"makepkg failed: {result.stderr}") + + with open("/home/madgoat/Documents/LMStudio-bin Aur/.SRCINFO", "w") as f: + f.write(result.stdout) + + print("Generated: .SRCINFO") + + +def main(): + """ + Main maintenance engine workflow. + """ + print("=== LM Studio PKGBUILD Maintenance Engine ===\n") + + # Change to workspace directory + import os + os.chdir("/home/madgoat/Documents/LMStudio-bin Aur") + + # Step 1: Resolve download URL + final_url = resolve_download_url() + + # Step 2: Extract filename and version + filename = final_url.split("/")[-1] + version = extract_version(filename) + print(f"Detected version: {version}\n") + + # Step 3: Download file if missing + download_file(final_url, filename) + + # Step 4: Calculate SHA256 for AppImage + sha256 = calculate_sha256(filename) + print() + + # Step 5: Calculate SHA256 for static icon (lmstudio.png) + # Uses identical hashing logic as AppImage + icon_hash = calculate_sha256("lmstudio.png") + print() + + # Step 6: Stage install file + stage_install_file() + print() + + # Step 7: Render PKGBUILD from template + # The template uses {{sha256}} for the AppImage hash and {{icon_sha256}} for icon hash + # and the sha256sums array in the template includes both hashes plus 'SKIP' for .desktop file + render_template("PKGBUILD.template", "PKGBUILD", version, final_url, sha256, icon_hash) + print() + + # Step 8: Generate .SRCINFO + generate_srcinfo() + + print("\n=== Maintenance Engine Complete ===") + print(f"Version: {version}") + print(f"URL: {final_url}") + print(f"AppImage SHA256: {sha256}") + print(f"Icon SHA256: {icon_hash}") + print(f"SHA256sums: ('{sha256}' '{icon_hash}' 'SKIP')") + + +if __name__ == "__main__": + main() diff --git a/pkgbuilds/shared/lmstudio-bin/verify_git_hygiene.sh b/pkgbuilds/shared/lmstudio-bin/verify_git_hygiene.sh new file mode 100755 index 0000000..d9f5478 --- /dev/null +++ b/pkgbuilds/shared/lmstudio-bin/verify_git_hygiene.sh @@ -0,0 +1,100 @@ +#!/bin/bash +# Git Hygiene Verification Guard +# Updated: Explicitly allows lmstudio.png, verifies exclusion of src/ and pkg/ from history and staged index + +echo "=== Git Hygiene Verification Guard ===" +echo "" + +# Color codes +RED="\033[0;31m" +GREEN="\033[0;32m" +YELLOW="\033[1;33m" +NC="\033[0m" + +FAIL=0 + +# Check 1: Verify lmstudio.png is NOT ignored (explicitly allowed) +echo "Check 1: Verifying lmstudio.png is tracked/allowed..." +if git ls-files lmstudio.png 2>/dev/null | grep -q "lmstudio.png"; then + echo -e "${GREEN}✓ PASSED: lmstudio.png is tracked${NC}" +elif ! git check-ignore lmstudio.png 2>/dev/null; then + echo -e "${GREEN}✓ PASSED: lmstudio.png is not ignored${NC}" +else + echo -e "${YELLOW}⚠ WARNING: lmstudio.png appears to be in .gitignore${NC}" +fi +echo "" + +# Check 2: Verify src/ folder is NOT in git history +echo "Check 2: Verifying src/ folder is NOT in git history..." +SRC_IN_HISTORY=$(git log --all --full-history --name-only --format="" -- 'src/' 2>/dev/null | wc -l) +if [ "$SRC_IN_HISTORY" -gt 0 ]; then + echo -e "${RED}✗ FAILED: src/ folder found in git history${NC}" + FAIL=1 +else + echo -e "${GREEN}✓ PASSED: src/ folder is clean from history${NC}" +fi +echo "" + +# Check 3: Verify pkg/ folder is NOT in git history +echo "Check 3: Verifying pkg/ folder is NOT in git history..." +PKG_IN_HISTORY=$(git log --all --full-history --name-only --format="" -- 'pkg/' 2>/dev/null | wc -l) +if [ "$PKG_IN_HISTORY" -gt 0 ]; then + echo -e "${RED}✗ FAILED: pkg/ folder found in git history${NC}" + FAIL=1 +else + echo -e "${GREEN}✓ PASSED: pkg/ folder is clean from history${NC}" +fi +echo "" + +# Check 4: Verify src/ folder is NOT in staged index +echo "Check 4: Verifying src/ folder is NOT in staged index..." +SRC_STAGED=$(git diff --cached --name-only -- 'src/' 2>/dev/null | wc -l) +if [ "$SRC_STAGED" -gt 0 ]; then + echo -e "${RED}✗ FAILED: src/ folder has staged files${NC}" + git diff --cached --name-only -- 'src/' + FAIL=1 +else + echo -e "${GREEN}✓ PASSED: src/ folder is clean from staged index${NC}" +fi +echo "" + +# Check 5: Verify pkg/ folder is NOT in staged index +echo "Check 5: Verifying pkg/ folder is NOT in staged index..." +PKG_STAGED=$(git diff --cached --name-only -- 'pkg/' 2>/dev/null | wc -l) +if [ "$PKG_STAGED" -gt 0 ]; then + echo -e "${RED}✗ FAILED: pkg/ folder has staged files${NC}" + git diff --cached --name-only -- 'pkg/' + FAIL=1 +else + echo -e "${GREEN}✓ PASSED: pkg/ folder is clean from staged index${NC}" +fi +echo "" + +# Check 6: Verify no AppImages or packages are staged +echo "Check 6: Verifying NO binary extensions are staged..." +BINARY_STAGED=$(git diff --cached --name-only | grep -E "\.(AppImage|zst|tar\.gz)$" | wc -l) +if [ "$BINARY_STAGED" -gt 0 ]; then + echo -e "${RED}✗ FAILED: Binary files are staged!${NC}" + git diff --cached --name-only | grep -E "\.(AppImage|zst|tar\.gz)$" + FAIL=1 +else + echo -e "${GREEN}✓ PASSED: No binary extensions staged${NC}" +fi +echo "" + +# Check 7: Review staged changes +echo "Check 7: Reviewing staged changes summary..." +git diff --cached --stat +echo "" + +# Final result +echo "=== Verification Summary ===" +if [ "$FAIL" -eq 0 ]; then + echo -e "${GREEN}✓ All hygiene checks PASSED${NC}" + echo "Repository is ready for commit." + exit 0 +else + echo -e "${RED}✗ Some hygiene checks FAILED${NC}" + echo "Please fix the issues before committing." + exit 1 +fi diff --git a/pkgbuilds/shared/lmstudio-bin/verify_system.sh b/pkgbuilds/shared/lmstudio-bin/verify_system.sh new file mode 100755 index 0000000..ae151c9 --- /dev/null +++ b/pkgbuilds/shared/lmstudio-bin/verify_system.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# LM Studio AUR Package Verification Script +# Updated: Checks for vendored lmstudio.png in root, makes /usr/share checks informative in dev environments + +echo "=== LM Studio AUR Verification ===" +echo "" + +# 1. Vendored Icon Existence Check (Primary) +echo "[1/4] Checking Vendored Icon..." +if [ -f "./lmstudio.png" ]; then + echo "✓ Found vendored lmstudio.png in root" +else + echo "✗ MISSING: vendored lmstudio.png in root" + exit 1 +fi +echo "" + +# 2. System Icon Installation Check (Informative) +echo "[2/4] Checking System Icon Installation..." +if [ -f "/usr/share/pixmaps/lmstudio-bin.png" ]; then + echo "✓ Found lmstudio-bin pixmap icon in /usr/share" +else + echo "ℹ INFO: lmstudio-bin pixmap not in /usr/share (expected in non-installed dev environment)" +fi +echo "" + +# 3. Desktop File Verification +echo "[3/4] Verifying Desktop Entry..." +ICON_NAME=$(grep "^Icon=" lmstudio.desktop | cut -d'=' -f2) +if [ "$ICON_NAME" == "lmstudio-bin" ]; then + echo "✓ Desktop Icon name matches: $ICON_NAME" +else + echo "✗ Desktop Icon mismatch: $ICON_NAME (expected lmstudio-bin)" + exit 1 +fi +echo "" + +# 4. PKGBUILD Consistency +echo "[4/4] Verifying PKGBUILD Icon Mapping..." +grep -q "lmstudio.png" PKGBUILD +if [ $? -eq 0 ]; then + echo "✓ PKGBUILD contains lmstudio.png mapping" +else + echo "✗ PKGBUILD missing icon installation logic" + exit 1 +fi +echo "" + +echo "=== SYSTEM GREEN ===" diff --git a/pkgbuilds/shared/lmstudio/.SRCINFO b/pkgbuilds/shared/lmstudio/.SRCINFO deleted file mode 100644 index 1664afb..0000000 --- a/pkgbuilds/shared/lmstudio/.SRCINFO +++ /dev/null @@ -1,20 +0,0 @@ -pkgbase = lmstudio - pkgdesc = Discover, download, and run local LLMs - pkgver = 0.3.35.1 - pkgrel = 1 - url = https://lmstudio.ai/ - arch = x86_64 - license = LicenseRef-EULA - makedepends = squashfs-tools - makedepends = graphicsmagick - depends = zlib - depends = hicolor-icon-theme - depends = fuse2 - depends = clblast - noextract = lmstudio-0.3.35.1.AppImage - options = !strip - options = !debug - source = lmstudio-0.3.35.1.AppImage::https://installers.lmstudio.ai/linux/x64/0.3.35-1/LM-Studio-0.3.35-1-x64.AppImage - sha256sums = ad9bf98e91ff13b5eea1d26f1457c8d7c4bed24bbb419551d5cbff4840380953 - -pkgname = lmstudio diff --git a/pkgbuilds/shared/lmstudio/.nvchecker.toml b/pkgbuilds/shared/lmstudio/.nvchecker.toml deleted file mode 100644 index 1d5a5a5..0000000 --- a/pkgbuilds/shared/lmstudio/.nvchecker.toml +++ /dev/null @@ -1,3 +0,0 @@ -[lmstudio] -source = "cmd" -cmd = "curl -sIL -o /dev/null -w '%{url_effective}\\n' https://lmstudio.ai/download/latest/linux/x64 | sed -E 's|.*x64/([0-9]+\\.[0-9]+\\.[0-9]+)-([0-9]+).*|\\1.\\2|'" diff --git a/pkgbuilds/shared/lmstudio/PKGBUILD b/pkgbuilds/shared/lmstudio/PKGBUILD deleted file mode 100644 index 7750fda..0000000 --- a/pkgbuilds/shared/lmstudio/PKGBUILD +++ /dev/null @@ -1,69 +0,0 @@ -# Maintainer: envolution -# Contributor: SoleSoul -# shellcheck shell=bash disable=SC2034,SC2154 - -pkgname=lmstudio -_appname=lm-studio -pkgver=0.3.35.1 -_pkgver="${pkgver%.*}-${pkgver##*.}" -pkgrel=1 -pkgdesc="Discover, download, and run local LLMs" -arch=('x86_64') -url="https://lmstudio.ai/" -license=('LicenseRef-EULA') -depends=('zlib' 'hicolor-icon-theme' 'fuse2' 'clblast') -makedepends=('squashfs-tools' 'graphicsmagick') -options=(!strip !debug) -_appimage="${pkgname}-${pkgver}.AppImage" -source=("${_appimage}::https://installers.lmstudio.ai/linux/x64/${_pkgver}/LM-Studio-${_pkgver}-x64.AppImage") -sha256sums=('ad9bf98e91ff13b5eea1d26f1457c8d7c4bed24bbb419551d5cbff4840380953') -noextract=("${_appimage}") - -prepare() { - rm -rf squashfs-root - chmod +x "${_appimage}" - # get the files we need for packaging - offset=$(./"${_appimage}" --appimage-offset) - unset PAGER # unsquashfs is very picky about pager settings - unsquashfs -q -o "$offset" -d squashfs-root "${_appimage}" \ - "${_appname}.desktop" \ - "usr/share/icons/hicolor/0x0/apps/lm-studio.png" \ - "LICENSE.electron.txt" \ - "LICENSES.chromium.html" - # unsquashfs -o "$offset" -l "${_appimage}" | grep -i license -} - -build() { - # Adjust .desktop so it will work outside of AppImage container - sed -i -E "s|Exec=AppRun|Exec=env DESKTOPINTEGRATION=false /usr/bin/${pkgname}|" \ - "squashfs-root/${_appname}.desktop" - sed -i -E "s|Icon=.*|Icon=${pkgname}|" \ - "squashfs-root/${_appname}.desktop" -} - -package() { - # AppImage - install -Dm755 "${srcdir}/${_appimage}" "${pkgdir}/opt/${pkgname}/${_appname}.AppImage" - install -Dm644 "${srcdir}/squashfs-root/LICENSE"* -t "${pkgdir}/usr/share/licenses/${pkgname}" - install -Dm644 /dev/stdin "$pkgdir/usr/share/licenses/$pkgname/EULA" <<< "https://lmstudio.ai/app-terms" - - - # Desktop file - install -Dm644 "${srcdir}/squashfs-root/${_appname}.desktop" \ - "${pkgdir}/usr/share/applications/${pkgname}.desktop" - - #source icon from squashfs - src_icon="$srcdir/squashfs-root/usr/share/icons/hicolor/0x0/apps/lm-studio.png" - sizes=("16x16" "32x32" "48x48" "64x64" "128x128" "256x256") - - # Loop through each size and create resized icons - for size in "${sizes[@]}"; do - install -dm755 "${pkgdir}/usr/share/icons/hicolor/$size/apps" - gm convert "$src_icon" -resize "$size" "$pkgdir/usr/share/icons/hicolor/$size/apps/${pkgname}.png" - done - - # Symlink executable - install -dm755 "${pkgdir}/usr/bin" - ln -s "/opt/${pkgname}/${_appname}.AppImage" "${pkgdir}/usr/bin/${pkgname}" -} -# vim:set ts=2 sw=2 et: