猫のアイコンと配布チャネル別のアプリ行を備えた、DuoUpdaterのネイティブmacOSメニューバー更新リスト。

DuoUpdater:それぞれの配布チャネルを尊重するネイティブmacOSアップデーター

DuoUpdaterはMacにインストールされたアプリをスキャンし、Sparkle、App Store、Homebrew、GitHub、ベンダー固有のチャネルを使い分け、置き換えを検証してロールバックも残します。

要点
  • DuoUpdaterはApple SiliconとmacOS 15以降向けのネイティブSwiftメニューバーアプリで、インストール済みアプリの実際の更新チャネルを調べます。
  • Mac App Store、Xcode Releases、Sparkle、Homebrew、GitHub Releases、Alcove、選別したベンダーendpointを決められた順序で確認します。
  • バンドルを置き換える前に署名、Team ID、bundle ID、実行可能アーキテクチャを確認し、バックアップ、再確認、ロールバックを行えます。
  • 最新のv0.4.1 notarized macOS ZIPはGitHub Releasesで配布され、初回導入後はSparkle appcastで自身も更新します。

Macのアプリ更新は、すべて同じダウンロード経路で処理する必要がありません。Sparkleアプリにはappcastがあり、App StoreアプリはAppleが管理し、HomebrewとGitHubのプロジェクトにはそれぞれの配布方式があります。自分のアップデーターを起動しなければならないアプリもあります。DuoUpdaterの出発点は明快です。アプリが本当に使うチャネルを見つけ、そのチャネルが許す方法で更新します。

プロジェクトのリポジトリは jizhi0v0/duo-updater で、Swiftで書かれています。ライセンスは MIT です。現在確認できる最新リリースは DuoUpdater 0.4.1 で、Apple Silicon MacのmacOS 15以降を対象にしています。

解決する問題

DuoUpdaterはメニューバーアプリです。/Applications、/Applications/Utilities、~/Applicationsをスキャンし、インストール済みアプリを一覧にします。各行は更新の有無だけでなく、現在のバージョン、目標バージョン、更新チャネル、ボタンを押したときに実際に行われる操作を示します。ディスク上だけ更新され、実行中のコピーが古いままなら、再ダウンロードではなくRelaunchを表示します。

Homebrewがインストールした非.appの項目も別の行にします。コマンドラインformula、フォント、ドライバーなどです。アプリバンドルを入れるcaskは通常のアプリ行として扱われるため、一覧で二重に数えられません。「インストールしたもの」をFinderで見える.appだけに限定しない設計です。

アプリを選ぶとrelease notesも表示されます。Sparkle appcastとGitHub Releaseは、バージョン、日付、変更点を比較的きれいに取り出せます。それ以外はアプリごとのrecipeを使い、ベンダーのページを解析できない場合は、理解したふりをせず、永続化しない WKWebView に戻します。

アプリ自身のチャネルで更新する

READMEに示される順序は意図的に固定されています。Mac App Store、Xcode Releases、Sparkle、Homebrew Cask、GitHub Releases、Alcove、最後に選別されたベンダーendpointです。最初にアプリを認識できたソースが回答し、「対象外」なら次へ進みます。JetBrains Toolbox管理アプリとTestFlightビルドは、このチェーンの外で別に扱われます。

チャネルを尊重するとは、すべてのアプリをZIPとしてダウンロードして強制置換しないということです。Sparkleは公開鍵がある場合にEdDSAを使うネイティブ経路、自動更新アプリは自身のupdater、Homebrewアプリはcask、App Storeは mas と特権helperを使います。GitHubやベンダーのダウンロードは、明示的なルールがインストール可能なアセットを検証した場合だけです。

更新前の安全確認

DuoUpdaterが自分でインストールするバンドルには、ソース確認に加えてコード署名、Team ID、bundle ID、実行可能アーキテクチャの確認があります。Apple SiliconアプリがIntel専用ビルドへ置き換わることも防ぎます。インストール直前にディスク上のバンドルを再読込し、ソースにも再問い合わせするため、古い一覧から重複インストールすることを避けられます。

更新前にロールバック用バックアップを保存でき、設定では自動再起動も選べます。実行中アプリを強制終了することはありません。通常の terminate() を呼ぶだけなので、アプリが保存確認を出して拒否できます。その場合も更新済みバンドルはディスクに残り、Restart操作が表示されるため、未保存の作業を犠牲にしません。

メジャーアップグレードには警告が出ます。商用アプリでは新しいライセンスが必要になることがあるためです。.pkg/.mpkgにも境界があります。システムインストーラーに渡した後はパッケージの署名、Team ID、保存先、OSバージョンは確認できますが、内部のすべてのMach-Oアーキテクチャを検査したり、インストーラー後に自動でアーキテクチャを戻したりはしません。

App Store、TestFlight、権限

App Storeアプリは通常のダウンロードリンクではありません。DuoUpdaterは mas とバックグラウンドhelperで完全なダウンロードを処理できます。helperが未承認だったり地域制限があったりする場合は、ディープリンクまたはApp Storeの更新画面へ戻し、地域ロックも表示します。helperはmacOSのLogin Items & Extensionsで一度許可する必要があります。

TestFlight betaは独立した設定です。オフならTestFlightのデータを読みません。オンにすると、更新確認やRefreshの操作でTestFlightを短時間バックグラウンド起動することがあります。TestFlightの候補ビルドとCotEditorのチャネルを読むにはFull Disk Accessが必要ですが、通常のアプリ一覧や更新確認には必要ありません。

権限は機能ごとに分かれています。何も許可しなくてもアプリ一覧、バージョン確認、release notesは見られます。App Managementは/Applicationsの置き換え、Notificationsは通知とDock badge、AccessibilityはGUI経由のApp Store操作やインストーラーウィンドウを閉じる場合だけに使われます。「検出できる」と「インストールできる」を混同しない設計です。

Release Logは更新一覧以上のもの

検出した各バージョンを記録し、使っているソフトウェアがいつリリースされたかを後から見られるようにします。Sparkle、GitHub、Alcove、electron-builder manifestが時刻を明示した場合だけ正確な時刻を表示します。バージョンしかないソースでは、旧版を最後に見た時点と新版を初めて見た時点の推定ウィンドウを ≈ 付きで示します。

これにより、ヒートマップが推測を事実として扱いません。ベンダーが新バージョンを公開したことは確かでも、公開時刻をクライアントへ渡さない場合があります。DuoUpdaterは変化を見た証拠を保存し、検出時刻を公開時刻のように見せません。構造化されたrelease notesがあれば、選択したアプリの横にネイティブな文章として表示します。

v0.4.1のRelease説明にもこの保守姿勢が表れています。Sogou入力法は辞書と設定をバックアップしてワンクリック更新でき、JetBrains AirはToolboxが実際に提供するbuildを使い、名前を変更されたApp Storeコピーはどのコピーが更新を担当するかを示し、Markdownのリリースノートもネイティブなリストになります。

同じエンジンを使うduo CLI

リポジトリはメニューバーUIだけではありません。duo CLIは本物の DuoUpdaterCore にリンクし、同じソース順、インストールポリシー、ignore、skipルールを使います。CLIとGUIの判断が食い違うなら、別仕様ではなくバグです。主なコマンドは duo list、duo check --json、duo install Cursor、duo doctor、duo backups です。

duo list                     # list installed apps without network access
duo check --json             # one JSON object per line
duo install Cursor           # install one update, or use --all
duo doctor                   # check whether this Mac can install
duo backups                  # list or restore rollback points

CLIは --source sparkle,github,…、--include-hidden、duo ignore、duo skipにも対応します。ただしApp Store更新は明確に拒否します。CLIにはアプリbundle、特権helper、Accessibilityの経路がないためです。メニューバーアプリがインストール中でもロックを強制取得しません。半端な処理を続けないこと自体が安全境界です。

プライバシー:自前のテレメトリーサーバーはない

プロジェクトはtelemetry、analytics SDK、自前サーバーを使わないと説明しています。ネットワーク要求はチェック対象のベンダー、api.github.com、formulae.brew.shへ直接送られ、バージョン確認に必要な情報だけを持ちます。全アプリのバージョンを一つのクラウドデータベースへ集める方式より、通信先を説明しやすいモデルです。

ただし「テレメトリーがない」は「外部データを一切読まない」という意味ではありません。CleanShot Xが入っていれば設定の activationKey を読み、自身のendpointへ個別appcastを要求します。TablePlusのbeta設定など、アプリごとのチャネル設定も読まれます。GitHub tokenは環境変数または gh auth token から取得され、api.github.com にだけ送られ、外部ドメインへのリダイレクトでは除去されます。

これらは機能単位で確認すべき境界です。ユーザーが入力したGitHub tokenやAlcove licenseはログインKeychainに保存されます。ベンダーのrelease notesは永続化しない WKWebView で表示され、再起動後もcookieを残しません。初回起動前に、自分のアプリ構成と権限設定を確認するとよいでしょう。

インストール方法

DuoUpdater自身のApp Storeページは確認できなかったため、公式の導入先は GitHub Releases です。リポジトリはnotarize済みビルドを公開すると説明しており、現在の DuoUpdater 0.4.1 macOS ZIP はApple SiliconとmacOS 15以降に対応します。

# Open the latest release page:
open https://github.com/jizhi0v0/duo-updater/releases/latest

# Or download the v0.4.1 Apple Silicon ZIP directly:
open https://github.com/jizhi0v0/duo-updater/releases/download/v0.4.1/DuoUpdater-0.4.1-macos.zip

ZIPを展開し、DuoUpdater.appを/Applicationsへ移します。初回起動でApp Management、通知、その他の機能に必要な権限を選びます。権限なしでも検出は続けられ、必要なインストール経路を実行するときだけmacOSが該当する許可を求めます。Apple Siliconは必須で、Intel Macは対象外です。

コードを変更するときだけソースからビルドする

通常の利用者はRelease ZIPを使うのがよいでしょう。更新エンジンを研究したりメニューバー画面を変更したりする場合、リポジトリはCore、アプリ、CLIに分かれています。DuoUpdaterCore/ は独立してテストできるSwift Package、App/ はXcodeGenで生成するSwiftUI MenuBarExtra アプリ、CLI/ は duo コマンドです。

# Build and test the core package:
cd DuoUpdaterCore
swift build
swift test

# Generate the macOS app project:
cd ../App
xcodegen generate
open DuoUpdater.xcodeproj

現在のソースビルドにはSwift 6.4、つまりXcode 27のツールチェーンが必要です。デプロイ先はmacOS 15のままです。自分のビルドを/Applicationsへ入れる場合は make install がReleaseを作り、安定したDeveloper ID署名で標準の場所へ配備します。Forkで自分のチームを使うなら、先に DUO_TEAM_ID=YOURTEAMID を設定します。

ソースビルドだから署名を省略できるわけではありません。特権helperとアプリは実際の署名からTeam IDを導き、未署名またはad-hocのビルドは接続を拒否します。これにより、身元が固定されていないアプリがroot helperと通信することを防ぎます。公開リリースにはApple notarytoolの認証情報が必要ですが、通常の利用者には不要です。

限界

DuoUpdaterはすべてのMacソフトを自動更新できる万能データベースではありません。GitHub Release、ベンダーendpoint、recipeはページ構造の変更で壊れます。そのため、すべてのアプリを大まかに扱うのではなく、検証済みのアプリルールを保守する方針です。明確なインストール可能アセットがなければ、適当なファイルを選ばず検出だけに留めるか、元ページを開きます。

システムインストーラー、地域制限、App Store helper、TestFlightのデータ権限、アプリ自身の保存確認も最終結果に影響します。一つの画面へまとめることはできますが、ライセンス、ネットワーク、アカウント、macOS権限をベンダーの代わりに解決するものではありません。

ライセンス

DuoUpdaterは MIT License です。コードの確認、変更、商用利用ができ、再配布時には著作権とライセンス表示を残します。リポジトリ内の mas、Sparkle、swift-subprocess、ベンダーサービス、更新対象の第三者アプリにはそれぞれのライセンスや利用条件があり、メインリポジトリのMITだけで置き換えることはできません。

インストールすべき人

Apple Silicon Macを使い、アプリの更新を一か所で確認したい一方、Sparkle、Homebrew、GitHub、App Storeを同じダウンロードモデルに押し込みたくないなら、DuoUpdaterはv0.4.1から試す価値があります。強みはチャネル認識、インストール直前の再確認、失敗後のロールバックです。Apple Silicon限定、macOS権限への依存、recipeとベンダーページの変化という制約も明確です。

プロジェクト情報

ライセンス
MIT
対応環境
macOS 15以降 / Apple Siliconのみ
実装言語
Swift 6.4、SwiftUI、AppKit、Swift Package Manager
確認したバージョン
v0.4.1(GitHub Release、2026-09-21確認)

インストール

# Open the latest GitHub Release:
open https://github.com/jizhi0v0/duo-updater/releases/latest

# Download the current Apple Silicon macOS ZIP:
open https://github.com/jizhi0v0/duo-updater/releases/download/v0.4.1/DuoUpdater-0.4.1-macos.zip

ライセンスの概要

リポジトリはMIT Licenseで公開されています。再配布時には著作権表示とライセンス表示を残してください。バンドルされたツール、フレームワーク、ベンダーフィード、第三者アプリには個別の条件があります。