{"id":28443668,"url":"https://github.com/alexykn/sps2","last_synced_at":"2025-06-29T14:31:45.843Z","repository":{"id":296519717,"uuid":"991931531","full_name":"alexykn/sps2","owner":"alexykn","description":"atomic package manager for macos","archived":false,"fork":false,"pushed_at":"2025-06-22T20:37:54.000Z","size":265371,"stargazers_count":29,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-22T21:26:47.395Z","etag":null,"topics":["macos","package-manager","rust","state-management"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexykn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-28T11:12:44.000Z","updated_at":"2025-06-22T20:37:57.000Z","dependencies_parsed_at":"2025-05-31T20:33:53.945Z","dependency_job_id":"37b247f3-5bb9-40ed-992e-3ac8c779653c","html_url":"https://github.com/alexykn/sps2","commit_stats":null,"previous_names":["alexykn/sps2"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/alexykn/sps2","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexykn%2Fsps2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexykn%2Fsps2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexykn%2Fsps2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexykn%2Fsps2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexykn","download_url":"https://codeload.github.com/alexykn/sps2/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexykn%2Fsps2/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262608786,"owners_count":23336564,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["macos","package-manager","rust","state-management"],"created_at":"2025-06-06T08:08:07.973Z","updated_at":"2025-06-29T14:31:45.824Z","avatar_url":"https://github.com/alexykn.png","language":"Rust","funding_links":[],"categories":["Rust","macos"],"sub_categories":[],"readme":"# sps2\n\nA modern, atomic package manager for macOS ARM64 with rollback capabilities and hermetic builds.\n\n## Early Development Notice\n\n**This project is in the early stages of development.** It is not yet recommended for production use. The API, package format, and internal architecture are still subject to change. There is no public package repository yet.\n\n### Current Status\n\n- ✅ **Working**: `install`, `uninstall`, `rollback`, `history`, `list`, `vulndb update`, `check-health`\n- 🚧 **In Progress**: `draft` and `build` (functional but incomplete)\n- ⚠️ **Untested**: `update`, `upgrade`, `info`, `search`, `reposync`, `cleanup`, `audit`, `self-update`\n\n## Features\n\n- 🔄 **Atomic Updates** - All package operations are atomic with instant rollback\n- 📦 **Content-Addressed Storage** - Deduplication via BLAKE3 hashing\n- 🏗️ **Hermetic Builds** - Reproducible builds in isolated environments\n- 🔐 **Security First** - Minisign signatures, SBOM generation, CVE scanning\n- 🚀 **Fast \u0026 Parallel** - Concurrent downloads and installations\n- 🎯 **Single Prefix** - Clean design with everything in `/opt/pm/live/`\n- 🐍 **Python-Style Versions** - Familiar version constraints (`\u003e=1.2.0,\u003c2.0.0`)\n- 📝 **YAML Recipes** - Declarative, staged build definitions\n\n## Installation\n\n### Prerequisites\n\n- macOS with Apple Silicon\n- Rust 1.87.0 or later\n- SQLite 3.x\n- sudo access for `/opt/pm` directory\n\n### Build from Source\n\n```bash\n# Clone the repository\ngit clone https://github.com/yourusername/sps2.git\ncd sps2\n\n# Build the project\ncargo build --release\n\n# Run setup script (requires sudo)\nsudo ./setup.sh\n\n# Add to PATH in your shell config\necho 'export PATH=\"/opt/pm/live/bin:$PATH\"' \u003e\u003e ~/.zshrc\nsource ~/.zshrc\n\n# Verify installation\nsps2 --version\n```\n\n## Quick Start\n\n### Installing Packages\n\n**Some working .sp packages in the test_build/ dir. Layout is messy, will eventually clean that up.**\n\n```bash\n# Install from repository (when available)\nsps2 install jq\n\n# Install specific version\nsps2 install \"jq==1.7\"\n\n# Install with version constraints\nsps2 install \"curl\u003e=8.0.0,\u003c9.0.0\"\n\n# Install from local .sp file\nsps2 install ./package-1.0.0-1.arm64.sp\n\n# Build and install\nsps2 build my-package.yml\n\n# Build without installing\nsps2 build my-package.yml -o ./packages/\n```\n\n### Generating Build Recipes\n\nUse the `draft` command to automatically generate recipes:\n\n```bash\n# From a Git repository\nsps2 draft -g \"https://github.com/BurntSushi/ripgrep\"\n\n# From a source archive URL\nsps2 draft -u \"https://example.com/package-1.0.tar.gz\"\n\n# From a local directory\nsps2 draft -p ./my-project\n\n# From a local archive\nsps2 draft -a ./my-archive.tar.gz\n\n# Specify output file\nsps2 draft -g \"https://github.com/helix-editor/helix\" -o helix.yml\n```\n\n### Building Packages\n\nExample recipe for ripgrep (generated by `draft`):\n\n```yaml\nmetadata:\n  name: ripgrep\n  version: \"14.1.1\"\n  description: \"Line-oriented search tool that recursively searches for regex patterns\"\n  license: \"MIT\"\n  homepage: \"https://github.com/BurntSushi/ripgrep\"\n\nenvironment:\n  network: true     # Cargo needs network for dependencies\n\nsource:\n  git:\n    url: \"https://github.com/BurntSushi/ripgrep\"\n    ref: \"14.1.1\"\n\nbuild:\n  system: cargo\n  args: [\"--release\"]\n```\n\nBuild with various options:\n\n```bash\n# Basic build\nsps2 build ripgrep.yml\n\n# Build with custom output directory\nsps2 build ripgrep.yml -o ./packages/\n\n# Build with maximum compression\nsps2 build ripgrep.yml --max\n\n# Build with custom job count\nsps2 build ripgrep.yml -j 8\n```\n\n### Managing Packages\n\n```bash\n# List installed packages\nsps2 list\n\n# Example output:\n# ┌─────────┬─────────┬───────────┬─────────────┐\n# │ Package ┆ Version ┆ Status    ┆ Description │\n# ╞═════════╪═════════╪═══════════╪═════════════╡\n# │ bat     ┆ 0.25.0  ┆ Installed ┆ -           │\n# ├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤\n# │ helix   ┆ 25.1.1  ┆ Installed ┆ -           │\n# ├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤\n# │ ripgrep ┆ 14.1.1  ┆ Installed ┆ -           │\n# └─────────┴─────────┴───────────┴─────────────┘\n\n# Show package info\nsps2 info jq\n\n# Search for packages\nsps2 search rust\n\n# Update packages (respects version constraints)\nsps2 update\n\n# Upgrade to latest versions\nsps2 upgrade curl\n\n# Uninstall packages\nsps2 uninstall jq\n```\n\n### State Management\n\n```bash\n# View state history\nsps2 history\n\n# Example output:\n# ┌────────────────────────┬─────────┬───────────┬──────────────────┬──────────┐\n# │ State ID               ┆ Current ┆ Operation ┆ Created          ┆ Packages │\n# ╞════════════════════════╪═════════╪═══════════╪══════════════════╪══════════╡\n# │ 48b6f85f-78bb-4dc5-... ┆ *       ┆ install   ┆ 2025-06-13 16:12 ┆ 4        │\n# ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤\n# │ a7be49ca-a976-4f75-... ┆         ┆ install   ┆ 2025-06-13 16:11 ┆ 3        │\n# └────────────────────────┴─────────┴───────────┴──────────────────┴──────────┘\n\n# Rollback to previous state\nsps2 rollback\n\n# Rollback to specific state\nsps2 rollback 48b6f85f-78bb-4dc5-9487-a8a60e97423b\n\n# Clean up orphaned packages and old states\nsps2 cleanup\n\n# Check system health\nsps2 check-health\n```\n\n### Security Features\n\n```bash\n# Update vulnerability database\nsps2 vulndb update\n\n# Show vulnerability database statistics\nsps2 vulndb stats\n\n# Audit installed packages for vulnerabilities\nsps2 audit\n\n# Audit specific package\nsps2 audit --package curl\n\n# Fail on critical vulnerabilities\nsps2 audit --fail-on-critical\n```\n\n### Repository Management\n\n```bash\n# Sync repository index\nsps2 reposync\n\n# Update sps2 itself\nsps2 self-update\n```\n\n## How It Works\n\nsps2 uses an innovative atomic update system:\n\n1. **Content-Addressed Store** - All package files are stored by their BLAKE3 hash\n2. **State Directories** - Each system state is a complete filesystem tree\n3. **Atomic Swaps** - Updates use APFS clones and atomic renames\n4. **Instant Rollback** - Previous states are preserved and can be restored instantly\n\n### Directory Structure\n\n```\n/opt/pm/\n├── live/          # Current active state (add /opt/pm/live/bin to PATH)\n├── store/         # Content-addressed package storage\n├── states/        # Historical states for rollback\n└── state.sqlite   # Package database\n```\n\n## Building Your Own Packages\n\nsps2 uses YAML format for package recipes with declarative, staged build definitions. See [Build Script Documentation](BUILD_SCRIPT_DOCUMENTATION.md)\n\n### Example: Rust Application (Helix Editor)\n\n```yaml\nmetadata:\n  name: helix\n  version: \"25.1.1\"\n  description: \"A post-modern modal text editor\"\n  license: \"MIT\"\n  homepage: \"https://github.com/helix-editor/helix\"\n\nenvironment:\n  network: true     # Cargo needs network access\n\nsource:\n  git:\n    url: \"https://github.com/helix-editor/helix\"\n    ref: \"25.1.1\"\n\nbuild:\n  system: cargo\n  args: [\"--release\"]\n```\n\n### Example: Meson Project (pkgconf)\n\n```yaml\nmetadata:\n  name: pkgconf\n  version: \"2.4.3\"\n  description: \"A system for managing library compile/link flags\"\n  license: \"ISC\"\n  homepage: \"https://github.com/pkgconf/pkgconf\"\n\nsource:\n  git:\n    url: \"https://github.com/pkgconf/pkgconf\"\n    ref: \"pkgconf-2.4.3\"\n\nbuild:\n  system: meson\n  args: [\"--buildtype=release\"]\n```\n\n### Example: Building from Source Archive\n\n```yaml\n# sps2 build recipe for curl\n#\n# This recipe builds curl from source archive.\n# It enables support for OpenSSL, zlib, and nghttp2 (for HTTP/2).\n\nmetadata:\n  name: curl\n  version: \"8.14.1\"\n  description: \"Command-line tool for transferring data with URLs\"\n  license: \"MIT\"\n  homepage: \"https://curl.se\"\n  dependencies:\n    runtime:\n      - openssl\n      - zlib\n      - nghttp2\n      - brotli\n      - libssh2\n      - libidn2\n      - libpsl\n\nenvironment:\n  defaults: true    # Optimized flags for macOS ARM64\n\nsource:\n  fetch:\n    url: \"https://github.com/curl/curl/releases/download/curl-8_14_1/curl-8.14.1.tar.bz2\"\n    checksum:\n      sha256: \"2893f7b7614192c2a4d8289f3d0009798a7c5f5d895011b5e4c0cf910c4a8b1e\"\n\nbuild:\n  system: cmake\n  args:\n    - \"-DCMAKE_BUILD_TYPE=Release\"\n    - \"-GNinja\"\n    - \"-DBUILD_SHARED_LIBS=ON\"\n    - \"-DBUILD_STATIC_LIBS=OFF\"\n    - \"-DCURL_USE_OPENSSL=ON\"\n    - \"-DCURL_ZLIB=ON\"\n    - \"-DUSE_NGHTTP2=ON\"\n    - \"-DENABLE_IPV6=ON\"\n    - \"-DCURL_USE_LIBSSH2=ON\"\n    - \"-DUSE_LIBIDN2=ON\"\n    - \"-DCURL_BROTLI=ON\"\n    - \"-DCURL_USE_LIBPSL=ON\"\n    - \"-DBUILD_TESTING=OFF\"\n    - \"-DENABLE_CURL_MANUAL=OFF\"\n\npost:\n  patch_rpaths:\n    style: homebrew  # curl needs absolute paths\n\ninstall:\n  auto: true\n```\n\n## Developer Tools\n\n### Store List (sls) - Debugging Content-Addressed Storage\n\nThe `sls` utility is a specialized debugging tool for exploring sps2's content-addressed storage system. It provides ls-like functionality for both the object store and package metadata.\n\n#### Basic Usage\n\n```bash\n# List all hash prefix directories (00-ff)\nsls\n\n# List objects with a specific hash prefix\nsls ff\n\n# List a specific object by partial hash\nsls ffff5aa9\n\n# Show full hash without filename mapping\nsls --hash ff\n```\n\n#### Object Store Exploration\n\n```bash\n# Long format with permissions and sizes\nsls -l ff\n\n# Example output:\n# -r--r--r-- 2.11 KiB ffff5aa98bd51ec0 -\u003e include/c++/15/fenv.h (gcc:15.1.0)\n# -r--r--r-- 6.46 KiB ffff1d26e56791c5 -\u003e share/man/man3/SSL_config.3ossl (openssl:3.5.0)\n\n# Recursive listing of entire store\nsls -R\n\n# Find all files from a specific package\nsls -R | grep \"bat:0.25.0\"\n\n# Find all Python files\nsls -R | grep \"\\.py \"\n\n# Find files by name pattern using ripgrep\nsls -R | rg \"libcurl.*dylib\"\n\n# Find all files from multiple packages\nsls -R | rg \"(gcc|clang|llvm):\"\n```\n\n#### Package Directory Exploration\n\n```bash\n# List all packages with their names and versions\nsls -p\n\n# Example output:\n# 0543d3aaf01da99f -\u003e bat:0.25.0\n# 098b0c7c800fd65f -\u003e autoconf:2.72.0\n# 0c0be36a37e74b78 -\u003e cmake:4.0.3\n\n# List specific package by hash prefix\nsls -p 0543\n\n# Long format for packages (shows metadata files)\nsls -p -l\n\n# Find packages by name pattern\nsls -p | grep \"python\"\n\n# Find all compiler packages using ripgrep\nsls -p | rg \"(gcc|clang|llvm|rust)\"\n```\n\n- **Object Storage**: Files stored by hash in `/opt/pm/store/objects/[first-2-chars]/[full-64-char-hash]`\n- **Package Storage**: Package Metadata stored in `/opt/pm/store/packages/[package-hash]/` with files:\n  - `manifest.toml` - Package metadata and file list\n  - `files.json` - Detailed file information\n  - `sbom.spdx.json` - Software Bill of Materials\n- **Deduplication**: Multiple packages can reference the same file hash (content deduplication)\n\n## Contributing\n\nWe welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n## Documentation\n\n- [Architecture Overview](ARCHITECTURE.md) - Detailed system design\n- [Build Script Documentation](BUILD_SCRIPT_DOCUMENTATION.md) - YAML recipe format reference\n- [Contributing Guide](CONTRIBUTING.md) - How to contribute\n- [Code of Conduct](CODE_OF_CONDUCT.md) - Community guidelines\n\n## Security\n\n- Packages are signed with [Minisign](https://jedisct1.github.io/minisign/) // TODO\n- All downloads are verified against BLAKE3 hashes [BLAKE3](https://github.com/BLAKE3-team/BLAKE3)\n- SBOM (Software Bill of Materials) generated for every package\n- Offline CVE scanning via integrated vulnerability database\n\n## License\n\nBSD 3-Clause License. See [LICENSE.md](LICENSE.md) for details.\n\n## Acknowledgments\n\nsps2 stands on the shoulders of giants:\n\n- [moss \u0026 boulder](https://github.com/AerynOS/os-tools) AerynOS - atomic updates, content-addressed storage, stateful package management\n- [Homebrew](https://brew.sh/) - Inspiration for macOS-native packaging\n- [Ansible](https://www.ansible.com/) - Inspiration for YAML format and shell/command distinction\n- [Starlark](https://github.com/bazelbuild/starlark) - Previously used for build recipes\n\n---\n\n*Building the future of package management on macOS, one atomic update at a time.*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexykn%2Fsps2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexykn%2Fsps2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexykn%2Fsps2/lists"}