個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證A native macOS download manager with adaptive parallelism — detects anti-leech CDNs, learns per-host limits, and stays out of App Nap. SwiftUI + actor-based engine.
翻譯準備中
正在載入完整 README。
檢視完整 README ↗Note: MacGet is not affiliated with or endorsed by Tonec Inc. or Internet Download Manager. It's an independent free alternative.
Most "multi-threaded" download managers naively open as many TCP connections as you let them. Modern CDNs treat that as leech behavior — they TCP-RST connections after a few bytes, throttle your IP, or 403 your requests. The result: more threads = slower downloads, sometimes failures.
MacGet's engine discovers each host's true capacity at runtime and adapts:
~/Library/Application Support/Macget/host_caps.json. Future downloads from that host start at the right level — no rediscovery cost.ProcessInfo activity is held while any download is running, so macOS doesn't throttle CPU/network when you switch apps or minimize the window..torrent files download in the same queue as everything else, several at once. Off by default; seeding is bounded by a ratio and time limit you control. MacGet doesn't search for or index torrents.@Observable view models and an actor-based engine.brew install --cask suryansh-codes2209/macget/macget
Requires macOS 26.4 or later on Apple silicon. The cask removes the quarantine attribute after install, so there is no Gatekeeper prompt and no "Open Anyway" step.
macget.dmg from the Releases page.Minimum macOS: 26.4 Tahoe.
Macget is currently distributed free and un-notarized (no paid Apple Developer account). On first launch macOS Gatekeeper will say "Macget can't be opened because Apple cannot check it for malicious software." This is expected — to open it:
Power-user one-liner instead of the steps above:
xattr -dr com.apple.quarantine /Applications/Macget.app
Auto-updates (via Sparkle) install smoothly after this one-time step.
git clone https://github.com/Suryansh-Codes2209/Macget.git
cd Macget
open Macget.xcodeproj
Then in Xcode: ⌘R to run, ⌘U to test. The .xcodeproj is committed and Sparkle is gated behind #if canImport(Sparkle), so the app builds and runs without any extra setup.
To enable auto-updates (optional): File → Add Package Dependencies… → https://github.com/sparkle-project/Sparkle (≥ 2.6.0).
After the first install you don't re-download MacGet from this page — it keeps itself current with Sparkle, the standard auto-update framework for apps distributed outside the Mac App Store.
Sparkle is gated behind
#if canImport(Sparkle). Auto-updates are active in release builds that bundle the Sparkle SPM dependency; a from-source build without it falls back to a Check for Updates… menu item that explains the dependency is missing.
Maintainers — publishing an update: cut a release (see
Release a DMG), then regenerate the signed feed
with Sparkle/bin/generate_appcast site/ and push site/. GitHub Pages serves
site/appcast.xml at the SUFeedURL above. The EdDSA private signing key
lives only in your login Keychain ("Private key for signing Sparkle updates") —
back it up offline, or you can
never sign another update for existing installs.
The download engine is the heart of the app; everything else is glue. Top-level flow for one download:
Probe (HEAD → GET Range:0-0 fallback) → Disk-space check → Plan chunks
→ Open sparse partial file → Spawn workers (staggered)
→ Stream over URLSession → 64 KB writes through FileWriter actor
→ Demote on rapid failures → Finalize → Move into place
Key types (under Macget/Engine/):
| Type | Role |
|---|---|
DownloadEngine | Top-level actor. Owns all coordinators, schedules per maxConcurrentDownloads, emits an AsyncStream<EngineEvent> to the UI. |
DownloadCoordinator | Per-download actor. Probes, plans, spawns workers, runs the orchestration loop, demotes on rapid failures. |
ChunkWorker | One HTTP-Range request, one attempt. Streams data via an AsyncThrowingStream bridge over URLSessionDataDelegate. |
ChunkPlanner / ChunkSplitter | Static planning: split bytes into ≥ 64 KB chunks, clamped to Download.maxThreadCount. |
FileWriter | Actor wrapping a FileHandle. Serializes positional writes so concurrent chunks don't race. |
RangeProbe | HEAD then ranged-GET fallback. Records Content-Length, Accept-Ranges, ETag, Last-Modified. |
SpeedMeter | 3-second rolling-window throughput + ETA. |
HostCapStore | Persistent per-host parallelism memory. Caps ratchet downward only. |
URLSessionFactory.shared | Single process-wide URLSession — responsiveData QoS, extended background idle mode, httpMaximumConnectionsPerHost = 16. |
For deeper detail, read docs/architecture.md — the full engine walkthrough, object graph, and resume semantics. CLAUDE.md holds the day-to-day conventions for contributors.
Macget/
├── Macget/ ← Swift sources
│ ├── App/ ← AppDelegate, AppEnvironment
│ ├── Models/ ← Download, Chunk, Status, Settings
│ ├── Persistence/ ← DownloadStore (queue.json), HostCapStore (host_caps.json)
│ ├── Engine/ ← ★ multi-threaded download engine
│ ├── Services/ ← Clipboard watcher, filename resolver, disk check
│ │ └── Catalog/ ← OPDS parser/client, catalog list (catalogs.json)
│ ├── Updater/ ← Sparkle wrapper (gated)
│ ├── ViewModels/ ← @MainActor @Observable
│ ├── Views/ ← SwiftUI
│ ├── Resources/ ← Info.plist, entitlements, Assets.xcassets, Branding/
│ └── Supporting/ ← os.Logger
├── MacgetTests/ ← XCTest suites (46 tests)
├── MacgetUITests/ ← XCUITest harness
├── scripts/release.sh ← build → DMG → notarize → staple
├── site/index.html ← landing page (deploy via GitHub Pages)
├── .github/workflows/ci.yml ← CI: build + test on push/PR
├── CHANGELOG.md
├── CLAUDE.md ← architecture + conventions
└── Macget.xcodeproj
# Build
xcodebuild -project Macget.xcodeproj -scheme Macget -configuration Debug build
# Run all tests
xcodebuild test -project Macget.xcodeproj -scheme Macget -destination 'platform=macOS'
# Run one test class or method
xcodebuild test -project Macget.xcodeproj -scheme Macget -destination 'platform=macOS' \
-only-testing:MacgetTests/ChunkPlannerTests
scripts/release.sh)Free, no Apple account: run ./scripts/release.sh --no-notarize. It builds an
ad-hoc-signed DMG (bundling yt-dlp + ffmpeg), skipping the Developer ID and
notarization steps. Sparkle auto-updates still work; users do the one-time
Gatekeeper "Open Anyway" from First launch on macOS.
This needs only brew install create-dmg and the Sparkle key (step 4 below).
Notarized (frictionless install) requires a paid Apple Developer account — one-time setup:
xcrun notarytool store-credentials "macget-notary" \
--apple-id "[email protected]" \
--team-id "YOUR-TEAM-ID" \
--password "<app-specific password from appleid.apple.com>"
brew install create-dmgbin/generate_keys. Copy the printed public key into Macget/Resources/Info.plist's SUPublicEDKey. Back up the private key offline.Per release:
CHANGELOG.md../scripts/release.sh from the repo root (builds, notarizes, and writes
dist/macget.dmg alongside the versioned dist/Macget-<version>.dmg).dist/macget.dmg as an asset named
exactly macget.dmg — the Sparkle appcast enclosure and the Homebrew cask
URL both depend on that exact name../scripts/publish-cask.sh to push the Homebrew cask to the
tap.Sparkle/bin/generate_appcast site/ and push site/ to GitHub Pages.The CI workflow at .github/workflows/ci.yml runs build + tests on every push/PR.
Issues and PRs welcome. The Engine/ directory is the high-stakes code — please include unit tests for any change there, and mirror the actor / @Sendable conventions described in CLAUDE.md.
MIT. See LICENSE.