新しい App アイコンが macOS 26 で正しく表示されるようになりました。 ダークスタイルで矢印とリングが塗りつぶされた塊のようにつながることはなくなり、猫の頭と耳の輪郭もギザギザせずなめらかになりました。
ワークベンチを閉じると、リリースノートが使っていたメモリが解放されるようになりました。 以前は、開いたリリースノートのページが DuoUpdater を終了するまでバックグラウンドで動き続けていました。
すべてのリリースを新しい順に掲載しています。アプリが自身をアップデートするときに表示する内容と同じです。ダウンロードはリリースページから。古いリリースは英語で表示されます。
新しい App アイコンが macOS 26 で正しく表示されるようになりました。 ダークスタイルで矢印とリングが塗りつぶされた塊のようにつながることはなくなり、猫の頭と耳の輪郭もギザギザせずなめらかになりました。
ワークベンチを閉じると、リリースノートが使っていたメモリが解放されるようになりました。 以前は、開いたリリースノートのページが DuoUpdater を終了するまでバックグラウンドで動き続けていました。
新しい App アイコン。 丸くなったシャム猫で、しっぽが更新の矢印になっています。macOS 26 以降では、選択しているライト・ダーク・カラーのアイコンスタイルに合わせて表示されます。
省データモードや従量制のネットワーク(iPhone のインターネット共有など)では、バックグラウンドの確認を待つようになりました。 通常のネットワークに戻るとすぐに実行されます。手動での確認とアップデートのインストールはこれまでどおりです。
ネットワークの一時的な不調で失敗した確認は、2 分後に一度だけ自動で再試行されます。 以前は、失敗した行と警告が次の定期確認(デフォルトでは 6 時間後)まで残っていました。
内部の改善。 リリースノートの画像が使うディスク容量が大幅に減り、リクエスト パネルで再検証のリクエストが 2 回数えられることはなくなり、Muse の確認でログインページをダウンロードすることもなくなりました。
Quark Cloud Drive のように独自のセットアップスクリプトでインストールする Homebrew の App が、ワンクリックで更新できるようになりました。 以前は毎回、インストーラパッケージが含まれていないというエラーで終わっていました。
インストーラを自分で実行する必要がある Homebrew の App は、失敗する代わりにリンク付きでアップデートを表示するようになりました。 以前は DuoUpdater がインストーラ全体をダウンロードしたあと、エラーで止まっていました。
認識できる Homebrew の App が増えました。 Visual Paradigm Community Edition のように Homebrew が別の名前でインストールする App についてもアップデートを確認するようになり、名前の似た別の App と取り違えることもなくなりました。
Homebrew の cask が取り下げられた App に、Homebrew がインストールを拒否するアップデートを勧めることはなくなりました。 代わりに、App 自身のアップデートフィードがあればそちらで確認します。
VS Code のリリースノートが再び表示されるようになりました。
内部の改善。 Antigravity と OpenLens のアップデートが別の方法で見つかった後も、設定 › 診断 に警告が残り続けることはなくなりました。
blender.org からダウンロードした Blender もアップデートを確認し、ワンクリックで更新できるようになりました。 以前は Homebrew でインストールしたものだけが確認対象でした。
Blender のアルファ版、ベータ版、リリース候補版(RC)は、それぞれ独自のトラックで更新されます。 DuoUpdater はインストールされているビルドの種類を読み取り、同じ種類の新しいビルドが出たときに知らせます。アルファ版に正式版を勧めることはなく、その逆もありません。
Muse のアップデートが再び表示されるようになりました。 Muse のダウンロードリンクがサインインを求めるようになってから、その行には新しいバージョンではなくエラーが表示されていました。
内部の改善。 起動後はじめてメニューバーのポップオーバーとワークベンチを開くときが少し速くなりました。また duo check は、すべて最新だと言う代わりに、確認に失敗した App を一覧に表示するようになりました。
DuoUpdater がイタリア語、繁体字中国語、ポルトガル語(ブラジル)、トルコ語に対応しました。 これで 11 言語になります。ドイツ語、スペイン語、日本語の誤訳や途中で切れていた表示も直しました。設定 → フォルダでは、Finder と同じようにお使いの言語でフォルダ名を表示します。
Homebrew でインストールしたアプリは、Homebrew を通して更新するようになりました。 対象は、brew でインストールされ、独自のアップデータも持っているアプリです。以前は DuoUpdater がその場で更新しても Homebrew はそれを知らず、次の brew upgrade で、すでに入っているバージョンをもう一度ダウンロードしてインストールしていました。
ウインドウはいまいる操作スペースで開きます。 以前は、設定などの DuoUpdater のウインドウを閉じてから開き直すと、最後に表示していた操作スペースに切り替わることがありました。
ひとつのアップデートには、通知もひとつだけ。 2 つのソースで確認するアプリでは、同じ新バージョンが何度も通知されることがありました。
リリースログに未来の日付のリリースが表示されなくなりました。 開発元のフィードの日付が、DuoUpdater がそのリリースを最初に見つけた時刻より後になっている場合は、見つけた時刻を使います。
バックアップディスクが外れていても、ワークベンチのウインドウが画面に収まるようになり、「今すぐコピー」はコピーできない理由を表示します。 以前はウインドウが画面より高くなってリストを最後までスクロールできず、「今すぐコピー」は押しても何も起きませんでした。
Xcode のベータ版とリリース候補版をワンクリックで更新できるようになりました。 設定 → Xcode で Apple Developer アカウントに一度サインインすれば、DuoUpdater が新しいベータ版や RC をほかのアップデートと同じようにダウンロードしてインストールします。以前は新しい版が出たことを知らせるだけでした。
どのバージョンの Xcode も、いまある Xcode と並べてインストールできます。 設定 → Xcode にはすべての Xcode リリースがバージョンごとにまとめて並び、お使いの macOS に対応するグループは最初から開いています。「インストール」を押すと、選んだ版が別のコピーとしてアプリケーションに入り(例:Xcode-26.6.app)、何も置き換えません。アーカイブ(.xip)だけを保存することもできます。サインインしていれば Apple 自身のリストも加わるので、新しいリリースが数分で現れます。
Apple Developer のサインインが自分で続くようになりました。 Apple はデベロッパのセッションを約 8 時間で終了します。DuoUpdater は、Apple がこの Mac をまだ認識している限り、ウインドウもパスワードもなしにバックグラウンドで新しいセッションを取得します。設定 → Xcode でオフにできます。
新しい Xcode のリリースが早く表示されるようになりました。 平日、Apple がふだんリリースする時間帯には、DuoUpdater が 5 分ごとに新しい Xcode を探します。
開発元の変更で動かなくなっていたいくつかのアプリが、また動くようになりました。 CapCut beta と Superconductor nightly が再び見つかってインストールできるようになり、Superconductor はいまのアプリの識別情報のままです。VLC 3.0.24 と JetBrains Air のリリースノートも再び表示されます。
Qoder CN IDE に対応しました。 Qoder の中国本土向け IDE で、アップデートの確認とワンクリックインストールができ、リリースノートもウインドウに表示されます。デスクトップアプリの Qoder CN も、リリースノートを表示するようになりました。
Qoder IDE の最新バージョンが行ったり来たりしなくなりました。 Qoder はアップデートを段階的に配信しています。DuoUpdater はお使いの IDE と同じ方法で問い合わせるようになったので、毎回同じ答えが返ります。以前は案内されるバージョンが 2 つのリリースの間で切り替わることがあり、答えが途中で変わってワンクリックインストールが途中で止まることもありました。
Sparkle で更新するアプリがダウンロードしたアップデートが古くなっていても、また更新できるようになりました。 Sparkle で自身を更新するアプリがあるビルドをダウンロードしたあとで新しいビルドが出た場合、DuoUpdater は古いダウンロードを消してから最新版をインストールします。以前は「更新」を押しても、いまインストールしても元に戻されると表示されるだけで、行は変わりませんでした。
duo install が、最新ビルドがすでに待機中であることを伝えるようになりました。 アプリ自身のアップデータが最新バージョンをダウンロード済みの場合、そのことを表示し、アプリを終了するか duo restart を実行するよう案内します。以前は、そのアプリは確認だけでインストールはできない、と誤って表示していました。
搜狗输入法 がワンクリックで更新できるようになりました。 DuoUpdater は、その入力方式が自分で更新するのと同じやり方で適用します。インストール済みのバンドルはその場所に残ります。先に辞書と設定のコピーを取るので、ロールバックすればそれらも戻ります。
別のディスクに置いたバックアップに、入力メソッドの辞書と設定も含まれるようになりました。 以前はアプリ本体だけがバックアップ用ディスクに移されていたため、そこから入力メソッドをロールバックすると、新しいバージョンのデータが残ったままになっていました。
入れられないアップデートを案内しなくなりました。 JetBrains Air は Toolbox が実際に提供しているビルドを表示するようになりました。デベロッパが名前を変えたあと古い名前のまま残った App Store のアプリには、App Store がどちらのコピーを更新しているかを表示し、もう一方のコピーを入れ直すだけのアップデートは出さなくなりました。
より多くのアプリのリリースノートが整形されて表示されるようになりました。 ノートを Markdown で公開しているアプリも、ほかのアプリと同じネイティブのリストで表示されます。以前はプレーンテキストのまま表示されていました。
「再起動」がアプリ自身のインストーラの邪魔をしなくなりました。 アプリが自分でアップデートをダウンロード済みで、ロールバック用バックアップの置き場所が外部ディスクのとき、その書き出しはインストーラが終わるまで待つようになりました。以前は、macOS がインストーラに与えるわずか数秒のあいだに動いていました。
ロールバック用のバックアップを別のディスクに置けるようになりました。 バックアップはアプリまるごとのコピーなので、起動ディスクではどんどんかさみます。設定 →「バックアップ」に接続中のディスクが空き容量とともに並び、すでにあるバックアップの移動も、これから取るバックアップのバックグラウンドでの書き出しもそこへ行えます。ディスクを外していても、ロールバックできなくなるのではなく後回しになるだけです。ターミナルでは duo backups に disks、sync、verify、probe が加わりました。
千问输入法 に対応しました。 新しいバージョンが出ると DuoUpdater が知らせ、その入力メソッド自身と同じやり方で更新します。
リリースノートが前のバージョンのまま固定されなくなりました。 開発元が変更履歴ページに載せる数分前にアップデートを公開すると、古いノートが新しいバージョンのものとして保存され、そのまま永久に残っていました。CleanShot X では 5.0.1 の公開当日から 5.0 のノートが表示され続けていました。
バックアップを削除すると、表示どおりの容量が本当に空くようになりました。 以前のバージョンの DuoUpdater が取ったバックアップは macOS が削除を拒む形で書かれていたため、「クリーンアップ」はコピーの大半をディスクに残したまま、空けた容量として数えていました。
「クリーンアップ」がすぐ開くようになりました。 以前は押すたびに、保存済みのバックアップをすべて一から測り直していました。
WorkBuddy の最新バージョンが再び表示されるようになりました。 更新サービスが最新ビルドではなくアップグレード経路の次の一段を返すため、4 つの WorkBuddy がいずれも 2 リリース前で止まっていました。
内部の改善。 どのバイナリを実行するかを宣言していないアプリ(Meta の Muse など)でも、フレームワークと SDK を読み取れるようになりました。
「再起動」で完了したアップデートもロールバックできるようになりました。 アプリが自分でアップデートをダウンロード済みで「再起動」を押したとき、DuoUpdater が先に現在のバージョンを保存するようになり、そのアップデートもほかと同じく「ロールバック」に表示されます。以前は DuoUpdater 自身がインストールしたアップデートしか元に戻せませんでした。
アップデートでアプリの中身がどう変わったかを確認できます。 以前のバージョンが保存されているアプリでは、ワークベンチの「リリースノート」の隣に「バンドル差分」ビューが加わりました。署名と権限、最低 macOS バージョン、バックグラウンド項目とログイン項目、同梱ライブラリ、追加・削除・サイズ変更されたファイルを表示します。ターミナルでは duo diff で、任意の 2 つのアプリのコピーを同じように比較できます。
アプリ自身のアップデータがアップデートを適用しなかったとき、「再起動」がそれを知らせます。 アプリが終了してもアップデートが適用されなかった場合、その行にそう表示され、引き続き「再起動」を選べます。以前はインジケータが何も言わずに止まっていました。
Cherry Studio の最新バージョンが再び表示されるようになりました。 Cherry Studio が Mac 用ダウンロードの名前を変えてから、DuoUpdater は古いリリースを最新と見なしていました。そのため新しめのコピーは「最新」と表示され、それより古いコピーにはその古いビルドが提示されていました。
応答しないヘルパーのせいで App Store のアップデートが止まらなくなりました。 以前は DuoUpdater のヘルパーが応答しなくなると、アップデートが 0% のまま止まり、後ろに並んだ App Store のアップデートも DuoUpdater を終了するまで待たされていました。
「すべて更新」で、無視したアプリを再起動しなくなりました。 「更新したアプリを自動的に再起動する」がオンのとき、まとめての更新の最後に、無視したアプリや、ダウンロード済みのバージョンをスキップしたアプリを終了して開き直すことがありました。
Tinycast と SuperCmd に対応しました。 Tinycast やそのベータに新しいバージョンが出ると DuoUpdater が知らせます。また SuperCmd 2 に加えて、オープンソースの初代 SuperCmd も認識するようになりました。Kimi Code のリリースノートも表示されるようになりました。
リリースノートが提示中のバージョンと一致するようになりました。 VS Code の最新のリリースノートページが空で表示されていたほか、新しいバージョンが出た直後には、前のリリースのノートが表示されることがありました。
「リリースログ」が起動のたびに同じリリースを重複して記録しなくなりました。 以前は Claude、Raycast、Cline などのアプリで、DuoUpdater を起動するたびに重複した項目が増えていました。
ワークベンチのサイドバーが「アプリ」「Brew」「ロールバック」の 3 つのタブに分かれました。 タブをクリックするか、タブの上をドラッグして切り替えられます。検索は 3 つすべてを同時に絞り込みます。
内部の改善。 同じアプリに対する「再起動」と「ロールバック」が互いに干渉しなくなりました。アップデートフィードによって DuoUpdater がダウンロードフォルダ以外のファイルを削除することはなくなりました。バックグラウンドのチェックで、他のアプリのデータへのアクセスを macOS が求めるおそれがなくなりました。「リクエスト」のフィルタに非常に大きな数を入力してもアプリが終了しなくなりました。duo install で拒否した管理者権限の要求を、メニューバーでも尊重するようになりました。
iStat Menus のアップデートを正しく判定するようになりました。 iStat Menus がアップデートを出し直したとき、インストール後も同じアップデートが表示され続け、もう一度「更新」を押すとエラーになることがありました。
Memoh Desktop に対応しました。 新しいバージョンが出ると DuoUpdater が知らせ、ワンクリックでアップデートできます。
「すべて更新」で、App Store がすでに開き直したアプリの再起動を求めなくなりました。 App Store がアプリを終了して新しいバージョンで開き直すと、その行はすぐに更新済みと表示されます。以前はまとめての更新がすべて終わるまで「今すぐ再起動」と表示されていました。
自分でアップデートをダウンロード済みのアプリを、もう一度ダウンロードしなくなりました。 アプリによっては、バックグラウンドでアップデートを取得し、再起動されるのを待っています。DuoUpdater で「更新」を押すと、ディスクにすでにあるコピーをインストールするようになり、アップデートは数秒で終わり、ダウンロードも発生しません。以前は同じリリースをもう一度ダウンロードしていました。
Cua Driver と Petex に対応しました。 どちらかに新しいリリースが出ると DuoUpdater が知らせます。Cua Driver はさらにワンクリックでアップデートでき、リリースノートも表示します。
同じアップデートが何度も通知されなくなりました。 開発元のサーバーが 2 つのバージョンを行き来していると、チェックのたびに新しいアップデートに見え、そのたびに通知が届いていました。
インストールし終えたパッケージが、もう一度インストールを勧めなくなりました。 以前はその行に、ダウンロード済みのパッケージをもう一度開くと表示され続けていました。
DuoUpdater には macOS 15 Sequoia 以降が必要になりました。 macOS 14 のままの Mac は今のバージョンを使い続けられますが、アップデートは提示されなくなります。Apple シリコン搭載の Mac はすべて、対応する macOS にアップグレードできます。
内部の改善。 定期チェックでダウンロードリンクを前もって解決しなくなりました。以前は、開発元のダウンロードサーバーがタイムアウトすると、正常に使える「更新」ボタンが一時的に消えることがありました。
Aside に対応しました。 Aside ブラウザの新しいビルドが出ると DuoUpdater が知らせ、そのリリースノートを表示します。
お使いの macOS で動かないアップデートは提示されなくなり、その理由が行に表示されるようになりました。 開発元がリリースごとに対応する macOS を明記している場合、DuoUpdater はそれに従います。macOS をアップグレードしたあと、Little Snitch がお使いのシステムより低い上限のビルドを提示することはなくなりました。Xcode がお使いの macOS より新しいバージョンを必要とするビルドを提示することもなくなりました。アプリがより新しい macOS を必要とするインストーラパッケージは、開けないアプリをインストールする代わりに拒否されます。以前は空白のダッシュだった行に「このmacOSにはまだ未対応」または「より新しいmacOSが必要です」と表示され、クリックすれば詳細を確認できます。
各アプリがどの SDK でビルドされたかがわかるようになりました。 アプリ名の横のマークをクリックすると、詳細にたとえば「macOS 27.0 SDK でビルドされています。」と表示されます。どのアプリが最新の macOS 向けにビルドし直されたかを見分けるのに便利です。
古いシステム向けと最新システム向けの 2 つのパッケージに分かれている Homebrew アプリを、正しい方から読み取るようになりました。 OnyX は macOS 27 でこのように分かれていますが、DuoUpdater は古いシステム向けのパッケージしか見ていませんでした。そのため OnyX がまったく表示されないか、Homebrew が 27 ではインストールを拒否するバージョンを基準に最新と判定していました。今は、インストールした方のパッケージを DuoUpdater が追跡します。
TestFlight の起動時に、ベータ版のアップデートが消えなくなりました。 新しいビルドが待っているベータ版が「最新」に戻り、TestFlight をもう一度開くまでそのままになることがありました。
Dropbox と ToDesk のワンクリックアップデートが正しいファイルをダウンロードするようになりました。 Apple シリコン搭載の Mac で、Dropbox は Intel 専用のビルドをダウンロードし、安全チェックで拒否されていました。ToDesk では、正式リリースではなく一部のユーザーにだけ配信される先行ビルドが提示されていました。
「再起動」で Spotify のアップデートがすぐに完了するようになりました。 Spotify が自分でアップデートをダウンロード済みのとき、「再起動」は数分間待たされてからようやくアップデートが適用されていました。
ベータ版がリリース版へ進めるようになりました。 Xcode のベータ版には、最新と表示される代わりにリリース候補が提示されます。CotEditor のベータ版ではリリース候補が見えるようになり、テスト期間が終わった Carbon Copy Cloner のベータ版には、確認失敗と表示される代わりに、正式リリースになったバージョンが提示されます。
リリースノートがお使いのバージョンと一致するようになりました。 Blender 5.2 では 5.1 のノートが、Raycast 1.x では 2.x のノートが表示されていました。Gemini の「ページを開く」は、エラーではなく Google の現在のデスクトップ版ページを開くようになりました。
設定では、各オプションの説明がそのすぐ隣に表示されるようになりました。 セクション全体の下にあった長い説明は、各コントロールの下の短い一行に置き換わり、ポップアップメニューは選択中の項目だけを説明します。
アプリ内の名称を DuoUpdater に統一しました。Web サイトの表記に合わせています。
信頼していない tap の Homebrew パッケージが再び表示されるようになりました。 Homebrew 6 以降、brew はインストール済みの一覧を出す際に信頼されていない tap のパッケージを黙って飛ばすため、それらは説明もなく DuoUpdater から消えていました。現在は「未確認 · tap が信頼されていません」として表示され、コピーできる brew trust コマンドが添えられます。ターミナルでそれ(またはアップグレード)を実行したあとは、ウインドウに戻った時点で反映されます。
自己アップデートに管理者パスワードが必要なアプリが、二重にアップデートされなくなりました。 Tailscale のようなアプリが自分でアップデートをダウンロード済みで再起動を待っているとき、DuoUpdater はそれを認識できずに「更新」を提示しており、アプリ自身のインストーラと衝突するおそれがありました。現在その行には「再起動」が表示され、「すべて更新」の対象からも外れます。
Homebrew セクションから Homebrew 自体をアップデートできるようになりました。 Homebrew の新しいリリースが出ると、先頭に brew update を実行する行が表示されます。HOMEBREW_NO_AUTO_UPDATE を設定している場合は表示されません。
Homebrew のアップグレードに失敗したとき、brew の実際のエラーが表示されるようになりました。 以前はエラーのあとに brew が出すアドバイスが表示されるか、何も表示されなかったため、「コマンドラインツールが古すぎる」といったメッセージが届きませんでした。複数のパッケージをまとめてアップグレードするとき、終わる前に完了と表示されることもなくなりました。
メニューバーのアイコンが 50 を超えて数えられるようになりました。 待機中のアップデートが 50 件を超えても、以前は 50 のままでした。
リリースノート:Claude のノートは Claude 自身と同じく「New」「Improved」「Fixed」に分けて表示されます。Mac Mouse Fix のノートは埋め込みページではなくテキストで表示されます。Homebrew 公式アプリのノートも表示されるようになりました。
duo check は、実際には確認できなかったときに「Everything is up to date.」と言わなくなりました。 TestFlight を読めなかったときや、アプリのスキャンが中断されたときは、そのことを伝えます。
アプリが複数の言語でリリースノートを公開している場合、お使いの言語で表示されるようになりました。 一部のアプリは各リリースのノートを翻訳付きで配信していますが、DuoUpdater はそのうち最初か最後に並んでいた翻訳をそのまま使っていたため、あるアプリのノートが誰の画面でもドイツ語で表示されたり、別のアプリではリリースごとに言語が変わったりしていました。
Mac 版が追加されたアプリが「このMacではサポートされていません」と表示されることはなくなりました。 Apple シリコンで動かしている iPhone / iPad アプリが、開発元が本物の Mac 版を出した瞬間に誤ってそう扱われていました — 更新をより利用しやすくするはずの変更が、逆に働いていたわけです。
App Store で購入し、ベータ版のテストにも参加しているアプリが、TestFlight のビルドと取り違えられることはなくなりました。 開発元がベータ版をそのまま昇格させた場合、両者のビルド番号が同じになり、購入済みのコピーが TestFlight のものとして扱われていたため、App Store から更新が提示されることがありませんでした。
今お使いの macOS より新しいバージョンを必要とする App Store の更新は、そのことを伝えるようになりました。 これまでは、その行がそれでもインストールを提示し、最後の段階で App Store に断られ、理由は画面のどこにも表示されませんでした。
「リクエスト」のウインドウが、記録が実際にどこまでさかのぼれるかを表示し、すべてを網羅できない期間にはその印を付けるようになりました。 これまでは、数時間分しか記録のない状態で「過去 30 日」を選んでも「過去 24 時間」を選んだときとまったく同じに見え、理由は画面のどこにも表示されませんでした。
TestFlight のベータ版について DuoUpdater がどこまで面倒を見るかを、設定 → 一般 で選べるようになりました。 「更新したときだけ」は TestFlight がすでに把握している内容を読み取り、「更新」を押したときに最新の情報を問い合わせます。「常に最新に」では DuoUpdater が自分からも問い合わせるため、バックグラウンドでインストールされた TestFlight のベータ版が更新するまで疑問符のままになることも、届いているビルドが「最新」の裏に埋もれて気付かれないこともなくなります。「オフ」では何も読み取らず、推測する代わりにその旨を行に表示します。すでにフルディスクアクセスを許可している Mac は「更新したときだけ」から、それ以外は「オフ」から始まります。
自分で TestFlight を開くだけで、そこで何がインストールされたかを DuoUpdater が把握できるようになりました。 TestFlight からインストールしたベータ版は、次に更新確認をするまで疑問符のままでした。macOS 27 では、すでに持っているアプリについて TestFlight の「テストの準備完了」のお知らせが届かなくなったため、それが何時間も続くことがありました。
Cline の更新が、リリース版とベータ版のどちらでも表示され、リリースノートも見られるようになりました。 これまではバージョンの代わりに疑問符が表示されていました — DuoUpdater が読める種類の更新フィードを配信しておらず、Homebrew のパッケージもないためです。DuoUpdater は Cline 自身の更新機能と同じ場所に問い合わせるようになったので、提示される更新は Cline 自身がインストールするはずのものと同じになり、ベータ版はベータ版のまま保たれます。
「追加」「修正」といった見出しごとにまとめられたリリースノートが、その見出しを保つようになりました。 これまではすべてが一つの平らな一覧にまとめられていたため、どれが新機能でどれが不具合の修正なのか分かりませんでした。
Mac Mouse Fix 自身の General 設定で「Get Beta Versions」をオンにしている場合、そのベータ版のリリースが提示されるようになりました。 これまで DuoUpdater には Mac Mouse Fix の通常のリリースしか見えなかったため、ベータ版は次の通常版が出るまで気付かれずにいました。
ビルド番号が単なる通し番号になっているアプリが、自身のパッチリリースを隠してしまうことはなくなりました。 たとえばバージョン 12.10、ビルド 282987 と報告するアプリでは、12.10.1 のリリースが「すでに最新です」と読み取られていました。
同じバージョン名のまま新しいビルドが出たときも、改めて知らせるようになりました。 一度どれかのビルドを知らせたあとは、同じ名前の後続のビルドは何も告げずに届いていました — 行は点灯し、バッジも数えていたのに、お知らせは一度も出ませんでした。
「すべて更新」が、実際に更新されたアプリだけを数えるようになりました。 仕上げに Apple のインストーラが開くアプリは、そのウインドウがまだ開いているうちから完了として数えられていたため、「2 個のアプリを更新しました」と表示されても、実際にはまだ何も変わっていないことがありました。
更新は済んだのに残骸が残った場合、「Appの管理」の許可を求めるのではなく、インストール済みとして報告されるようになりました。 新しいバージョンはすでに動いているのに、その行はシステム設定へ案内していました。
「すべて更新」を中止すると、進行中のダウンロードも止まるようになりました。 これまでは、数ギガバイトの転送が最後まで続き、さらに 5 回まで再試行してから、ようやく中止されていたことに気付いていました。
一つの更新履歴ページを共有する 2 つのアプリでリリースノートが入れ替わることはなくなり、バージョンごとのページにノートがあるアプリでも、更新後の内容が最新に保たれるようになりました。 Antigravity と Antigravity IDE は 15 分ほど互いのノートを表示することがあり、Thunderbird、WeChat、Opera などは更新後しばらく前のバージョンのノートを表示し続けていました。
アプリ一覧の検索が、設定の検索と同じようにアクセント記号を無視するようになりました。 「cafe」と入力すれば「Café」が見つかります。
「診断」のページに、リリースチャンネルごとの状態の行が並ぶようになりました。 ベータ版やプレビュー版のルールが壊れていても、正常な安定版の陰に隠れてしまっていました。
GitHub からの「アクセスできません」という応答が、レート制限として報告されることはなくなりました。 非公開になったリポジトリや、スコープの足りないトークンのときに、追加しても役に立たないトークンをすすめてしまっていました。
自分で更新するアプリで、待機中のビルドが実行中のものより古い場合には、「再起動」が提示されなくなりました。
内部の改善。 インストール、バックアップ、パッケージの確認が、アプリの他の処理が使うスレッドを占有しなくなり、実行中でもメニューの反応が保たれます。大きなダウンロードの最中もメニューは滑らかなままです。リリースログは、ベンダーが一つのバージョン名で出したすべてのリリースを数えるようになりました。アプリ自身の実行ファイルが欠けてしまうようなロールバック用のバックアップは、保存せずに拒否されます。新しい Mac での初回起動時に、意味のないデータベースのエラーが記録されることはなくなりました。duo verify と duo reconcile は、項目がつぶれてしまった更新履歴や、何日も失敗し続けているインストーラのアドレスを報告するようになりました。応答のない duo コマンドは、固まったままにならず 20 秒でスキャンを諦めます。
自分で更新するアプリの一部が、より新しいバージョンが出ているのに最新のように見えることはなくなりました。 更新情報が、反映の遅いダウンロードサーバーの先にあるアプリでは、公開から何日ものあいだ古いバージョンが見えたままになることがありました。
Kimi のリリースノートが DuoUpdater に表示されるようになりました。
CodeEdit の更新が表示されるようになりました。 これまでは、より新しい CodeEdit があっても、その行は更新を提示せずに疑問符のままでした。
内部の改善。 メニューの Homebrew の一覧がより速く埋まり、duo コマンドの起動も速くなりました。
TestFlight ベータ版で「再確認」を押すと、正しい結果が表示されるようになりました。 これまでは、次に更新確認をするまで、その行が疑問符に変わってしまっていました。
更新確認ボタンが TestFlight に問い合わせている間も、TestFlight ベータ版の結果が保たれるようになりました。 これまでは、数秒間すべてが疑問符に変わってしまうことがありました。
super.engineering に対応しました:更新の確認、リリースノート、ワンクリックのインストール。 新しいナイトリーは変更点とともに一覧に表示され、「更新」を押せばインストールまで行います。
Microsoft Edge Beta に、安定版の Edge のビルドが提示されることがありました。 Microsoft のベータ版のフィードが一時的に空になっていた間、行には安定版のバージョンが表示され、更新するとお使いのベータ版がそれで上書きされるところでした。
iPhone / iPad アプリのベータ版も含め、TestFlight ベータ版に、TestFlight が提供している更新が表示されるようになりました。 更新確認ボタンがバックグラウンドで TestFlight に問い合わせるようになり、見つけた更新が数分後に消えてしまうこともなくなりました。また、TestFlight ボタンを押すと、TestFlight でそのベータ版のページが開きます。
TestFlight ベータ版が最新かどうかを DuoUpdater が判断できないときは、そのことを伝えるようになりました。 TestFlight からサインアウトしているときや、そのベータ版のテストにもう参加していないときなどには、行は最新と呼ぶ代わりに疑問符を表示します。
フルディスクアクセスについて説明するようになり、許可していなくても繰り返し煩わされることはなくなりました。 フルディスクアクセスがなくても、DuoUpdater が他のアプリのデータ読み取りに関する macOS の警告を引き起こすことはなくなりました。TestFlight ベータ版や CotEditor にフルディスクアクセスが必要な場合は、なぜ必要なのか、どこで許可できるのかが一度だけ説明されます。
更新したアプリが終了すると、「再起動」が消えるようになりました。 終了後もヘルパーを動かしたままにするアプリは、更新がとうに反映されたあとも再起動を求め続けていました。
macOS のプライバシー確認に応答していなくても、更新の確認が止まることはなくなりました。 確認は、そのアプリの設定を使わずに続行されます。
Rockxy と Ollama のリリースノートが、また欠けることなく表示されるようになりました。 Rockxy は最新の 1 件だけでなく最近のリリースまでさかのぼって表示されるようになり、Ollama は最新のリリースが抜け落ちることがなくなりました。
任意のコマンドラインの相棒 duo が、TestFlight をよりうまく扱えるようになりました。 --refresh-testflight は、TestFlight を開いているかどうかにかかわらず、画面を奪うことなく動作します。また、TestFlight がすでに新しいビルドを告知しているのに、duo check がベータ版を最新と呼ぶことはなくなりました。
Telegram Desktop の更新確認がまた動くようになりました。 Telegram が公開するファイルの名前を変更したため、行はそこからバージョンを読み取れなくなり、後ろで待っている更新ではなくチェックの失敗を表示していました。
TestFlight から入れた iPhone / iPad アプリが、そのものとして認識されるようになりました。 DuoUpdater はそれを App Store で購入したものと読み違えていたため、行は誤った管理元を示し、そのうえ存在しない項目についてストアに問い合わせていました——チェックのたびに、そのアプリが入っている限りずっとです。
TestFlight のベータには TestFlight 自身のアイコンが付きます。 App Store が面倒を見ている行にはすでにストアのアイコンが付いていましたが、TestFlight が面倒を見ている行は名前を書き出していたため、同じ種類の行が二通りの示し方をされていました。
ネットワークウインドウのヘッダーが、タブを切り替えても動かなくなりました。 二つのタブは見出しをわずかに違う高さに置いていたため、行き来するとウインドウがぴくりと動いたように見えていました。
アプリ一覧全体のスクロールがまた滑らかになりました。 全体を素早くスクロールするとフレームが落ちていました。各行が、まず組み立てられなくても自分の高さを答えられるようになりました。
App Store のアプリのリリースノートは、必ず App Store のものになりました。 ストア自身の照会が外れたり失敗したりすると、ウインドウはそのアプリの別の配布経路のノート——独自のバージョン番号を持つ別のビルドのもの——に後退することがあり、お使いのコピーには決して提供されないリリースの説明を表示していました。
Windscribe を Beta または Guinea Pig チャンネルにしている場合、そのチャンネルのビルドが提供されます。 DuoUpdater は Windscribe 自身の設定で選んだ更新チャンネルを読むので、プレリリース系列を追っているコピーが、その系列に新しいビルドがあるのに最新だと言われることはなくなりました。ウインドウにはそれらのプレリリースビルドのノートも表示されます。以前は安定版のものしか出ていませんでした。
Windscribe が更新チェックの対象になり、リリースノートも表示されます。 古いビルドで動いているコピーには、移行できるバージョンとその変更点が並びます。以前は DuoUpdater から Windscribe のバージョンを見る手段がありませんでした。更新は引き続き Windscribe 自身のインストーラーで行われます。アプリの外側にある部分も設定するためです。
クリックしている間に消えたアプリに、更新が適用されることはなくなりました。 クリックからインストール開始までの間にそのアプリがアンインストールされたり、置き換えられたり、読み取れなくなったりした場合、DuoUpdater はその場所にそのままインストールするのではなく、停止してその旨を伝えます。
任意のコマンドラインの相棒 duo が、パッケージのインストールを終わってもいないのに完了と呼ぶのをやめました。 .pkg で配布されるアプリをインストールすると macOS のインストーラーが開き、あとはあなたに委ねられますが、要約はそれをインストール済みとして数えていました——まだ何も置き換わっていないのに「1 installed」と。これらは別々に数えられるようになりました。--json 出力も各行にそのアプリに何が起きたかのラベルを付けるので、スクリプトが失敗と意図的なスキップを見分けるために英語の説明を読む必要はもうありません。
内部の改善。 ワンクリック更新を守るインストール前の再確認が duo install も守るようになり、ダウンロードがアプリを置き換える前に通らなければならない検査は、それを使う両方の経路で一箇所にまとまりました。
更新ソースの答えが食い違ったときに「更新」を押しても何も起きない、ということがなくなりました。 クリックした瞬間に走る再確認が、行に出ていたものより古いバージョンを返した場合、DuoUpdater はそのことを伝え、アップデートを提示したままにします。以前はアプリを最新扱いにして一覧から外してしまい、同じアップデートが次の確認でまた現れていました。
Fork を Develop チャンネルに設定していても、アップデートがまた提示されます。 DuoUpdater は Fork のチャンネル設定を逆に読み、かなり遅れている Stable フィードを見ていました。そのため Develop 版は、Fork 自身がより新しいバージョンを出しているのに最新と表示されていました。
Mac Performance Monitor のリリースノートが表示されるようになりました。 このアプリはリリースノートを、こちらが読んでいるフィードではなくリポジトリ側に公開しているため、ウインドウに出せるものがありませんでした。
CotEditor に対応しました。正式版とベータ版、どちらのラインにも対応しています。 どちらのラインをたどるかは、動作中のバージョンと、CotEditor 自身の「Update to prereleases when available」設定から判断します。ベータ版には、バージョンが巻き戻る正式版ではなく次のベータ版が提示されます。
App Store から入れたアプリに、別の入手先からのダウンロードが提示されることはなくなりました。 ストアへの問い合わせが失敗したり空で返ったりした場合、その行はバージョン番号を出さずに、ストアが管理していることを示します。以前は、そのアプリの別の配布経路(バージョン番号の体系が異なる別ビルド)へ流れてしまい、ストア版の上にそれを入れる提案をすることがありました。
アプリが古いバージョンに戻るようなアップデートが提示されることはありません。 フィードによっては、実際にはより先を行くプレリリース版よりも正式版が上に並ぶことがあり、それを入れるとアプリが巻き戻ってしまっていました。
行に長いエラーが出ても、一覧の残りが下に押しやられなくなりました。 2 行までに収め、全文はポインタを重ねると表示されます。
さらに 4 つの App に対応しました:WhatCable、Qoder IDE、Qoder、Yaak。 いずれも更新の確認とワンクリックのインストールに対応し、リリースノートは埋め込みのページではなくテキストとしてウインドウに読み込まれます。
Qoder の 2 つの Mac App を区別するようになりました。 IDE とデスクトップ App は名前もダウンロードページも共通ですが、別々のバージョン系列で公開されています。それぞれを個別に追うようになりました。
WhatCable と Yaak のベータ版を、専用のトラックで追うようになりました。 ベータ版を使っているコピーにはこれまで参照先がまったくなく、「失敗」のまま止まっていました。今は次のベータ版が提示され、リリースノートも正式版のものとは分けて表示されます。WhatCable では、ベータ版がやがて昇格する正式版も対象に含まれます。それを選ぶと、そのコピーは正式版のトラックへ移ります。
App Store の App の確認に使う通信量が、以前のごく一部になりました。 これまでは確認のたびに App Store の App すべての製品ページを取得し直していました。ページは 1 時間保持されるようになり、ストアへの問い合わせも App ごとに 1 回ではなく、すべての App について数回で済むようになりました。確認間隔が 5 分の場合、全体の通信量はおよそ 3 分の 1 減ります。既定の 6 時間間隔では確認と確認の間にページの保持期間が切れるため、そちらでの削減は小さくなります。
1 つの App を確認し直しても、App Store の App すべてを取得し直さなくなりました。 これまでは「再確認」を一度押すだけで保持していた製品ページをすべて破棄していたため、次の定期確認がその全部を払っていました。今は指定した App だけを更新します。
GitHub で配布される App の確認にかかる通信量も、以前のごく一部になりました。 これまでは何も公開されていなくても、確認のたびに各リリースの説明文を丸ごと取得し直していました。今は前回から変わったかどうかを GitHub に尋ね、変わっていなければ何も取得しません。1 日に 1 回は各リリースを丸ごと読み直すので、取り下げられたリリースにも 1 日以内に気づきます。
GitHub のベータやナイトリーのトラックを追っている App は、リリース一覧のページではなく 1 件だけを求めるようになりました。 ほとんどの場合は最新のリリースが答えであり、そうでない回にだけページ全体を取得します。
Vorssaint の更新の確認がリダイレクトを経由しなくなりました。 リポジトリの名前が変更されており、古い名前をたどると、リクエストは黙って GitHub の匿名レート制限に落ちていました。今は新しい名前へ直接向かいます。
内部の改善。 リリース成果物は GitHub がホストする Mac 上でビルド・署名・公証されるようになり、そのビルドの出所は誰でも検証できます。また、記録されるリクエストログは、キャッシュから返した応答とネットワークに出た応答を区別するようになりました。
書き出したリクエストログにアカウント名が含まれなくなりました。 ホームフォルダにインストールされた App の行は、これまで完全なパスをそのまま書き出していましたが、どの方法で取り出しても ~ と表示されるようになりました。
「リクエスト」タブが、何を記録し何を記録しないかを明示するようになりました。 ここに記録されるのは DuoUpdater 自身が行った取得です。リリースノートのページは画像やフォントを自分で取得し、App Store と Homebrew の更新は別のツールが行います。それらは現れません。ウインドウがそう述べるようになり、推測に委ねなくなりました。
「URL をコピー」がアドレスをエスケープしてから渡すようになりました。 スペースを含むパス(Firefox、Thunderbird、Bartender のダウンロードなど)はそのままコピーされていました。ブラウザは補ってくれますが、コマンドラインは補いません。
CapCut のベータ行が、失敗した確認として表示されなくなりました。 あるベータが正式版になり、次のベータが始まるまでの間、提供元はそのトラックに何も公開しません。これが赤い行と、押しても効かない「再試行」として現れていました。次のベータが現れるまで、その行はこのソースからの答えを持たないだけになります。
Audacity が、何で作られているかを示すマークを表示するようになりました。 起動は小さなランチャーが受け持ち、隣にある本体に引き渡します。マークはそのランチャーから読み取られていましたが、ランチャー自身は何もリンクしていません。
App Store のリリースノートがあなたの言語で表示されるようになりました。 これまではストア自身の既定の言語で取得していたため、中国語や日本語で使っている Mac でも英語のままでした。
DuoUpdater 自身の更新が、「ネットワーク」ウインドウで自身の名前の下に表示されるようになりました。 バージョンの確認、リリースノート、ダウンロードのいずれも App の列が空欄のままでした。
内部の改善。 アドレスのパスに含まれる資格情報は、リクエストが記録される前に取り除かれるようになりました。クエリ文字列のものが以前からそうであったのと同じです。
「Download Traffic」ウインドウは「ネットワーク」になり、タブが 2 つになりました。 「ダウンロード」はこれまでどおりの台帳で、各アップデートがファイルとしていくらかかったかを示します。「リクエスト」は新しく、DuoUpdater があなたの代わりに行ったすべての取得を、何のためか・どの App のものか・いくらかかったかとともに記録し、スクロールする代わりに絞り込んで質問できます。上部の数字は、そのとき絞り込んでいる範囲に対する答えで、累計ではありません。
Spotify の更新確認がネットワークをほとんど使わなくなりました。 Spotify はバージョン情報をどこにも公開していないため、確認は 2 MB のインストーラースタブからバージョンを読み取っています。これまでは毎回そのファイル全体を取得していました。今は先にファイルが変わったかどうかを尋ね、変わっていなければダウンロードしません。
PDF Expert が自身のアップデートを見つけられるようになり、変更点も表示されます。 これまでは開発元が 2022 年以降更新していないリリース一覧を読んでいたため、どのバージョンを使っていても「最新です」と表示されていました。今はアプリ自身のアップデータが使う一覧を参照し、最新版だけでなく、以前のバージョンの更新内容も表示します。
UTM のプレビュー版が独自の更新を受け取れるようになり、ワンクリックでインストールでき、対応するリリースノートも表示されます。 これまでプレビュー版は正式版と比較され、何も告げずに「最新です」と表示されていました。今は自分の系列を追い、その系列の正式版を受け取った時点で正式トラックに戻ります。
内部的な変更。 記録されたリクエストがダウンロード台帳と同じ保存先に移り、1 つのダウンロードに対する 2 つの記録が食い違うことがなくなりました。既存の台帳はそのまま引き継がれます。
さらに 15 個のアプリを更新チェックの対象にしました。1 つを除いてワンクリックで更新できます。 AgentsView、AnythingLLM、Chatbox、ChatGPT Classic、DSH Desktop、FluidVoice、GitHub Copilot、Kun、Meetily、Microsoft 365 Copilot、OpenLogi、OpenSuperWhisper、Paseo、T3 Code(alpha と nightly の両方)、Vorssaint です。例外は ChatGPT Classic で、更新の有無は確認しますが、アプリ自身を更新するインストーラが同梱されているため、その 1 つだけはご自身で実行していただく形になります。
8 個のアプリのリリースノートが、Web ページを開かずに DuoUpdater の中で読めるようになりました。 Xcode、Antigravity、Antigravity IDE、AnyDesk、AnythingLLM、Chatbox、Headlamp、Helium です。このうち 3 つは、そもそも開くべきページがありませんでした。AnyDesk のページはボット判定を返し、Helium の開発元はノートのページを公開しておらず、Antigravity IDE にはリンク自体がありませんでした。
Xcode のベータ版が、各ベータで何が変わったかを示すようになりました。 これまでは行にビルド番号とリンクが出るだけでしたが、いまはお使いのベータと、その同じバージョンのそれ以前のすべてのベータについて、Apple のリリースノートを並べて表示します。
Word、Excel、PowerPoint、Outlook、OneNote が更新の完了を認識するようになりました。 この 5 つは、すでに終えたインストーラーを開き直すよう促し続け、再起動の案内まで進みませんでした。待っても再チェックしても解消しない状態でした。
再起動待ちの行が、また自分を説明するようになりました(両方のウインドウで)。 アプリがベンダーの公開版より新しく、かつ再起動待ちのとき、ボタンの上の行はまったく別のことを表示していました。「すべて更新」の再起動待ちの行についても、ウインドウとメニューの説明が食い違っていました。
ロシア語で、状態タグがアプリ名を押し出さなくなりました。 あわせて、すべての翻訳言語で無関係な文言を流用していたタグも直しました。
ベンダーが日付だけを示し時刻を示していないアプリでも、リリースノートが表示されます。 これまでこうしたリリースはどこにも痕跡が残りませんでした。
開くことを拒否したリリースノートのページが、その理由を伝えるようになりました。 以前は真っ白になり、ノートを公開していないアプリと見分けがつきませんでした。
微信開発者ツールの Nightly のリリースノートが空でなくなりました。
内部の変更。 バージョンとリリース日の扱いを一本化し、ビルド番号がマーケティングバージョンとして読まれることがなくなりました。リリースのタイムラインも、ベンダーが示していない時刻を作り出さなくなりました。
チェックに失敗したアプリが、ウインドウでも見えるようになりました。 これまでウインドウは、チェックに失敗した行に何も描いていませんでした。無視した行、スキップした行、App Store・Toolbox・TestFlight が管理する行も同じで、「最新」とまったく同じ見た目になっていたのです。いまは両方のウインドウが同じアプリについて同じことを言い、再試行ボタンもどちらにもあります。
どの行でも「再確認」で、そのアプリだけを問い合わせられます。 実行中のアプリも読み直すので、緑の点がおかしいと感じたときはこれが一番早い直し方です。
スキップと無視が、ウインドウの右クリックメニューからも解除できるようになりました。 どちらの行も「右クリックで解除」と案内していましたが、このウインドウのメニューにその項目がありませんでした。
バックグラウンドのチェックが、読んでいる最中のリリースノートを消さなくなりました。 1 時間ごとのチェックは読み込み済みのノートをすべて捨てていたため、開いていたリリースノートはくるくる回る表示に戻っていました。いまは自分で更新したときだけ読み直します。
中断から再開したダウンロードは、完了とみなす前に検証します。 ファイル全体を送り直すサーバーも、途中で打ち切るサーバーも、これまでは鵜呑みにしていて、問題は次の段階で「壊れたアーカイブ」として現れていました。特定のプロキシ越しでは必ず失敗していたダウンロードも通るようになりました。
1 つのアプリを更新するのに、ディスク上のすべてのアプリを読み直さなくなりました。 クリックのたびに、指定した 1 つを見るためだけに全アプリを 2 回走査していました。
Chrome のリリースノートがもう固まりません。 Google のブログのちょっとした模様替えだけで数分止まることがありましたが、ページがどんな形でもすぐ読めるようになりました。
ダウンロード済みのインストーラーを、捨てて取り直すことがなくなりました。 同じリリースを 2 通りに書くベンダー(v1.2.3 と 1.2.3)の場合、待機中のパッケージが認識されず、「再起動」がすでに終わった入れ替えを待ち続けることもありました。
管理者インストールの失敗が、キャンセル操作と取り違えられなくなりました。 エラーは何も表示されず、そのアプリはワンクリック更新を静かに提供しなくなり、行のメニューから管理者権限をもう一度求めるまで戻りませんでした。
緑色の「実行中」の点が、すべてのアプリを認識します。 起動や終了を macOS がまったく通知しないアプリがあり、その点は無関係な操作で更新されるまで間違ったままでした。
更新中に「すべて更新」ボタンが出たり消えたりしなくなり、更新のさなかに更新したアプリが、もう一度更新を促す状態に戻ることもなくなりました。
更新を押した瞬間にチェックが失敗した場合は、そう伝えます。 「やることなし」として片付けられることはもうありません。
内部の改善。 変わった書式で書かれたリリース日を正しく読めるようになり、リリースノートのページのアドレス検査があらゆる同等表記を網羅し、日々の記録処理が Mac 上でアプリが起動・終了するたびにディスクへ触れることもなくなりました。
Docker のマークが、バックグラウンドサービスではなくインターフェイス側を指すようになりました。 行には「ネイティブ」と出ていましたが、Docker Desktop は Electron アプリです。このマークはアプリのバンドルから読み取られますが、Docker のバンドルは外側の殻にすぎません。そこで名指しされているプログラムは Go で書かれたバックグラウンドサービスで、フレームワークを何も抱えておらず、実際にウインドウを描いているアプリはその一段内側にあります。読み取り自体はすべて正しく、読む先のファイルだけが違っていたわけです。DuoUpdater は、外側のバンドルが自力では何も示さず、かつ内側に技術スタックを証明できるアプリがちょうど一つだけある場合に限り、内側のアプリを見にいきます。ですから本物のインターフェイスと一緒に配られているヘルパープロセスが、自分の素性をホストに貸すことは依然としてできません。Docker は Electron 42.5.0 と表示されます。これを書いた機械にある百四十六個のアプリのうち、変わるのはこの一行だけです。
CleanShot X のリリースノートがまた読めるようになりました——5.0 の分も含めて。 CleanShot はここ数年で最大の更新を出し、それに合わせてリリースノートのページを作り直しました。日付がバージョン番号の上に移り、番号の外側に二層が増え、機能リリースではバージョンと変更点リストのあいだに紹介文と動画リンクが二つ入るようになっています。DuoUpdater が使っていた読み取り規則は、そのどれにも一致しなくなりました。空欄より厄介だったのは、空に見えなかったことです。前のリリースについて保存済みだったノートがそのまま画面に残り、新しいバージョンの見出しの下に並んでいました——つまり「5.0」という見出しの下に 4.8.10 の変更点が出ていて、それを知らせるものはどこにもありませんでした。
リリース公開前に保存されたノートを、いつまでも信用せず読み直すようになりました。 これは同じ話のもう半分です。DuoUpdater は、CleanShot が 5.0 の内容を公開する六分前に 5.0 の存在を知り、その時点のページをそのまま保存して 5.0 の名前で控えました——以後どの確認も「すでに保存済み」を見つけるだけで、二度と見にいきませんでした。保存済みのノートは確定として扱う前に、起動ごとに一度ベンダーへ確認するようになったので、ノートが遅れて出たバージョンも次に開いたときに自分で埋まります。間違ったまま残ることはありません。
メニューバーから開くものが、一回目のクリックで開くようになりました。 行の「更新履歴」——あるいは設定やリリースログ——を選んでも一回目はまったく反応がなく、二回目からしか動きませんでした。メニューを開き直すと毎回それが「一回目」に戻るので、メニューを開いて一度クリックしてウインドウを待つ人にとっては、一度も動いたことがなかったことになります。メニュー内の最初のクリックは、狙った動作ではなく DuoUpdater を前面に出すことに使われていました。開いたウインドウも前面に留めるようにしました。以前は前面に出された直後に押し戻されており、それがこの症状が「クリックしても何も起きない」ように見えたもう一つの理由です。
アプリが自分の名前を空のままにしていても、名前が出るようになりました。 欧路词典はアイコンもバージョンもあるのに、名前の位置だけが空白でした。このアプリのバンドルは表示名を宣言してはいるのですが、中身は空です——本当の名前はアプリの各言語の翻訳側にあるためです——そして DuoUpdater はその空の答えを答えとして受け取り、次を尋ねませんでした。今はアプリのもう一つの名前へ、それも無ければアプリファイル自体の名前へと順に辿るので、名前のない行はもう出ません。この環境の百五十本のうち該当したのは一本だけですが、要点は、情報は最初からそこにあったのに読み飛ばされていたことです。
再起動できなかったときに、その理由を伝えるようになりました。反応のないボタンを押したように見えるのではなく。 アプリがあなたを待つウインドウを開いていると——保存の確認、サインインのシート、何かのダイアログ——macOS はそのアプリを終了させません。これはこちら側にはどうにもできません。アプリ自身のウインドウだからです。以前の DuoUpdater は三十秒空回りしたあと、同じボタンを説明もなく戻すだけでした。それはまさに壊れたボタンに見えるので、人はもう一度押します。今はその行が何が起きたのかを伝え、そのウインドウに対処するためアプリへ案内します。何も変更されておらず新しいバージョンはすでに入っているので、残っているのは本当に再起動だけです——そしてこの先十分以内にご自分でそのアプリを終了すれば、DuoUpdater がそれに気づき、新しいバージョンで立ち上げ直します。クリックは要りません。
欧路词典のリリースノートが、また一つのリリース分に戻りました。十六年分ではなく。 このアプリは自らの全履歴を——2.5.0 まで遡るすべてのバージョンを——その時点で最新のリリースのノートの中に載せます。そのため詳細ペインは「26.9.0」という見出しの下にその全部を並べ、直前に何が変わったのかを見るには十年分をスクロールしなければなりませんでした。今は各バージョンが、他のすべてのアプリと同じように、一覧の中で独立した項目になります。
アプリが何で作られているかを示すあの印は、Tauri については「似ている」ではなく証拠を求めるようになりました。 Tauri はバンドルに何も残しません——フレームワークも、自前のフォルダもありません——ので、あの印だけはパッケージのされ方と、Apple のウェブビューをリンクしているという事実から割り出していました。Longbridge はそのすべてに当てはまりますが、Tauri ではありません。Zed と同じレンダラで自分のウインドウを描き、画面の一角にだけウェブビューを埋め込んでいます。DuoUpdater は今、そう名乗る前にバイナリから Tauri 自身の指紋を読み取ります。ですから Tauri と呼ばれるものは本当に Tauri であり、Longbridge はありのままの姿——ネイティブの Mac アプリとして表示されます。
CapCut が、ByteDance のサーバーの半秒の不調で赤くなることはなくなりました。 DuoUpdater が CapCut のバージョンを尋ねるエンドポイントは成功のステータスコードを返しますが、五十回に一回ほど、答えの代わりにエラーオブジェクトを返します——ByteDance 自身のインフラ内部でのタイムアウトで、本来 436 キロバイトのところが約 390 バイトです。こちら側にはそれと「CapCut が応答の形を変えた」とを見分ける手立てがなく、その行はチェックの失敗を示していました。次の試行で直るものに対して「壊れている、誰かが直さなければ」と読める表示です。今はその特定の形が何であるかを認識します。リクエストはただちに再試行され、五日間続いた場合にのみ、本当の問題として報告されます。
リストのすべてのアプリが、何で作られているかを示すようになりました。 App Store が管理するアプリの行には以前からストアの印が付いていましたが、それ以外の行はどれも同じ見た目でした——Sparkle のアプリも、Electron のアプリも、ネイティブのアプリも区別が付きません。これからは名前の隣にその技術自身の印が付きます——クリックすれば名称と一文の説明が、ポインタを重ねればツールチップが出ます:Electron、Tauri、Flutter、Qt、Java、Chromium、Mac Catalyst、Apple シリコン上で動く iPhone アプリ、あるいはネイティブの Mac アプリ——そして事実として読み取れる場合はランタイムのバージョンも添えます(Electron 42.4.1、Qt 6.2、アプリが内蔵する Chromium、ビルドに使われた Tauri)。いずれもアプリのバンドル自身から読み取ったものです——パッケージャが同梱せざるを得なかったフレームワーク、ランチャーが必要とするランタイム、バイナリがリンクしているライブラリ——ですから、名前からの推測ではなく、いま入っているものについての事実です。名前が長くて余地がないときは、印のほうが引き下がります。名前を二行目に押しやることはありません——その行は名前のものです。まるごと切りたいときは設定 → 一般で。
LibreOffice が「すでに入っている版へのダウングレード」を告げることはなくなりました。 ダウンロードの索引は三桁の版(26.8.0)を並べる一方、インストール済みの本体は四桁(26.8.0.3)を名乗ります。足りない桁をゼロで埋めると、入っているほうが新しく見えてしまい——結果として、まさに最新であるアプリについて「配布元があなたより遅れています」という控えめな注記が出ていました。アプリが名乗るより少ない桁数で公開している配布元は、これからは同じリリースをより粗く述べているものとして読み取ります。本当の巻き戻しなら、これまでどおりそう告げます。
アップデートで増えた設定が、一度だけ自分を指し示すようになりました。 設定ウインドウの真ん中に現れた新しい項目は、誰にも見つけてもらえない項目です。それを追加したアップデートの後、メニューバーの歯車に青い点が付き、その項目のあるページにもサイドバーで点が付き、項目自身にも——あなたが目を通すまで——点が付きます。実際にそこまでアップデートした人にだけ表示されます。新規インストールが、そのアプリにとって元々備わっているだけの機能に青い点で出迎えられることはありません。
前回追加した Electron 系アプリが、実際にワンクリックで更新できるようになりました。 0.3.75 では、これらのアプリが自身の中に持つファイルを読む機能を追加し、実際に読めてもいました——新しいバージョンも、あなたの Mac に合ったダウンロードも、照合用のチェックサムも算出できていた。ただ、その結果を渡す先がどこにもなかったのです。更新ボタンは一度も現れず、duo install が示す拒否理由も本当の理由ではありませんでした。このリリースでインストール経路をつなぎました。実感としては何も変わらないかもしれません。この読み取りは手書きルールすべての後ろに位置するため、他の何ものもカバーしていないアプリについてしか発言しません——そして今日、このビルドを作ったマシン上では、そんなアプリは一つもありません。効いてくるのは、明日あなたが入れる「まだ誰もルールを書いていないアプリ」に対してです。
ネイティブ動作から Intel 版へ引き戻すようなダウンロードは、拒否するようになりました。 Apple シリコンは今も変換を通じて Intel アプリを動かせます。つまり Intel 専用のダウンロードは「この Mac で動くか」という確認を通過し、そのまま問題なくインストールされてしまう——ネイティブで動いていたアプリを、気づかないうちに変換動作のコピーに置き換え、以後の更新でも同じことを繰り返す、という結果になっていました。現在はすべてのその場での更新で、手元のものと届いたものを突き合わせ、この入れ替えを拒否します。逆方向、あるいはユニバーサル版から Apple シリコン版への移行は通常の動作であり、これまで通り許可されます。
ダウンロードのアーキテクチャを証明できないときは、推測せずに見送るようになりました。 ベンダーによっては既定のダウンロードとは別に Apple シリコン版を公開しており、既定のほうが Intel 版だと判断する唯一の手がかりは「もう一方が存在すること」に気づくことです。この二度目の確認がきれいに返ってこない場合——ベンダーのサーバーに拒否された、接続が切れた、両者のバージョンが食い違っている——DuoUpdater はその沈黙を答えとして扱わなくなりました。バージョンは伝え、インストールは提示しません。それが誠実な結果です。
壊れたルールが「診断」から消えることはなくなりました。 手書きルールと新しい読み取りの両方に覆われたアプリ——設計上これが大多数です——では、ルールの失敗が直後の読み取りの成功で打ち消され、実際には壊れているアプリが健全に見えていました。現在は両者を別々に記録します。またこの読み取りは初めて自身の失敗を報告するようになりました。このビルドを作ったマシンでは、三つのアプリが以前から「見つかりません」を返し続けるアドレスを指していたことが判明しましたが、これまでそれを口に出すものは何もありませんでした。
更新は見えるがインストールできない行が、二つの場所で同じものを提示するようになりました。 メニューバーには「開く」と書かれたボタンが表示され、押すと Finder が開き、ウインドウ側では同じ行に何も表示されていませんでした。
Electron で作られたアプリが、誰かが先に登録しておかなくても認識されるようになりました。 多くの Mac アプリは、更新の在りかを書いた小さなファイルを自分の中に同梱しています。これまで DuoUpdater が把握できたのは、誰かが手でルールを書いたものだけで、それ以外は一覧に並んでいてもバージョンが表示されず、新しいビルドが出たことをお知らせする手段もありませんでした。今後はそのファイルを直接読みます。Sparkle のものをずっと読んできたのと同じやり方です。おかげで、この種のアプリは誰かが対応する日ではなく、あなたが入れたその日から対象になります。
すでに手書きのルールがあるアプリはそのままです。 新しい読み取りはそれらの後ろに控えているため、空白を埋めることしかできず、すでに機能していたものを置き換えることはありません。
提示するダウンロードが正しいかどうかは二つの細部で決まり、どちらも実物のアプリで確かめたうえで決めました。 Apple シリコン版を並べて公開していながら、Intel 版を「主」のダウンロードとして示すベンダーがあります。また、Apple シリコン版に Intel 版と見分けのつかないファイル名を付けるところもあり、名前からは何も分かりません。DuoUpdater はアーキテクチャで選び、そのダウンロードがお使いの Mac で動くと確信できない場合はバージョンだけをお伝えしてインストールは提示しません。問題なく入ったのに起動しないものをお渡しするよりは、そのほうがよいと考えています。
アプリのベータ版・リリース候補版・ナイトリービルドを使っている場合、DuoUpdater はこれまで別のトラックを見張っていました。 どのトラックにいるかは、ベンダー自身のリリース一覧の中から手元のビルドを見つけて判断しています。ところがプレリリースは、元になった正式版と同じ公開バージョン番号をそのまま名乗ることが多く——それはプレリリースとしてごく普通の振る舞いです——その結果、正式版の項目のほうに一致してしまっていました。しかもこの誤りは無言でした。画面には何も異常が出ないまま、自分のトラックの次のビルドについて知らされることがなくなり、表示されるリリースノートも正式版のものになっていました。Supacode と TypeWhisper のプレリリース版を実際にインストールして挙動を確かめたことで判明し、どちらも本来いるトラックを正しくたどるようになりました。
CapCut のベータ版で、実際には入っていないバージョンが表示されていました。 行には「9.3.4545 → 9.4.0-beta6」と出ていましたが、CapCut 自身も Finder も他の更新ツールも、手元のものを 9.4.0-beta5 と呼んでいました。一部のアプリは本当のバージョンを一般的でないフィールドに入れており、DuoUpdater は矢印の手元側では見た目の整ったほうを、ベンダー側では本物のほうを読んでいたのです。提示される更新自体は常に正しく、誤っていたのはラベルだけでした。今は矢印の両側が同じ場所から来ています——CapCut も、同じ作りの他の 7 本のアプリも同様です。
MacWhisper、GitHub Copilot for Xcode、TypeWhisper、OpenUsage でリリースノートが表示されるようになりました。 この 4 本はノート欄が空のままでした。更新フィードにノートが一切含まれていないためで、ベンダーが実際に公開しているものと一本ずつ突き合わせるまで気づかれていませんでした。現在は MacWhisper 自身のリリースノートのページ、Copilot の変更履歴ファイル、TypeWhisper の変更履歴サイトを読み、OpenUsage はリリース一覧を指すようにしています。
Helium は自前の更新サービス経由になり、ベータチャンネルと大幅に小さいダウンロードが利用できるようになりました。 これまでは公開リリース一覧から追跡していましたが、そこには正式版しか現れません——つまり Helium のベータを使っている人には正式版が渡されていました。自前のサービスは差分パッチも配信しているため、通常の更新は 124 MB の再ダウンロードではなく約 40 MB で済みます。正式版とベータ版の両方で検証済みで、何かを置き換える前に、インストール済みのコピーに含まれる署名鍵でダウンロードを検証します。
Firefox と Thunderbird のベータ版・開発者版・ナイトリービルドが、ようやく正しく更新を検出できるようになりました。 この 5 つの配信トラックは、これまで一度も更新を報告できていませんでした。読んでいたのは Mozilla が公開しているバージョンファイルで、そこには表示用のバージョンしか載っていません。しかもベータ版はインストールされる時点で「b5」の部分が削られます。つまり Firefox のベータは一周期のあいだずっと自分を 155.0 と名乗り、問いは「155.0b5 は 155.0 より新しいか」だけになり、答えは「新しくない」でした。ナイトリーはさらに深刻です。Mozilla は毎日ビルドを出しますが、そのすべてが 157.0a1 という名前なので、4 週間の周期でひとつも報告できませんでした。そこで DuoUpdater は Mozilla 自身の更新サービスに問い合わせるようにしました。Firefox の内蔵アップデーターが使うのと同じアドレスで、アプリ自身がその場所を書き記しています。比較に使うのは、両側が共有しているビルド識別子です。公開前に、5 つのトラックすべてについて実際のダウンロードと突き合わせました。そのサービスが返す識別子は、お使いのアプリの中にあるものとバイト単位で一致します。1 ビルド遅れたベータは更新として表示されるようになり、同じ日の早い時刻にビルドされたナイトリーも同様です。安定版と ESR はもともと影響を受けておらず、今回も変更していません。ひとつはっきり書いておきたい制限があります。このサービスはリリース日時を公開していないため、この 5 つのトラックについては、リリースログに残るのは「Mozilla が公開した時刻」ではなく「DuoUpdater が最初にそのビルドを見た時刻」のままです。
Wispr Flow、AionUi、Devin がワンクリックで更新できるようになりました。「新しいバージョンがあります」と伝えるだけではなくなります。3 つとも更新を検出することはできていましたが、適用はできませんでした。理由として書かれていたのは、ベンダーが Intel 版と Apple シリコン版を別々に配布しており、DuoUpdater には選ぶ手段がない、というものです。実測してみると、その理由は成り立ちませんでした。この 3 つが読んでいるエンドポイントはもともと Apple シリコン用であり、DuoUpdater 自体も Apple シリコンでしか動きません。選ぶ場面はそもそも存在しなかったのです。組み込む前に、それぞれのダウンロードを取得して確認しました。中身が正しいアプリであること、お使いのコピーと同じ開発者の署名があること、Apple の公証を受けていること、そして AionUi については自身のマニフェストが公開しているチェックサムと一致すること。そのうえで、古いコピーに対して実際にインストールし、新しいバージョンで戻ってくることを確かめました。
Grok Bot を追跡できるようになりました。新しいバージョンの検出と、ワンクリック更新に対応します。 xAI のデスクトップアプリは、Cursor を手がける Anysphere がビルドして署名しており、更新も Cursor 自身の配信サービスを通ります。だからこそ通常の経路はどれも答えられませんでした。Sparkle フィードはなく、App Store にも登録がなく、公開のリリースリポジトリもなく、Homebrew の cask は更新をアプリ自身に委ねています。そこで DuoUpdater はベンダー自身のバージョン用エンドポイントを読みます。ほかに二つ候補がありましたが、どちらも理由があって使っていません。x.ai のダウンロードボタンの先にあるものはバージョン番号をまったく公開しておらず、アプリ自身のアップデーターが使うものは、すでに最新の場合に空の応答を返します。その沈黙は、壊れたエンドポイントと見分けがつきません。組み込む前にダウンロードも確認しました。ディスクイメージには正しいアプリが入っており、お使いのコピーと同じ開発者の署名があり、Apple の公証も受けています。あえて用意していないものが一つあります。リリースノートです。xAI はこのアプリ向けには公開しておらず、公開されている唯一の changelog は別の製品のものです。
Comet と Msty Studio もワンクリックで更新できるようになり、更新できるのにしていないアプリを見張る検査も加わりました。 この 2 つは、更新を検出できるのに適用できなかった最後の組でしたが、どちらも新しい仕組みは不要でした。必要だったのは、ベンダーが実際に返しているものをよく見ることだけです。Comet のダウンロードリンクは署名付きで 1 時間で失効するため、更新ボタンは Perplexity 自身のゲートウェイを指すようにしました。リンクは数時間前の確認時ではなく、クリックした瞬間に発行されます。Msty は 1 つのファイルに 4 つのダウンロードを並べており、Intel 版が先頭にあります。ダウンロードの検証に使う指紋は、その先頭の項目から取られていました。今は実際に取得する Apple シリコン版に結び付いています。おかげで、確認からクリックまでの間に新しいリリースが出た場合も、多くは黙って入らずに止まります。どちらも公開前に実際にダウンロードし、本物のインストール関門を通しました。より大きな教訓は、この 2 つとは関係のないところにあります。検出のみとされた理由がすでに成り立たなくなっていても、それに気づく仕組みが DuoUpdater にはありませんでした。そこで毎晩のレシピ点検が、見ているだけのアプリがすでにインストーラーを差し出している場合にそう言うようになりました。
QQ音乐 に対応しました —— 新バージョンの検出、ワンクリック更新、そしてウインドウ内でのリリースノート表示です。 これまでのやり方はどれも通用しませんでした。Sparkle フィードはもちろん、Sparkle フレームワーク自体を積んでおらず、Homebrew の cask は更新をアプリ自身に委ねており、アプリ自身のバイナリが名指しする更新エンドポイントは、何を尋ねても 200 と空の本文を返してきます —— その沈黙は壊れたエンドポイントと見分けがつかないため、これまでは手を付けずにいました。代わりに DuoUpdater が読むのは、ベンダー自身のダウンロードページが実際に組み立てられている元のデータファイルです。そのページは空の外枠として出荷され、このファイルから流し込まれて埋まる仕組みで、しかもリリースノートが存在する唯一の場所でもあります —— ブログも appcast もバージョンごとのページもありません。そこでノートはこのファイルから直接読み取られ、DuoUpdater 自身のウインドウ内に描画され、更新は同じ応答が名指しする公証済みディスクイメージをインストールします。記録しておく価値のある落とし穴が一つあります。このファイルには今も6年前の Mac 版の記録がもう一つ残っており、現行のものと並んでいるため、両方のルールとも「Mac」という単語ではなく、Mac 版ダウンロードのバージョン入りファイル名を手がかりにしています。そしてはっきり言っておくべき制限も一つあります。このファイルが公開するのは画面に表示されるバージョンだけで、その裏にあるビルド番号は決して含まれません。そのため、名前を変えないまま出し直されたバージョンはここでは見分けがつきません。存在しない更新をでっち上げることはありません —— ただ、その一種類だけは見えないのです。
TimeMachineEditor に対応しました —— 新バージョンの検出とワンクリック更新です。 これまでのやり方はどれも通用しませんでした。Sparkle フィードはなく(フィードのアドレスも、それを使うフレームワークも積んでいません)、App Store にも登録がなく、公開のリリースリポジトリもなく、Homebrew の cask は更新をアプリ自身に委ねています。あるのは、単一のダウンロードリンクがその文言の中にバージョンを記している小さなベンダーサイトだけです —— これは Homebrew 自身のバージョンチェックが頼りにしているのと同じページを同じやり方で読むものなので、当て推量ではなく、ベンダー自身が意図している窓口です。更新は、単純なアプリの入れ替えではなくベンダー自身のインストーラーパッケージとしてインストールされます。これは意図的なもので、ダウンロードにはアプリ本体の外側にバックグラウンドスケジューラー、コマンドラインツール、launch daemon も配置されるため、アプリだけを置き換えると、新しいコピーの隣に古いままのスケジューラーが取り残され、その食い違いに気づく手段が何もなくなってしまうからです。
Little Snitch に対応しました。stable 版と nightly 版の両方でです。 Object Development は、自身のアップデーターがフォールバック先とするバージョンファイル —— Homebrew が読むのと同じもの —— を公開しており、DuoUpdater もそれを直接読みます。Little Snitch は Sparkle フィードを出荷しておらず、cask も更新をアプリ自身に委ねているためです。二つのリリースは一つの識別情報を共有しており、通常はそれで見分けがつかなくなるはずですが、今回はバージョン文字列自体がそれを教えてくれます。nightly ビルドはその語を省略せずに書き出す(「6.5 nightly (7301)」)のに対し、stable ビルドは単なる「6.4.1」と読めます。あえてしていないことも述べておく価値があります。これはあなたに代わって更新をインストールすることはありません。Little Snitch はアプリと並んでシステム拡張と権限付きのバックグラウンドサービスを動かしており、アプリ単体を入れ替えてもそれらが無事に残るかどうかは、実機で検証されていません。そのため DuoUpdater は、新しいバージョンが出ていることを伝えてベンダー自身のダウンロードへ送るだけで、ネットワークフィルターを相手に当て推量することはしません。
Carbon Copy Cloner に対応しました。大バージョン間をまたいで移そうとすることはありません。 Bombich は CCC 5、6、7 という三つの世代を同時に生かし続けており、どれもシステムには同じ識別情報を名乗ります。そのため「もっと新しいものがあるか」は見た目より厄介な問いになります。たしかに 7.1.6 は 6.1.13 より上位にソートされますが、両者をまたぐのは別売りの購入であり、CCC 7 が要求する macOS は CCC 5 のマシンが実際に動かしているものより新しいことさえあります。バージョン番号だけで答えていたら、すべての CCC 5・6 所有者に「無料の更新が待っている」と永遠に告げ続け、しかもそのたびに誤りだったはずです。そこで DuoUpdater は各世代を自身のアドレスから読み取り、実際に持っている世代の中での次のリリースだけを提示します。CCC 内部でベータ版を有効にしている人には、ベータリリースも拾い上げます。今のところ検出のみです。CCC はアプリと並んで権限付きのヘルパーをインストールしており、これはすでにあるワンクリック更新より大きな主張になるためです。そして、これらの更新がこれまで誰にも見えていなかった理由も記録しておく価値があります。アプリ自身の更新フィードは、どんな要求にも成功で応答しますが、その中身は完全に空のページです。
あなたの Mac では実際に動かせない更新が、ダウンロードされてインストールされることはなくなりました。 すべてのアプリバンドルは、それが起動できる最も古い macOS を記しており、一部のベンダーは最も新しいほうも記しています ——「このビルドはそれほど新しい OS には対応していません」というかたちで、macOS 27 にまだ追いついていないアプリはそう言い表します。DuoUpdater はそのどちらも読んでいませんでした。Sparkle フィード経由で追跡しているアプリでは、この下限はすでに守られていましたが、それは少数派です。ふつうの Mac に入っているアプリのうち、ベンダー自身のエンドポイントや GitHub のリリースから読むものが半数より多く、しかも GitHub のリリースは macOS の要件をどこにもまったく公開していません。そのため、あなたの Mac より新しい macOS へすでに移行したアプリが提示され、まるごとダウンロードされ、入れ替えられたうえで —— 開かない、ということが起こり得ました。DuoUpdater は今では、この要件をダウンロードしたアプリ自身から読み取り、あなたのプロセッサ向けにビルドされているかという既存のチェックのすぐ隣でそれを確認し、正常に動いているコピーを起動しないものに置き換えるのではなく、入れ替えそのものを拒否します。フィードがベンダー側の上限を公開している場合は、それも守られるため、開発元が「あなたの macOS には対応していない」と印を付けたビルドは、そもそも提示されません。 はっきり言っておくべき制限が三つあります。要件をダウンロードしたものから読み取るということは、その時点ですでにダウンロードは終わっているということです —— これが防ぐのは壊れたインストールであって、通信量ではありません。たいていのアプリには、それより前に尋ねられる場所がないからです。あなたの Mac では動かせない最新版を持つアプリは、その更新を表示し続け、インストールを拒否し続けます。拒否の理由には今では求められている macOS のバージョンが明示されますが、DuoUpdater はまだその答えを記憶して、以後提示をやめるところまではしていません。そしてこのチェックが対象とするのは、DuoUpdater 自身がアプリバンドルを入れ替える経路だけです。インストーラーパッケージはファイルを macOS に渡し、macOS がそのパッケージ自身の要件を強制しますし、Homebrew と App Store はそれぞれ自分のビルドを選びます。App Store の「iPhone・iPad 向け」区分から来たアプリは意図的に対象外です。そこに書かれているバージョンは iOS のものであり、それを macOS と比べるのは、チェックしないよりもかえって悪い結果になるからです。 まだはっきりと言葉にしていないことが一つあります。開発元が「あなたの macOS には対応していない」と印を付けたビルドがある場合、その更新は単に提示されないだけで、アプリは理由を説明されないまま「最新です」と表示されます。古い Mac であれば、macOS をアップグレードした日に自然と解消します。逆に新しすぎる Mac ではそうはならず、沈黙よりましな答えをきちんと用意すべき場面です。
百度网盘 に対応しました —— 新バージョンの検出、ワンクリック更新、そしてウインドウ内でのリリースノート表示です。 これまでのやり方はどれも通用しませんでした。Sparkle フィードは公開されておらず、手動でインストールされたコピーの代わりに Homebrew の cask が答えることもできず、しかもアプリ自身のバンドルが名指しする更新マニフェストはすでに死んでいます —— そのファイルも、arm64 版の対になるファイルも、それらを収めたディレクトリ自体も 404 を返します。そこで DuoUpdater は、ベンダー自身のダウンロードページが実際に組み立てられている元のエンドポイントを読みに行き、その同じ応答が名指しする公証済みの arm64 ディスクイメージをインストールします。リリースノートも同じ経路で届きます。「版本更新」ページには Mac版 タブがあるものの、ページ自体は空のまま出荷されており、API から流し込まれて埋まる仕組みなので、DuoUpdater はその API を直接読み、直近40件のリリースを自分のウインドウ内に描画します。はっきり言っておくべき制限が一つあります。そのフィードが公開するのは画面に表示されるバージョンだけで、その裏にあるビルド番号は決して含まれません。そのため、名前を変えないまま出し直されたバージョンはここでは見分けがつきません。存在しない更新をでっち上げることはありません —— ただ、その一種類だけは見えないのです。
チェックが失敗したときは、空欄を見せるのではなく「失敗した」とはっきり言うようになりました。 バージョンをベンダー自身のエンドポイントでしか答えられないアプリには、「応答なし」を表す手段が空のダッシュしかなく、それは対応レシピを持たないアプリの見た目と同じでした。そのためベンダーのエンドポイントがタイムアウトしたり移転したりしても、「DuoUpdater はこのアプリを追跡していません」という恒久的な判定に見え、再試行ボタンもなく、「チェックできなかったアプリ」の件数にも数えられませんでした。これらは今では実際のとおり「失敗したチェック」として扱われ、再試行ボタン・件数への計上・理由の明示が伴います。ただし意図的にすべてを対象にはしていません。リリーストラックにレシピがない、識別情報が足りないなど、Mac 側で手の打ちようがない状況は、これまでどおり静かなダッシュのままで、3回連続で失敗したチェックも永久にバナーへ留まらずそこから外れます。JetBrains Toolbox がインストールするアプリでは、裏のバージョン取得が失敗しても「Toolbox を開く」ボタンは残ります。どのみち Toolbox を開くのが答えだったからです。
「再起動して適用してください」というリマインダーは、実際に再起動を終えると消えるようになりました。 アプリ自身のアップデーターがバックグラウンドでビルドをダウンロードすると、DuoUpdater は通知に「再起動」ボタンを添えて知らせていました。押すと処理はうまくいき、アプリは新しいビルドで再び立ち上がり「現在 1.0 を実行中です。」と表示されますが、置き換わったはずのリマインダーは通知センターの下に残り、たった今再起動したものに対してなおも再起動を求め続けていました。DuoUpdater はリマインダーが「意味を失う」瞬間を監視していましたが、チェックが走るタイミングはすでに解決済みの後でした。今では未処理の再起動が一つも残っていない時点でリマインダーを取り下げ、DuoUpdater が動いていない間にアプリが自ら更新を適用した場合の置き去りのリマインダーも消します。
一つのバージョン番号の下に多数のビルドを出荷するアプリが、あらゆる場所で正しく扱われるようになりました。 Mac のアプリはバージョン文字列を二つ持ちます——画面表示用(「1.0」)と、実際に増え続けるビルド番号です。たいていのアプリは両方を動かしますが、ビルドだけを動かすものもあります。Amp は一日に10個のビルドを出荷し、すべて「1.0」と名乗りました。Surge は「6.9.0」のまま四つの別リリースを出荷し、JetBrains のプレビュービルドも同様です。DuoUpdater は「変わったか」の判断を、表示バージョンをおよそ十数箇所で比較することで下しており、これらのアプリに対しては常に「変わっていない」、あるいは「同じか」と尋ねる箇所では常に「同じだ」としか答えられませんでした。以下は、それによって壊れていたものです。単一の不具合であり、Amp がそれを見えるようにしたことで見つかりました。
「再起動」が3分間固まったように見えたあと、実際には起きていない失敗を報告することがなくなりました。 アップデーターがビルドを待機させているアプリで「再起動」をクリックすると、3分間くるくる回り続けたのちに失敗したと表示していました —— 実際には更新は1、2秒のうちに適用され、アプリはすでに新しいビルドで開き直されていたにもかかわらずです。DuoUpdater は、決して起こるはずのない「表示バージョンの変化」を監視していたのです。Amp で計測したところ、1秒に満たない入れ替えに対して189秒ものスピナーが回っていました。今では1秒を大きく下回るところで収まるようになり、本当に失敗したときは、これまでどおり失敗として報告されます。
「再起動」が、すでに古くなったビルドを提示することもなくなりました。 アプリのアップデーターが一つのビルドをダウンロードした後、開発元がさらに別のビルドを公開していても、DuoUpdater は依然として「再起動」を提示していました——再起動した瞬間に1ビルド遅れる、まさにそのチェックが防ぐはずだった事態です。そうした行は今では代わりに 更新 を提示し、現行のビルドを取得します。
バージョンをスキップしても、そのアプリが永久に沈黙してしまうことはなくなりました。 知っておく価値のある話です。「このバージョンをスキップ」は1件のリリースを見送り、次は通すはずの機能でした。ところが表示バージョンだけを記録していたため、複数のビルドで一つのバージョン名を保つアプリでは、一度のスキップが将来のすべてのリリースを見送ってしまい——永久に、再起動をまたいでも残り、画面上には沈黙の兆候が何もありませんでした。スキップは今では見送ったビルドを記録します。副作用が一つ。以前スキップされたバージョンは、古い記録がどのビルドを指すか分からないため再び提示されます。あらためてスキップすれば正しく記録されます。
何も変わっていないように見えた更新でも、「ロールバック」が戻ってくるようになりました。 ワークベンチは何も起きないロールバックを隠しますが、これらのアプリではあらゆるロールバックがそう見えてしまい、本物の更新の後も行が消え、完全なバックアップがディスクにあるのにたどり着けませんでした。
再起動を促すリマインダーは、ビルドごとに一度だけ通知される挙動に戻り、開発元が別のビルドを出荷しても機能し続けます。 0.3.69 は5分おきのリマインダーを、待機中のビルドごとに一度だけ話すものに置き換えましたが、ビルドを「名前」で識別していたため、これらのアプリでは最初の1回だけ通知され、以後は沈黙していました。修正済みです。別件として、未保存の作業でアプリが終了を拒否した場合、DuoUpdater は応答後に再度開くメモを保持しますが、判断中に開発元が別のビルドを公開すると破棄され、入れ替え後にアプリが閉じたまま再度開く手段がなくなっていました。今ではそのメモは新しいビルドに追従します。
失敗した App Store の更新が、こっそり「成功」として記録されることもなくなりました。 また、古いビルドのダウンロード済みインストーラーが「現在提示中」として扱われることもなくなりました。どちらも同じ比較処理が原因でした。リリース履歴もあるアプリの10ビルドを1件のリリースとして数えていましたが、今後は別々に数えます。ただし記録済みの履歴は復元できません。
行そのものが、再起動によってどのビルドが適用されるかを示すようになりました。 これまでは「1.0 → 1.0」と表示され、違いを何一つ言い当てていませんでした。今では「1.0 (129) → 1.0 (130)」と表示されますが、これはビルドこそが変化した内容である場合に限られ、バージョン名自体がすでに異なる場合の表記は変わりません。同じ修正は、「再起動」のツールチップ、通知、インストールが先送りされた理由を説明するメモ、そして duo install が拒否する際の文言にも及びます。
微信输入法 と 豆包输入法 が、再びワンクリックで更新できるようになりました —— しかも、これらのアプリ自身が更新する方法と同じやり方で。 入力方式に対するワンクリック更新は、0.3.25 が出荷されたその日のうちに、ある人の入力方式の設定が消え失せたことを受けて取り下げられていました。何が悪かったかというと、インストールのやり方そのものでした —— 初回インストーラーがするように、アプリ全体を丸ごと置き換えていたのです。入力方式は、そのアプリの「置き場所」によって macOS に登録されており、この二つのアプリはどちらも、その置き場所に手を触れずに自分自身を更新します —— アプリの器はそのまま残し、中身だけを入れ替えるのです。DuoUpdater も今では同じことをするようになったため、登録済みのアプリは更新を経ても同じアプリのままであり、途中のどこかで失敗しても、実行中だったコピーはそのままの場所に残ります。どちらのアプリも、もうパスワードを求めてくることもありません。
どちらか一方を更新する前に、それぞれが学習してきた内容がまず先にコピーされるようになりました。 あなたの辞書、設定、アカウントの状態はアプリの内部には存在しないため、DuoUpdater がこれまで保持していたロールバック用コピーは、それらについて何も語ることができませんでした。今では、入力方式の更新のたびに事前にスナップショットが取られ、ロールバック時に一緒に戻されます。しかもそのコピーはほぼ無料と言える軽さで —— 一方の578MBは0.1秒、ディスクもほとんど消費しません。これは修理というより安全網です。アプリが次に起動したときに自分のデータをどう扱うかは、そのアプリ自身のコードが実行することであり、それに対して立ちはだかれるものは何もありません。今は、戻る先が存在するというだけのことです。
更新が、アプリ自身の「自己更新能力」をこっそり奪ってしまうこともなくなりました。 DuoUpdater が管理者権限を必要としてアプリを置き換えるとき、アプリの所有者は元に戻していましたが、そのアプリがインストールされた時点の権限までは戻していませんでした —— そして、ダウンロードは通常、インストーラーが設定するものより狭い権限で展開されます。この二つの入力方式にとって、それは「自分自身のアップデーターが次の更新を完了できるか」と「自分の後始末すらできなくなるか」の分かれ目でした。アプリがインストールされた時点の権限は、今ではそれを置き換えるコピーにもそのまま引き継がれます。
DuoUpdater は、同じアプリに対して5分おきに再起動を促すのをやめました。 自分自身を更新するアプリは、新しいバージョンをディスクに置いておき、あなたが終了させるのを待ちます。DuoUpdater はチェックのたびにそれに気づき、そのたびにリマインダーを出していたため、まだ再起動しないと決めたビルドが、放っておく限りいつまでもせっついてきていました。各ビルドは今では一度だけ通知されます —— 再起動するか、スキップするか、あるいはそのアプリを無視すれば静かになり、次のビルドはまた通常どおり通知されます。
再起動待ちのアプリは「更新」として数えられ、無視されたアプリはまったく数えられなくなりました。 すでにディスク上に置かれている新しいバージョンは、紛れもなく更新です —— ただ少し早くダウンロードされているだけです。そのため今では、それとは別枠の集計にではなく、バッジと「N 件のアップデートが利用可能」の行の中に数えられます。無視されたアプリはその逆でした。無視したはずのアプリがバッジを点灯させる一方で、その行には控えめな「無視中」タグが表示されるだけでボタンは押せず、数字が指しているのは、あなたには何もできない何かだったのです。無視とスキップは今では、リマインダー、バッジ、リストという3つの表示すべてで同じ意味を持ちます。
搜狗输入法 に対応しました —— ウェブサイトではなく自分自身のアップデーターに尋ねることによってです。 搜狗のリリースノートページは3セグメントのバージョン番号を公開しますが、インストール済みのコピーは4セグメントを持つため、比較には切り詰めが必要でした。代わりに自身の更新チェックはバンドル自身の採番のまま答えます。DuoUpdater はそのエンドポイントに同じやり方で問い合わせ、4セグメントすべてを読み取るため、最後の1セグメントだけの出し直しも見えます。これは検出のみです。搜狗のアップデーターはアプリの入れ替え以上のこと —— QuickLook ジェネレーターの再登録、データの移動、入力方式の強制終了 —— を行うため、更新自体はアプリに任せています。知っておく価値が一つ、搜狗側の仕様です。エンドポイントは問い合わせ元の macOS バージョンに応じて答え、macOS 28 の Mac が自分自身として問い合わせると2023年のビルドを渡されます。DuoUpdater は自分自身として問い合わせないため、表示されるバージョンはどの Mac でも最新のものです。
後から入った修正で正しく読めたはずのリリースノートは、間違ったままにならず読み直されるようになりました。 ノートはバージョンごとにキャッシュされ、公開済みのノートは変わらないという理屈です。それはノート自体には正しくても、DuoUpdater がそこから抽出する内容には当てはまらず、文字化けして出てきたアプリは、その後の解析修正にかかわらずそのバージョンだけずっと壊れたままでした。キャッシュ項目は今では抽出ロジックの世代を記録し、古い世代のものは再取得されます。アプリのリリースノートと Homebrew フォーミュラのノート、両方のキャッシュがこう動きます。
どこかの CDN で失敗したチェックは、壊れていると判定される前にもう一度問い合わせ直されるようになりました。 502・503・504 は仲介者がその先のサーバーに届かなかったことを意味し、少し後の再送でたいてい成功します。Headlamp のチェックはまさにこれで死んでいました —— GitHub がレート制限ヘッダーなしで504を返していたのです。この3つは今では0.8秒後に一度だけ再試行されます。あえてこの3つだけです。500 はサーバー自身の失敗で繰り返してもたいてい再現し、レート制限の再試行はその予算自体を消費してしまうからです。
Homebrew フォーミュラのリリースノートは、そのノートが属するバージョンに紐づくようになりました。 ノートはフォーミュラ単位でしか記憶されず、一度読み込むとセッションの残り時間中ずっと最初のバージョンのノートが返され続けていました —— 新バージョン登場後も。読み込みはフォーミュラ一覧の待ちキューも占有していたため、brew info が遅いとリスト全体が止まることもありました。
ワークベンチのサイドバーでアプリを右クリックすると開けるようになりました。 メニューバーの行が以前から提供してきた「開く」を、より使いたくなるはずのウインドウにも用意しました。
ダウンロード済みのインストーラーを破棄すると、残っていたエラーも一緒に消えるようになりました。 パッケージを捨てると行は「更新」に戻っていましたが、取りやめた試みの赤い失敗表示は居座り続けていました —— エラーは行が最新になったときにしか消えず、更新を提示している行は決して最新にならないからです。今ではダウンロードと一緒に消えます。
オプションのコマンドラインコンパニオンである duo が、自分自身について不正確な説明をするのをやめました。 --timeout は廃止されました —— 受け付けられ、文書化されてはいたものの、実際にはどこからも読まれていなかったフラグです。--budget は今回初めて文書化され、それに言及する唯一のメッセージも、常に「15」と言い続けるのではなく、実際の分数を言うようになりました。--max-calls は既定値を20だと謳っていましたが、実際には6でした。数値以外を渡された数値フラグは、今ではエラーになります —— duo verify --max-concurrency 1x は以前は無視され、既定値の4で掃引されていましたが、これは意図的に掃引を遅くしようとしている人にとってはまったく逆の挙動でした。そして duo verify は、実際に行ったリクエストの数を数えるようになりました。502を返した後に再試行で成功したフィードは、こっそり2回問い合わせていたにもかかわらず、これまでのようにきれいな ok として報告されることはありません。-h は --help が効くあらゆる場所で機能します。
さらに4つのアプリに対応し、リリースチャンネルも2つ増え、そのすべてが所定の場所で更新されます。 CapCut、Canva、そして WorkBuddy はそれが出荷される両方のサイト——国際版と中国版——で対応しました。この二つは独立したリリーストレインを走らせているため、インストールされたコピーには常に、自分自身のサイトに属するバージョンとノートだけが提示されます。Termius と VSCodium は、すでに対応済みの安定版ビルドに加えて、Beta チャンネルと Insiders チャンネルにも対応しました。CapCut の第二のトラックは厄介なケースです。それは CapCut 自身の内部にあるスイッチで選ばれ、バージョン番号のどこにも現れないため、どちらのトラックにいるかは、たまたま実行しているビルドから推測するのではなく、ディスク上のコピーから読み取ります。そのチェックボックスをオンにしている場合は知っておく価値があります。DuoUpdater は、最新のベータ版が存在するようになった瞬間にそれを提示します。これは、CapCut 自身の段階的ロールアウトがあなたに届くはずだった時点よりも先を行くことがあります。
Android Studio のプレビューチャンネルが、今使っているものより古いビルドを提示することはなくなりました。 Google はリリースをバージョン順ではなく公開順に並べており、DuoUpdater はそのリストを3回別々に検索していました——バージョンのために1回、日付のために1回、ダウンロードのために1回です。そのため、より新しい Canary の後に公開されたリリース候補が、バージョンはある項目から、ファイルは別の項目から供給されてしまうことがありました。8月26日、Canary チャンネルは 2026.2.1 Canary 2 がすでに出荷されていたにもかかわらず、2026.1.4 RC 2 と答えていました。今では、それらの答えはすべて同じ1件の項目から取得されなければならなくなりました。
出し直されたリリースが、本来置き換えるはずだったコピーをインストールしてしまうこともなくなりました。 あるプロジェクトがバージョンを変えずにリリースを再ビルドすると、両方のファイルが一つのタグの下に残ります——KeePassXC は元の KeePassXC-2.7.11-arm64.dmg の隣に KeePassXC-2.7.11-1-arm64.dmg を出荷しています——そして DuoUpdater は、先にリストに現れたほうを取っていました。その順序はアルファベット順であり、今回はたまたま再ビルド版が先に来ましたが、次回は最後に来ていたかもしれません。目に見える手がかりは何もありませんでした。行に表示されるバージョンは正しく、その裏にあるファイルだけが間違っていたのです。正しいほうは今では、ファイル名自体が語っている内容によって選ばれます。
Nightly ビルドやスナップショットビルドは、実際のとおりプレリリースとして認識されるようになりました。 VLC の nightly、KeePassXC のスナップショット、Freelens の nightly は安定版と同じ名前・識別子でインストールされ、見分ける手がかりはバージョン文字列だけなのに読まれていませんでした。安定版インストール扱いだったため、nightly が普通のリリースに上書きされてしまうことがありました。DB Browser for SQLite の nightly は同じ理由でファイル名から読みますが、こちらは問題が隠れて生きていました。凍結バージョンは安定版が追いつくまでだけ上位にソートされ、追いつけばすべての nightly が静かに安定版ビルドを渡されるところでした。
アプリの再起動が、実際に何が起きたかを正しく報告するようになりました。 一部のアプリは自分のバンドルに第二のアプリを同梱します——Surge の Dashboard がそうです——内側のアプリだけ再起動が必要なとき、DuoUpdater は何も起きていないのに外側が再起動されたと報告していました。今では内側自身の結果を報告し、起きなかった再起動の通知も出しません。
すでにダウンロードが完了している更新は、そのことを表示し、取り消せるようになりました。 ダウンロード完了済みの行には青い「インストール」ボタンだけが表示され、完了済みであることも、ボタンがやり直しではなくインストーラーを開き直すだけであることも示されず、取り消す方法もありませんでした。今ではツールチップの中に隠すのではなく行自体にそれが表示され、右クリックメニューの ダウンロード済みインストーラを破棄 はダウンロードを捨てて行を「更新」に戻します。同じアプリのインストール中に破棄すると完了直後のパッケージまで巻き込むこともありましたが、もう起きません。
廃止されたページを指していたリリースノートのボタンが、再び現存するページを開くようになりました。 Microsoft が Edge の企業向けページ名を変更し、Termius も変更履歴を移動させたため、Edge の3チャンネルと Termius は存在しないページへ送っていました。ページの生存確認は一度もされておらず、それゆえ他が健全に見える中で朽ち果てたままになれたのです——今は定期チェックされます。Edge の Dev チャンネルにはボタン自体がありません。Microsoft がノート公開をやめ、残るページはすべて別のトレインのものだからです。
Raycast はバージョン2にも追従するようになりましたが、それを実行できる Mac に対してのみです。 Raycast 2 は macOS Tahoe と Apple シリコンを必要とします。それを満たさない Mac はバージョン1のトレインに留まり、どのみちインストールできなかったはずのリリースについて通知されることはなくなりました。二つのトレインは今では、それぞれ独自のリリースノートも保持するようになったため、バージョン1のインストールは、バージョン2ではなくバージョン1自身の履歴を読み込みます。
リリースノートが、DuoUpdater 自身のウインドウ内で描画されるアプリがさらに増えました。 BetterDisplay の3つのトラックすべて、Shotbase、そして WorkBuddy の両方のサイトです。BetterDisplay のノートはもう、ダウンロードボタンの生のマークアップで終わることも、リリースのたびに貢献者一覧を繰り返すこともなくなりました。
オプションのコマンドラインコンパニオンである duo は、理解できないコマンド行を拒否するようになりました。 打ち間違えたフラグは無視され、渡されなかったものとして扱われていたため、duo verify --githubb は指定したはずのレシピの代わりに、こっそりすべてのレシピをチェックしていました。未知のフラグ、値を欠くフラグ、余分な引数は今では受け付ける内容を名指ししたエラーになり、--help はどのコマンドの後でも機能します。
BetterDisplay のプレリリース版と内部ビルドが、それを求めた人にきちんと提示されるようになりました。 BetterDisplay は自身の3つのリリーストレインすべてを単一の更新フィードに載せており、その中からどれを選ぶかは自身の設定にある二つのスイッチで決まります。DuoUpdater は、たまたま実行しているビルドからしかトレインを推測できませんでしたが、それでは、オンにしたもののまだ行動に移していないスイッチについては何も分かりません——そのため、両方のスイッチをオンにしていながら安定版ビルドに留まっている人は、BetterDisplay 自身のアップデーターが4リリースも先のバージョンを提示している最中に、「最新です」と告げられていました。今ではあなたの実際の選択は BetterDisplay 自身から読み取られます。内部ビルドをオンにしても通常のプレリリース版が引き続き届くケースも含めてです。Apple シリコン専用のプレビュービルドは意図的に除外されているため、Intel Mac が実行できないビルドを提示されることはありません。
アプリのリリースチャンネルを立て続けに2回切り替えても、行が古い答えのまま取り残されることはなくなりました。 チャンネルのスイッチを切り替えると、DuoUpdater はそのアプリを再チェックしに行きますが、最初のチェックがまだ進行中に2回目の切り替えが行われると、それは以前は取り落とされていました——ベータ版をオフにしたばかりの人に対して、何か無関係な出来事が別のチェックを引き起こすまで、行はベータ版を提示し続けていたのです。今では新しいほうの切り替えが古いほうを引き継ぐようになり、途中で中断されたチェックは、到達できなかったアプリを「処理済み」として記録するのではなく、次回のパス向けに印を付けたままにします。行はまた、切り替え後により早くチェック中の状態に入るようになったため、画面上の答えがすでにあなたのスイッチによって無効になっている、という時間も短くなりました。
別のアプリの内側に住んでいるアプリが、その親アプリと一緒に閉じられ、再び開かれるようになりました。 一部のアプリは、自分自身のバンドルの中に第二の、それ自体で完結したアプリを同梱しています——Surge はそこに Dashboard を入れています。macOS はそれを別個のアプリとして扱うため、周りのアプリに更新が適用されても、それを閉じるものは何もありませんでした。内側のアプリは、たった今置き換えられたばかりのバージョンを、もはや自分が思っている場所にはないコピーから実行し続け、そこからは自分が属するアプリと話すことができなくなっていました。それらは今では、住んでいる親アプリと一緒に閉じられ、その後で再び開かれるようになり、実際にあなたが作業していたウインドウのほうが前面に戻ってきます。この扱いを受けるのは、あなた自身が開ける類のアプリだけです。アプリが自分のために動かす、目に見えないヘルパープロセスには手を触れません。
ひそかに取得されなくなっていたロールバックポイントが、再び取得されるようになりました。 あるアプリは、自分自身のファイルの一つをロックして、誰にも削除できないようにすることがあり、ロールバック用に保持されるコピーもそのロックを引き継いでしまっていました——そのため、そのコピーは次のコピーによって決して置き換えられず、一度でも中断された試みがあると、誰にも消せないコピーが残り続けることになります。それ以降、そのアプリの更新はすべて、戻る手段のないまま進み、理由も示さない一行だけでそれを告げていました。開発元自身の Mac 上のあるアプリは、2日間もその状態にありました。ロールバック用に保持されるコピーはもうロックを引き継がず、インストール済みのアプリは開発元が設定したとおりの状態のまま残り、行き詰まったコピーが、それを置き換えるはずのコピーをブロックすることもなくなりました。
成功した更新が「失敗した」と報告されることもなくなりました。 macOS は新バージョンを配置した後、旧バージョンの削除で失敗することがあります。それを額面どおり受け取り、DuoUpdater は更新済みなのに「更新されていない」、完全なコピーがあるのに「ロールバックポイントがない」と言うことがあり、前者ではすでに許可済みでどのみち助けにならない権限の付与を求めていました。今では報告の前にディスク上の実態を確認します。
バージョンの行が、バージョン番号にすでに含まれる桁を重複表示することもなくなりました。 再起動待ちのアプリでは、実行中のバージョンと着地先のバージョンが並びます。両方にビルド番号が付き、一つのバージョン名で複数ビルドを出す場合は意味がありますが、バージョンがすでに異なる場合は雑音でしかありません。Chrome の行は「151.0.7922.174 (7922.17…」で幅を使い果たし、実際に変化した桁の前で途切れていました。ビルド番号は今では、それが変化した内容のときだけ表示されます。
更新を完了させるためにアプリを開き直す操作を指す言葉が、一つに統一されました。 アプリ自身のアップデーターがすでに新しいバージョンを配置済みの場合は「Restart」と表示され、新しいバージョンをあなたが終了するまで脇に置いておくタイプのアプリでは「Relaunch」と表示されていました。その違いは裏側では実在するものでしたが、あなたにとっては何の違いもありませんでした——どちらの場合でもクリックする内容は同じですし、一度もクリックしなくても、アプリを終了させた時点でどのみち更新は反映されるため、結果も同じです。今ではどちらも一貫して「再起動」と表示されます——通知、ツールチップ、それを自動で行う設定に至るまで——これは Chrome や Claude をはじめ、自分自身を更新するほとんどのアプリがあなたの前に置く言葉でもあります。この区別のために二つの単語を持っていたのは英語だけで、ドイツ語、日本語、ロシア語、中国語はもともと一つの言葉しか使っておらず、スペイン語とフランス語は、他の場所ですでに使っていた言い回しに合わせて移行します。
管理者権限を必要とする更新は、失敗して権限のせいにするのではなく、きちんと管理者権限を求めるようになりました。 入れ替えにパスワードが必要かどうかは、アプリ自体ではなく、そのアプリが置かれているフォルダを見て判断されていました。macOS が root として設置したもの——すべての App Store アプリと、インストーラーパッケージが設置したあらゆるアプリ——はその判定を通過し、パスワード不要のルートを取るものの、それでは決して完了できませんでした。旧バージョンを削除するには、その内部のディレクトリへの書き込み権限が必要だからです。macOS はその拒否を、App Management 権限が拒否されたときと同じコードで報告するため、失敗は「App Management を許可してください」という要求として現れていましたが、それはどのみち助けにはなりません。障害はファイルの所有権にあったからです。普通の Mac では、それはすべての App Store アプリと、それ以外の少数のアプリに当てはまり、影響を受けたのは管理者アカウントでした——標準アカウントはすでに正しく振り分けられていました。それらの更新は今では、うまくいくルートを取るようになり、アプリはこっそりあなたの所有物になるのではなく、元々の所有者のままになります。
App Store のアプリも、他のすべてと同じようにロールバックポイントを持つようになりました。 これまでバックアップの対象から外れていたのは、ストアならいつでも以前のビルドを取り戻せるはずだ、という理屈からでした。実際にはそれはできません——App Store はアプリの現行バージョンしか提供しないため、ストアは、更新を適用しながら元に戻す手段が一つもないルートになってしまっていました。これらのアプリも今では、他のアプリと同様に更新前にバックアップされるようになり、そのコピーはクローンによって作られるため、更新が実際に元のアプリを置き換えるまでは、ディスク容量をほとんど消費しません。復元するときには、ストアに固有の事情がきちんと表示されます。更新はすぐに「更新」リストに再び現れ、自動アプリ更新がオンになっていれば自動的に再適用されます。そして、ストアの更新がそもそも適用されるはずのなかったケース——Mac 上で動く iPhone アプリ、あなたの地域では販売されていないタイトル——では、ロールバックポイントはもう取得されなくなり、行が「すでに実行中のバージョンにロールバックする」と提示することもなくなりました。
Longbridge Desktop に対応しました。二つのリリーストレインの両方でです。 Stable と Preview のそれぞれについて、バージョン検出、公式の Apple シリコンビルドのワンクリックインストール、そして図版込みで DuoUpdater 自身のウインドウ内に描画されるリリースノートに対応しています。
WhatsApp のリリースノートは、その App Store チェックがまだ進行中の間も表示されるようになりました。 そのウインドウに表示される App Store ページは、検索が決してヒットしない名前で登録されていたため、ノートのペインはそれを表示する代わりに空のまま留まっていました。
メニューのヘッダーが、より狭いスペースでより多くの情報を伝えるようになりました。 DuoUpdater 自身のバージョンが名前の隣に並ぶようになり、それをクリックするとリリースノートが開きます。「すべて更新」は独立した1行に移動し、翻訳されたラベルが全文を読み切れるだけの余白を持つようになりました。下部に並ぶ操作はアイコンになりました。DuoUpdater が自分自身を更新していることを知らせていたバナーはなくなり、代わりにバージョンの隣にあるスパークルが点灯し、あなたが変更内容を読み終えるまで点灯したままになります。メニューに収まらないほど長いステータス行は、それを引き伸ばすのではなく、省略記号で終わるようになりました。
「設定」が、提示している更新の選択肢を途中で切り詰めることもなくなりました。 更新をどう適用するかを決める二つのメニューは、いくつかの言語で自身のラベルを途中で切り取ってしまっていました。文言は今では短くなり、それでもなお足りない場合には2行目に折り返します。
「新機能について」は各バージョンの公開日を示します。 レールのすべてのバージョンに公開日が付きました。
アーキテクチャ別の更新が、この Mac が実行できるビルドを選ぶようになりました。 一部のアプリは一つの Sparkle フィードに同じバージョンを二重公開します——Apple シリコン用と Intel 用です——DuoUpdater はたまたま先にソートされたアドレスで決めていました。今はフィードのハードウェア要件を読み、空欄ならファイル名内のアーキテクチャを読みます。ネイティブビルドが一貫して選ばれ、起動できないビルドは提示されません。GitHub リリースも同様で、最新の成果物が別アーキテクチャ向けというだけで健全なレシピを壊れていると誤判定しません。
ChatGPT の更新チェックが、アカウントのロールアウトトラックに従うようになりました。 OpenAI は新デスクトップビルドが個人アカウントに届く間、ビジネス・エンタープライズアカウントを以前のビルドに留め置くことがあります。DuoUpdater はこれまでプランを反映せず、誰に対してもひそかに慎重なトラックを選んでいました——ChatGPT がすでに新ビルドをダウンロード中なのにインストール済みの方が進んでいると言ったり、アプリ自身のアップデーターが再度置き換えるビルドを提示したりしていました。今はアプリと同じ更新リクエストに、ChatGPT/Codex のサインイン状態からのプランラベルを載せます。ラベルがなければ慎重な挙動を保ち、資格情報自体はリクエストにも診断情報にも含めません。
macOS が一度も応答しない再起動が、それ以降のすべての更新を詰まらせることもなくなりました。 Launch Services は、更新済みのアプリを開き直すリクエストを受け付けたまま、二度と応答を返さないことがあります。行はずっと「再起動中…」のまま留まり、その「再起動」ボタンは無効のままで、DuoUpdater 自身の更新もその後ろで待たされていました。1分経っても応答がない起動は、今では失敗として解放されるため、行は復帰し、アップデーターの残りの部分は動き続けます。
「リリースログ」は、スクロールバーを素早くドラッグしても中身が空にならなくなりました。 以前の遅延読み込みスタックは、長距離のジャンプに追いつけず、新しい位置の周りで行が作られる間、一瞬ウインドウが空白になることがありました。ログは今では、目的地へ直接ジャンプできるリサイクリングリストを使用しています。更新用のコントロールも、矢印とスピナーの間で切り替わる際に同じ大きさを保つようになったため、チェックが始まっても最下段の行がぴくつくことはありません。
「Download Traffic」が、バイナリパッチを使った更新を示すようになりました。 新しいダウンロードはパッチの提示有無ではなく、実際に完了した経路を記録し、履歴に 「差分」バッジを付けます。0.3.62 由来の明らかに小さいパッチダウンロードも、経路欄がなかった時点の記録ながら認識されます。
開発元がそのように公開している場合、更新は変わった部分だけをダウンロードするようになりました。 一部のアプリは、リリースのたびに小さなパッチを同梱しています——手元のバージョンを新しいバージョンに変えるのに十分な、まるごと取得し直す必要のない差分です。DuoUpdater はこれまでそれを無視し、毎回フルパッケージをダウンロードしていました。今では、今のビルドにぴったり合うパッチがあれば、それを使います。ChatGPT の直近の更新は605MBではなく1.9MBで済み、Docker のそれは582MBではなく87MBで済みました。結果として得られるアプリケーションはどちらの経路でも同一です——同じ署名、同じバイト列であり、この機能を出荷する前にフルダウンロードと突き合わせて検証済みです。手元のものに合うパッチがない場合や、パッチの適用が失敗した場合は、これまでどおりフルダウンロードが行われるため、この仕組みのせいでインストールに失敗することはありません。
DuoUpdater は、アプリが自分で既にダウンロード中の更新を重ねてダウンロードしなくなりました。 多くのアプリは自身も更新を行い、同じ600MBのファイルに双方が手を伸ばすと二重に消費していました。今は進行中のダウンロードに気づいて手を出さず、黙って何もしないのではなく行にそう表示します。放棄されたダウンロードは10分で判定を打ち切り、何かが滞ったままになることはありません。
アプリがすでに準備済みの更新が、上書きされることもなくなりました。 自己更新アプリの多くはバックグラウンドでダウンロードし、終了を待って差し込みます。その上にインストールすると一見成功しても終了時に元に戻り、アプリ側の待機バージョンが DuoUpdater の入れたものより古ければ、始める前より遅れてしまっていました。今はどちらのバージョンでも完了までそのまま任されます。
DuoUpdater 自身の更新も小さくなりました。 そのリリースも今では同種のパッチを同梱するようになったため、最近のバージョンから更新する場合、取得するのは11メガバイトではなく数百キロバイトで済みます。
更新が残していった説明文が、自然に消えるようになりました。 DuoUpdater があるアプリをそのアプリ自身のアップデーターに委ねるとき、行にはその旨が表示されます——「アプリ自身のアップデータが更新を適用できるよう、前面に出しました」。この一文はこれまで永久にそこに残り続けていました。それを消す唯一の手段は、同じアプリに対して別の更新を開始することだけだったため、更新が完了してからずっと後になっても、行の下に居座ったまま、何時間も前に終わったことを説明し続けていたのです。今ではアプリが最新の状態になった時点で消えます。「ロールバックポイントなしで更新が適用された」という警告は、意図的にそのまま残されます。これはすでに起きた更新を説明するものであり、それが終わったときにこそ意味を持ち始めるものだからです。
拒否された更新は、あなたの言語で自分自身を説明するようになりました。 他の何か——バッチを処理中の DuoUpdater や、ターミナル上の duo——がすでにインストール中の場合、行にはその旨が表示されます。そのメッセージは、他はすべて翻訳されているウインドウの中で英語のままであり、しかもプロセス番号で終わっていました——ターミナルでは役に立ちますが、メニューの中では何もできることのない情報です。今ではこれは翻訳され、誰がロックを持っているかではなく、何をすればよいかを伝えるようになりました。コマンドラインツールのほうは、それを使って何かできる場所なので、引き続きプロセス番号を出力します。
リリース傾向の行と、そこに含まれる時刻表記が、あなたのロケールに従うようになりました。 「リリースログ → パターン」は、すべてを「Most often ships Friday, around 6 PM」という一文にまとめていました。曜日の名前が格変化する言語では、その曜日を文の途中に差し込む形では正しく言い表せず、誤った語形になっていました——ロシア語では「по пятницам」とすべきところが「Чаще всего выходит пятница」になっていました。今ではこれはラベルになり、「ピーク: 金曜日、午後6時ごろ」のように、どの言語でも正しく表示されます。時刻表記もそれに合わせます——あなたの Mac が時計を24時間表記で書くなら、これもそうなり、チャートの軸上でも同様です。
「設定」内の検索が、画面の言葉を理解するようになりました。 検索フィールドは英語のまま未翻訳の語彙リストと照合しており、「rollback」は「一般」にヒットしても「Zurücksetzen」や「回滚」は何もヒットしませんでした。今はすべての対応言語に語彙が用意されています。英語の語も、由来の文書が英語であるためどの言語でも引き続き機能します。
「すべて表示」をオンにしても、メニューがもたつくことはなくなりました。 手元のすべてのアプリの完全なリストは、表示されるたびにその全体が測定されていました——127個のアプリを持つ Mac では、これがおよそ1秒の処理に相当し、そのほとんどは画面にまったく見えない、はるか下のほうの行のレイアウトに費やされていました。しかもこれは最初の1回だけでなく、切り替えるたびに支払われるコストでした。今では実際に画面上にある行だけが構築されます。
失敗した更新が残す説明文が、その失敗そのものより長く生き残ることはなくなりました。 更新を適用できなかったとき——たとえば他の何かがすでにインストール中だったなど——行にはその理由が赤字で表示されていました。その一行を取り除くものは何もなく、実際に更新が完了して行がチェックマークに戻った後も、古い説明文はその下に居座り続け、DuoUpdater を再起動するまで、どのチェックを経てもそこに残り続けていました。今では、アプリが最新の状態になった時点でそれは消えます。まだ待機中の更新に属する理由はそのまま残されるため、まだ読んでいない理由が、バックグラウンドで実行されたチェックによって消されてしまうことはありません。
「すべて更新」ボタンが、リストの長さに応じて大きさを変えることもなくなりました。 保留中の更新がわずかしかないとき、このボタンは本来より小さいサイズで描画され、隣には80ポイント分の空白ができていました。そしてリストが伸びるたびに、本来のサイズへと飛ぶように戻っていました。今では、常にあるべきサイズを保ちます。
「Download Traffic」は、更新がどのバージョンに移ったかだけでなく、どのビルドに移ったかを示すようになりました。 数多くのアプリが、一つのバージョン名の下で複数のビルドを出荷しています——Surge は「6.9.0」として四つの別々のリリースを出荷しました——そのため、それらの行は「6.9.0 → 6.9.0」と表示され、何も伝えていませんでした。今では「6.9.0 (12028) → 6.9.0 (12030)」と表示されますが、これはバージョン名だけでは足りない場合に限られます。バージョンがすでに変わっている場合、ビルド番号はただの雑音でしかないため省かれます。
記録されるビルド番号は、実際に着地したものであり、更新が完了した時点でアプリ自身から読み取られます。 開発元の更新フィードが謳っていた番号ではありません——フィードは実際に誤った番号を報告することがありますし、この方法なら、ビルド番号をまったく公開していない場所——GitHub、Homebrew、App Store——でも機能します。macOS のインストーラーウインドウでまだ待機している更新について推測することは決してなく、それが現実のものになるまでは何も記録されません。
何も変えなかったダウンロードは、そのようにマークされるようになりました。 更新がすでに Mac にあるビルドを取得・インストールしてしまうことがあります——開発元側のバージョン食い違いや、既存のものを配るミラーが原因です。帯域幅を消費して成果がなく、トラフィックのウインドウで見たいものです。そうした行には今「変更なし」タグが付きます。以前の記録には比較用ビルド番号がないため推測せずそのまま残します。「不明」は「変更なし」とは違うからです。
DuoUpdater は、アプリを最新に保つことに実際いくらのダウンロード量がかかっているかを示すようになりました。 これまでも、あなたのために取得したすべての更新をバイト単位で数え続けてはいましたが、その数字を表示する場所がどこにもなく、誰にも読めないファイルの中に眠ったままでした。今では「Download Traffic」ウインドウがあり、メニュー下部のチャートボタンから開くことができ、そのボタンの隣には今月分の数字が表示されるため、最もよくある疑問はどこも開かずに答えが得られます。中を開くと、合計値、直近3か月をその変化とともに並べた表示、バイト数の内訳、そして費用がかかった順にランク付けされたすべてのアプリが並びます——いずれかをクリックすると、それが行った各更新、どのバージョンからどのバージョンへ移ったか、そのダウンロードがどれほどの大きさだったかが分かります。
この合計値は、自分に見えていないものについて正直です。 Homebrew、App Store、そして自身に内蔵されたアップデーターを通じて更新するアプリは、自分自身でバイトを取得しており、DuoUpdater がそれを扱うことは一切ありません——そのため、この数字は完全な集計ではなく下限値です。これは以前からずっと真実でしたが、変わったのは、まだ何も記録されていない時点の空の画面だけでそれが示されるのではなく、ウインドウがそのことを常に表示するようになった点です。
その後名前を変えたり削除したりしたアプリも、履歴を保ち続けます。 トラフィックは、アプリがディスク上のどこに住んでいるかに対して記録されており、これによって、同じアプリの二つのチャンネル——たとえば Android Studio の Canary と Beta——が合算されるのではなく、別々に保たれます。その代償として、アプリの名前を変更すると、その過去がもはや存在しない名前の下に残されてしまいます。OpenAI が Codex を ChatGPT に改名したとき、これによって30GB分のダウンロードが、重複しているように見える二つの項目に分かれてしまいました。それらの項目は今では、それが何であるかを示す見出しの下、リストの最下部にまとめられ、薄く表示されます。何も破棄されることはなく、合計値には引き続きそれらも含まれます。
App Store からインストールしたアプリに、開発元自身の直接ダウンロードが提示されることもなくなりました。 数多くのアプリが、ストアと、開発元自身のサイトからの直接ダウンロードという、同時に二つの場所で公開されています——同じアイデンティティを名乗りながら、実際には別物のビルドです。直接ダウンロード版は、ストアの審査を待たない分、たいてい先を行っています。DuoUpdater は、ストアからインストールされたアプリについてはまずストアをチェックしますが、そのチェックが何らかの理由——接続が切れた、ストアフロントが応答しなかった——で失敗すると、こっそり開発元のサイトに切り替え、そこにあるものを何でも提示してしまっていました。WhatsApp ではこれが「26.32.75 → 26.33.19」として現れました。本物のバージョンですが、間違った場所から来たものです。それを受け入れると、ストアのコピーが、App Store がもう二度と更新できないコピーに置き換わっていたはずです。ストアからインストールされたアプリは、今ではストアに対してのみチェックされます。
アプリ内でその更新チャンネルを切り替えると、即座に反映されるようになりました。 一部のアプリでは、通常のリリースとベータ版のどちらを使うかを選ぶことができます——Surge、Tailscale、Fork、OrbStack、IINA、Alfred などです——そして DuoUpdater はあなたが選んだほうに従うことで、頼んでもいないビルドを提示しないようにしています。これまでは、アプリを終了するか、DuoUpdater のいずれかのウインドウを開いたときにしか、その変更に気づけませんでした。どちらも、人々が実際にすることをカバーしていません——設定をオフにし、アプリは動かしたままにして、メニューバーをちらっと見る、というのがそれです。さらに悪いことに、アプリはその設定を、あなたがクリックした瞬間ではなく、都合のよいタイミングでディスクに保存します——Surge の場合は5分もかかりました——そのため、たとえアプリを終了させたとしても、それを早すぎるタイミングで読み取ってしまうことがありました。DuoUpdater は今では、その設定そのものの変化を監視し、1〜2秒以内にそのアプリだけを再チェックします。Surge を通常のリリースに戻すと、最大1時間もそこに残り続けるのではなく、即座にその行からベータ版が消えるようになりました。
どこにも到達できなかったチェックが、健全そのものの結果に見えることもなくなりました。 ネットワークがない、あるいは Wi-Fi アイコンは何も問題ないと言い続けているのにプロキシがひそかに接続を拒否している、といったようにすべてのソースが失敗したとき、失敗したアプリは隠され、パネルには「127 個のアプリ · 最新」と表示されていました。それは本当にすべてが最新の状態であるときに得られるのとまったく同じ画面であり、失敗したチェックと成功したチェックの区別がつかなくなっていました。パネルは今では、到達できなかったアプリの数を示し、何が問題だったかを表示し、それらを——それらだけを——再試行する選択肢を提示します。無事にチェックできたものにはいっさい手を触れません。
A helper macOS wouldn't switch on no longer sends you to reset your whole Mac. App Store updates install through a small background item macOS asks you to approve once. When that approval was refused, DuoUpdater had exactly one explanation for it: the system's record of the item is damaged, and repairing it takes a Terminal command that clears the background-item approvals of every app on your Mac. That is one cause among several, and macOS never says which one applies — the ordinary one is that the switch is simply off. The message now leads with that instead: turn DuoUpdater on under "Allow in the Background" in Login Items & Extensions, and DuoUpdater opens the pane for you. The Terminal reset is still written down, as the fallback for when DuoUpdater isn't listed there or switching it on changes nothing. The message also stopped running off the edge of its card.
Two Settings options read on one line again. The two options under Install routing — how App Store updates install, and what happens to apps that ship their own updater — used to put their name to the left of the menu, the way options do everywhere else on macOS. Adding six languages moved both names above their menus instead, because a German or Russian option can be long enough to run off the end of the line, and the safe layout was applied to every language at once. Each row now decides for itself: the name stays beside the menu as long as the menu leaves room for it, and only moves above when the text genuinely needs the width. In English, Japanese and Chinese both rows are back on one line; in German and French they stay stacked, which is the only way they fit without being cut off.
DuoUpdater now speaks Russian, Simplified Chinese, Japanese, German, French and Spanish. It follows whatever language your Mac is set to, and switches with it — there is nothing to turn on. If you would rather read it in a language your Mac isn't set to, macOS can do that per app: System Settings ▸ General ▸ Language & Region ▸ Applications. Everything the app writes itself is translated: the menu-bar panel, every Settings page, the setup window, the notifications, the alerts, and the small print under each option. Counts are handled the way each language actually handles them rather than by bolting an "s" onto the end, which matters most in Russian, where "1 update", "2 updates" and "5 updates" take three different endings — and in Chinese and Japanese, where they take none.
Two things stay in English on purpose. Release notes are the vendor's own words, so they arrive in whatever language the vendor wrote them in — translating them would mean rewriting what a developer said about their own release. And the duo command-line tool stays English, the way command-line tools generally are.
An App Store app that was open when you updated it comes back again. Last release drew a line in the wrong place. It was fixing something real — an update that failed, or that you cancelled, could bring an app back to life minutes after you had closed it yourself — but it decided whether to reopen by asking whether someone had answered a quit prompt. Almost no App Store update shows one: the prompt only appears on a route DuoUpdater stopped using a while ago. So from 0.3.53, updating an App Store app that was running closed it and left it closed, with nothing on screen to say why. The question it asks now is whether the update actually landed, which is the thing that decides whether a quit is coming at all. This is verified against a real App Store update rather than reasoned about: the store terminates your app to replace its files and never brings it back — despite its own prompt promising that it will.
DuoUpdater now tells you when App Store is waiting on you. The store cannot replace an app while it is open, so it puts up a "cannot be open during installation" prompt and waits — with no time limit, holding the update and a download slot for as long as it takes. That prompt is a small panel inside App Store's own window, which may be sitting on some entirely unrelated page; App Store bounces its Dock icon a few times and gives up; and DuoUpdater lives in the menu bar with no Dock icon to bounce. An update could sit there indefinitely with nothing anywhere telling you a click was needed — one took four and a half minutes here, ending only because someone thought to look. The row now says what is being waited for, from the moment the update starts.
The dot that marks an app as open no longer lags behind. macOS does not reliably announce that an app has launched — some apps never trigger it at all, while quitting is always announced. DuoUpdater listened only for those announcements, so a row could insist an app was closed while its window sat in front of you, and only correct itself when some unrelated app happened to open or quit. It now re-derives which apps are running whenever it rescans, which includes the moment you open the menu.
Two things a review caught before you did. The warning that an update was applied without a rollback point was being erased before it could be read: restarting an app cleared the whole note, and restarting after an update is the default. It is now retracted only by whoever wrote it. And Update All could refuse to restart an app — telling you its own updater had a version staged and waiting — when nothing was staged at all: it compared what was on disk now against a build number recorded before the install, so an app whose version name had not changed looked like a conflict.
An app that already downloaded its own update is no longer asked to download it again. Plenty of apps fetch their next version quietly in the background and hold it until you next quit them — that's the "relaunch to update" state you see inside Claude, TablePlus and others. DuoUpdater has always recognised that state in Electron apps and offered you Relaunch instead of an Update, because the bytes are already on your disk. Apps built on Sparkle, which is most of the rest, were invisible to it: TablePlus sat there with a 133 MB download and an unpacked 382 MB copy of 26.9.11 in its cache, while its row offered to fetch 26.9.11 for you all over again. Those apps are now recognised too — the row offers Relaunch, and nothing is downloaded twice.
One thing it deliberately won't do is offer Relaunch for an older build. An app can be holding a version behind the one you have, which happens when a vendor releases to some people before others and DuoUpdater installed the newer one first. Relaunching there would quietly move you backwards, so the row doesn't offer it — and DuoUpdater won't restart the app for you either, because that restart is the exact signal the app's own installer is waiting for.
Three ways an update could go wrong that a review caught before you did. An App Store update that failed, or that you cancelled, could bring the app back to life minutes later — you would quit it yourself and it would reopen, because DuoUpdater had noted "this app may need reopening" before anything had actually closed it. It now only reopens an app when a quit was genuinely asked for. Separately, the check added last release to stop an app's own updater undoing ours compared only the version name: a vendor that ships several builds under one version number slipped straight past it, which is the same failure it was written to prevent. It now compares the build number too. And an app's own updater is no longer assumed to be waiting just because a downloaded copy is sitting in its cache — Sparkle leaves those behind for ten days after an interrupted install, which could have left a Restart button that did nothing but explain itself.
Same changes as 0.3.51, reissued so it can actually reach you. 0.3.51 went out carrying the same internal build number as 0.3.50. That number, not the one in the version name, is what an update check compares — so anyone already running 0.3.50 was told they were up to date and never offered it. This release carries the changes below under a build number that is properly newer. If you are reading this on 0.3.51, nothing about the app changed between the two.
An update that kept coming back. ChatGPT would offer a new version, install it, restart — and a minute later the same update was waiting again. The install was never the problem: the new version really did land on disk. What happened next is that ChatGPT's own updater put a different one back. There are two lists involved, and DuoUpdater was reading the wrong one. The first is everything the vendor has published; the second is what the vendor is actually handing out to your Mac today, which can be an earlier build while a release is still rolling out. DuoUpdater was reading the published list — the same address ChatGPT itself is configured with, which is what made it look right — and offering you a build the vendor was still holding back. ChatGPT had meanwhile downloaded the build it was being offered and parked it, waiting for the app to close. Restarting to apply our update is what closed it. DuoUpdater now asks the same question ChatGPT's own updater asks, so the two agree on what the current version is.
Restarting an app no longer applies somebody else's update. That collision isn't unique to ChatGPT. A lot of apps download their next version quietly and install it the instant you quit them — the "relaunch to update" state you've seen in Claude, TablePlus and others. They'll wait hours for that quit; one was observed holding on for nearly seven. When DuoUpdater restarts an app to put its own update into effect, that restart is exactly the signal they're waiting for, and theirs runs second. Before restarting, DuoUpdater now checks whether anything is waiting, and what version it holds. If it's the same version — which is the common case, and harmless — nothing changes. If it's a different one, the app isn't restarted: the row says what's waiting and leaves the choice to you, rather than quietly swapping in a build you didn't pick.
An App Store update no longer leaves your app closed. Updating an app you have open through the App Store means closing it — the store's own installer quits it to replace the bundle, and doesn't open it again afterwards. DuoUpdater knew to reopen it, but only if you'd answered its own "quit to finish updating" prompt. Answer the identical prompt in the App Store window instead, or take an update that raises no prompt at all, and nothing remembered that your app had been open. It updated correctly, said "Updated ✓", and your app was simply gone — with no restart offered, because by then there was no running app to restart. What decides now is whether the app was running when the update started, which is the thing that was actually true, rather than which window you happened to click in.
豆包输入法 now gets checked, and shows its release notes. It was in the list — DuoUpdater looks inside /Library/Input Methods — but nothing anywhere knew where to ask about it, so the row sat blank forever and read like "nothing to do". It now reads the same endpoint the vendor's own download button reads, and compares the same build number the vendor versions by — so even a re-release that keeps the version name unchanged shows up, rather than passing as the version you already have. The release notes come from the feed the input method's own updater polls, laid out as a proper list rather than a link to a page that doesn't exist. As with 微信输入法, DuoUpdater will tell you a new version is out but will not install it for you: an input method is registered with the system by its installer, not merely copied into place, and quietly swapping the bundle is how you lose your personal dictionary.
Zed's release notes come back instead of an error. DuoUpdater asks GitHub about a lot of apps, and GitHub lets an unidentified caller ask only sixty questions an hour from one network — a budget every GitHub-hosted app on your machine shares. Zed's notes were the ones losing that race, and the panel showed a failure rather than the notes. Those requests now carry the GitHub token you saved in Settings ▸ GitHub, or the one the gh command-line tool already holds if you use it, which lifts the limit far out of the way. Without a token nothing gets worse: Zed's notes now come from a single, smaller source that covers both its channels, where before each one fetched its own web page.
Notion's release notes are about the app you have. They were being read from Notion's product announcements — the page that introduces features as they launch. Those posts are titled by feature, not by version, so nothing on that page ever lined up with the version number on Notion's row, and the notes for the update you were being offered were never there to find. They now come from Notion's own "What's new" page for the Mac and Windows app, where the versions are the ones you can actually compare against.
Some release notes were quietly incomplete, and no longer are. A release's final line could go missing from ChatWise's notes. Two of Postman's releases were cut off mid-sentence — both at the exact point where the text contained a quotation mark. Six apps' notes are now read from the same data the vendor's own site is built from, rather than picked out of the finished page, which is both sturdier and how those two ended up whole. HBuilderX is the one trade-off: its notes now come from the official release document, which covers the HBuilderX editor itself and not the bundled uni-app and uniCloud module logs, so its entries are shorter than before — the same releases, in the vendor's own words, minus the parts about other products.
Release notes that arrive inside an app's update feed are laid out properly. A good number of apps ship their notes as a small piece of a web page tucked inside the feed their updater reads. DuoUpdater used to hand that straight to the system's HTML renderer, which produced a serif font nothing else in the app uses, bullets indented into the margin, and — the part that mattered — a long list could be cut in half, with everything after the cut silently absent. Those notes are now read into the same list layout the rest of the panel uses: right font, right indentation, and nothing dropped. Where the markup is too tangled to be sure of, DuoUpdater leaves it to the old renderer rather than risk showing you part of a list as if it were all of it. TablePro benefits most — its notes had stopped being found at all.
Four more apps show their release notes properly, instead of an embedded web page. Alcove, Docker, Kiro and Waku each publish their notes somewhere a program can read them — Alcove and Docker on their own sites, Kiro as a feed, Waku on GitHub — but DuoUpdater was showing you the web page instead, which meant the vendor's fonts, the vendor's navigation, and no way to move between versions. They now read as proper entries in the list, the same as everything else. Kiro's feed covers three separate products; only the notes for the app you have installed are shown.
A release whose notes are written as sentences no longer vanishes. Some releases don't have a bulleted list of changes — they have a line or two of prose, sometimes only "no public-facing changes in this release". DuoUpdater understood lists and nothing else, so those releases were skipped entirely: if you happened to be running exactly that version, the panel had no entry for it at all, as though your own build had never shipped. They're kept now. Where the notes are laid out in a way that still can't be read cleanly — a table, mostly — the page is shown as before rather than half-converted into something misleading.
Antigravity IDE gets checked. It's a separate app from Antigravity, with its own version, and it was in your list but nothing ever checked it — the row just sat there with no version to compare against and no way to find out. It's checked now. DuoUpdater won't install it for you; it will tell you when a new version is out and where to get it.
DuoUpdater tells you when it updated itself, and what changed. It installs its own updates quietly, on purpose — it waits until you're away from the machine and swaps itself without asking, because a tool that interrupts you to talk about itself is getting in the way of the work it's supposed to protect. The cost was that you'd end up on a new version you never agreed to and never saw the notes for: every other app in your list has a "what changed" panel, and the one app that changed under you in silence was this one. Now the menu says so once, and opens its release notes. It's shown until you read it rather than for a set time — the update this is for is the one that landed while you were asleep. A fresh install doesn't get told it was updated, because it wasn't, and going back to an older build on purpose doesn't either.
And you can read those notes any time. The ✨ button at the bottom of the menu opens every release DuoUpdater has ever shipped, with the one you're running marked in the list.
Switching an app's update channel in that app is noticed straight away. Some apps let you choose between their stable and pre-release builds in their own settings — Tailscale, Fork, Surge, OrbStack, TablePlus, CleanShot, IINA, Alfred, DuoPaste. That choice lives in the app's own preferences, where nothing tells DuoUpdater it has changed, so switching from a beta track back to stable left the row still comparing you against the beta — and still offering it — until the next scheduled check, up to an hour later. DuoUpdater now re-reads that choice when one of those apps opens or quits, and when you come back to its own window, and re-checks just the app that changed.
Tailscale's Release Candidate track is one of the choices DuoUpdater understands. Tailscale publishes three: stable, release candidate, and unstable. Only two were known here, so a Mac opted into release candidates was quietly checked against stable instead, and reported up to date whenever a candidate build was newer than the stable one. All three are now checked against the track you actually chose.
Confirming a quit late no longer leaves the app updated but closed. Some apps guard their own quit with a dialog — Claude, for one, asks about an active conversation — and that dialog could land in the middle of a Relaunch. DuoUpdater rightly refuses to sit there while you decide (and it still won't force the quit past your unsaved work), but once it stepped aside it also stopped listening. Answer the dialog a minute later and the quit went through, the app's own updater swapped in the new version — and then nothing happened: some updaters deliberately don't reopen the app after installing, DuoUpdater was no longer watching, and you were left staring at an app that had simply closed. It now leaves a note for itself when it steps aside: if you do confirm that quit within the next few minutes, it waits for the update to finish landing and then brings the app back, in front if that's where it was. The note expires after a few minutes, so a quit hours later is just you closing the app, and stays that way.
The same late answer now works for a plain Restart. A save prompt could block the Restart button (and the automatic restart that follows a one-click Update) in exactly the same way, with a worse ending: the new version was already on disk, so when you finally dismissed that prompt and the app closed, DuoUpdater's next look around decided there was nothing left to restart and quietly dropped the badge too — an app closed, an update half-applied, and no trace that anything had been asked for. Answering a save prompt within a few minutes now finishes the restart it belonged to, and the app comes back on the new version.
App Store updates tell you they're waiting, and don't leave the app closed if you answer late. When the App Store finishes downloading an update for an app you have open, it asks for that app to be closed before it can install — and DuoUpdater waits, indefinitely and on purpose, for you to say when. Until now that request lived only inside the menu: if you never opened it, an update sat downloaded-but-not-installed all night, and background checks waited with it. It now also arrives as a notification with a Relaunch button, so you can answer it without hunting for the row. And if your app puts up a save prompt of its own after you tap Relaunch, answering it minutes later no longer strands the app closed — the update lands and the app is reopened, the same as if it had quit right away.
The list holds still while you are clicking down it. Every finished update used to re-sort the list on the spot: the app that just landed left the pending group, or picked up a Restart badge and jumped to the top, and everything below it slid up a row — under the pointer of anyone working down a list of Update buttons. Click the top one, go for the next, and the next one had moved. Now the order is held from the first click until the whole round is done: an app that finishes shows its confirmation in place, nothing else moves, and the list settles once at the end, when the finished apps drop away as they always did.
One less version number on a row that needs a restart. An app with an update waiting and an earlier update still needing a restart tried to print all three versions on one line — installed, available, and the older one still running. On four-part versions like Chrome's it did not fit, and the line was cut off exactly where the digits started to differ, so the part left visible said nothing at all. The line now sticks to the comparison that matters — what you have and what is offered — and the running version moved to the row's tooltip, where it fits.
No more Dock icon. DuoUpdater is a menu-bar app — everything it does starts from the icon up there — but it also held a Dock slot, and the only thing that slot ever did was open the same window the menu bar opens. It now runs from the menu bar alone. If you would rather keep the Dock icon, Settings ▸ General ▸ "Hide the Dock icon" turns it back on, and with it the badge that shows the number of pending updates; hidden, that count lives on the menu-bar icon instead.
An app you ignored is no longer checked at all. Ignoring an app hid its row, but every check still asked its vendor after it — one network request per app per round, spent on an answer nothing would ever be said about. On an unauthenticated GitHub budget of sixty requests an hour, those were requests taken from the apps you do watch. Ignoring now means not asking, which is what "hide an app from update checks" always claimed. Naming an app on the command line still checks it, and so does asking for hidden rows, since both are you asking about that app specifically. Skipping a version is unchanged and still checked — whether the version on offer is still the one you skipped can only be known by asking. And un-ignoring re-checks that app on the spot, instead of leaving the row blank until the next round comes due.
An app you ignored stops notifying you. An app that updates itself leaves a "Relaunch to apply it" reminder in Notification Center and repeats it every few minutes until you act on it. That reminder never consulted the ignore list, so an app you had ignored went on sending it — hidden in DuoUpdater's own list, still arriving every five minutes, with nothing on screen to explain where it was coming from. Ignoring an app now silences those reminders and clears any already waiting in Notification Center. Skipping a version does the same for that version.
A download no longer squeezes the app's name or its version off the row. While an app was downloading, the progress bar and its percentage claimed enough of the row that a long name wrapped onto a second line, a long date-style version was clipped at both ends to something unreadable, and at 100% the percentage itself broke across two lines. The row now measures what the name and the version actually need and fits the progress readout into what's left: the bar gives way to a compact ring, and the percentage stays. Nothing is given up until there is genuinely no room for it.
An update no longer looks like it fired twice. With one update pending, installing it briefly emptied the list: the row dropped out the moment the new version reached the disk, the "Everything is up to date" placeholder took its place and jumped the window's height, and then the row reappeared saying "Relaunching...". Nothing was actually wrong underneath — the app still had to be restarted to run the new code — but it read as though something had happened twice. The row now stays where it is from the click through to the relaunch. The step that used to announce "Done" while the app was still being restarted says "Installed" instead; "finished" is left for the confirmation at the end, where it belongs.
The workbench sidebar follows the arrow keys again. Holding an arrow key walked the selection off the edge of the list and left it there, moving through apps that were never drawn and not catching up when the keys stopped. The selected app stays in view.
Moving through that sidebar is quicker. Every keypress was re-deriving, once per app per row, a fact about the whole list that had not changed — on a machine with 124 apps that came to about fifteen thousand redundant filesystem-path lookups per keystroke. It is derived once now. Fast key repeat can still outrun the list; there is more to do here.
An App Store update says "Update", not "Get". When the background helper has not been approved there is no way to install an App Store update in place, so the row hands off to the App Store app instead — but the button for that read "Get", which is what the store says about an app you do not own yet. Every row that reaches it is an app you already have, with an update waiting. It says "Update" now, and when the helper is what is missing the tooltip says so, since approving it in Settings is what turns those updates into one click.
The action column lines up. A checkmark or a small badge at the end of a row was centred in its slot while a wide button sat flush against the row's edge, so the right-hand column read as ragged — and visibly out of line with the Homebrew row pinned below it. Everything ends on the same edge now.
WeType (微信输入法) now reports the version you actually have. Its version was being read off the name of the vendor's installer file, which turns out to carry the installer's version rather than the app's — the installer is a small downloader that fetches the real app separately, and the two numbers drift apart. DuoUpdater now reads the same manifest the vendor's own installer reads, so the version matches your copy and new releases show up when they ship. WeType still has to be updated with the vendor's installer rather than in place: replacing the bundle skips the input-method registration step and was found to lose settings.
A beta build can never arrive on the stable channel. The fix in 0.3.44 looks further back through an app's releases when the newest one has no Mac build attached. That wider search could also see the developer's beta and release-candidate builds, which the normal check never shows you — so an app that happened to publish a release without its Mac download could have offered you a beta. Nothing had actually hit this, and now nothing can: the wider search only ever considers finished releases.
Notion's release notes are readable again. Notion restyled its releases page and DuoUpdater could no longer pick the posts out of it, so the notes fell back to showing the raw web page. They render as proper entries again.
PureMac's updates are visible again. The developer publishes a separate command-line tool from the same place as the app, and its release was being read as if it were the app — as version 1.0.0, which looks older than what you have installed, so the app reported itself up to date and every real update stayed hidden. It now reads only the app's own releases.
An update that only ever existed for phones no longer sits in your list. Some apps share one version number across Mac, Windows, Linux and mobile, and sometimes a release goes out to the phones alone — the version number moves, but no Mac build is ever made. DuoUpdater was reading that as a Mac update, which left an update you could never install and that never went away. It now looks for the Mac download itself rather than trusting the version number, so those releases are correctly ignored. LocalSend was the app affected; its row now reads as up to date, which it is.
LocalSend installed from its own website updates in one click. Now that the right release is identified, its Mac disk image can be installed in place like the rest.
An App Store copy is never replaced with a build from elsewhere. A few apps are published both on the Mac App Store and as a download from their developer, under the same identity — LocalSend is one. Those are genuinely different builds, and the App Store's copy has to keep updating through the App Store. DuoUpdater now leaves those copies to the store instead of ever offering the developer's build over them.
Updates that the wider ecosystem never picks up get flagged for us. Our nightly recipe sweep could only tell whether an app's version could still be read, not whether the answer made sense for a Mac — which is why the LocalSend problem had to be spotted by hand. It now also compares against Homebrew, and raises a flag when we are reporting a version that nobody else has packaged long after it was published. Nothing about this is visible on your Mac; it is how this class of mistake gets caught by machine next time.
Package updates are read more thoroughly before they are opened. The check added in 0.3.41 asks an installer package where it installs, and refuses one that will not say. It was reading only the summary the package publishes about itself; it now also reads the package's own file list, which is what the installer actually follows. That means a package that keeps quiet in its summary is still understood instead of turned away. Every app that updates this way was re-checked against its real installer, and none of them changed.
A download link that stays broken now gets noticed. When a vendor's server has a bad minute, DuoUpdater waits it out rather than crying wolf — but that was letting a download link that had been broken for good slip by unremarked, because it looked the same as a bad minute on any single check. It now tells the difference: brief trouble is still ignored, trouble that lasts is flagged and fixed. Nothing changes on your Mac; this is about broken apps getting repaired sooner instead of quietly staying broken.
Release notes can't be pulled down to an insecure page. A vendor's notes page is loaded over a secure connection, but nothing stopped that page from redirecting itself to an insecure one. Now it can't.
Updating OneNote no longer installs the whole of Microsoft Office. OneNote's update was being fetched from Microsoft's combined Office installer, which puts Word, Excel, PowerPoint, Outlook and OneDrive on your Mac along with it. If you keep OneNote on its own, that was five applications you never asked for. It now downloads Microsoft's standalone OneNote update, which installs OneNote and nothing else.
Package updates are checked more strictly before they are opened. An update that arrives as a macOS installer package now has to say where it installs, and has to name the app you are updating. A package that will not say is refused rather than let through. Every app that updates this way — Office, Edge, Teams, OneDrive, Tailscale, ToDesk, AweSun and the rest — was checked against its real installer first, so this should never fire on a normal update.
Telegram's one-click update stops vanishing when Telegram's servers hiccup. Working out where to download Telegram from needs one extra request to their servers, and those servers were intermittently refusing it — a few minutes at a time, then fine again. When that happened the update was still detected, but the Update button quietly disappeared for that check and you had to go to the website yourself. DuoUpdater now retries before giving up, so a brief hiccup no longer costs you the one-click install.
Package installers are checked against the app they claim to update. Some updates arrive as a macOS installer package, which runs with administrator rights the moment you confirm it. Until now the only check was that the package came from the same developer as the app being updated — which would have let any package from that developer through, not just the right one. DuoUpdater now also reads where the package says it will install and refuses it if that is not the app you are updating. Nothing changes for a normal update; this only ever fires on a package that does not belong.
Release notes only open over a secure connection. The notes pane loads a vendor's own page for some apps, and one of those pages was still being fetched over plain http. Those pages now have to be https, and a handful of other malformed addresses are refused outright rather than loaded.
Fewer apps can go silently missing after a vendor renumbers. Zotero's jump to 10.0 in 0.3.37 exposed a whole class of this: an app disappears from the update list, with no error, because the vendor changed how many numbers are in its version. Twenty-one apps — among them VS Code, Discord, Obsidian, Figma, WhatsApp and GIMP — no longer depend on that staying the same. The rest were checked and deliberately left alone, because for those a looser check would risk reading the wrong number off the page.
The download percentage no longer spills out of its row. While an update downloaded, the number next to the progress bar sat too far right — clipped by the edge of the list instead of lining up with everything else in the column — and there was more empty space between the bar and the number than there needed to be. Both are fixed; the percentage still holds a fixed width, so the row stays steady as it counts up to 100%.
Zotero 10 shows up as an update again. Zotero numbered its new major release 10.0 — two numbers where every previous release had three — and DuoUpdater's check for it quietly stopped recognising the version. Nothing looked wrong: no error, no failed check, Zotero simply never appeared in the list, so anyone still on 9.0.6 was never offered the upgrade. It is recognised again, and the one-click install is unchanged.
A package update that leaves the old copy running now offers to restart it. Some updates install as a package handed to macOS's own installer, and when that finished it left the previous copy still running the old version — with no prompt, so you had to notice and quit it yourself. DuoUpdater now spots that and offers a Restart, the same as it already does for other kinds of update. It only offers one when a copy that was open before the install is genuinely still running the old code — if the installer (or you) already relaunched the app, or it wasn't open, nothing is shown.
WeChat DevTools (微信开发者工具) is checked for updates now — Stable, RC and Nightly each on their own track. It used to sit there as "unknown": since version 2.02 the app reports Electron's stock identity on disk, calling itself version 36.6.0, and all three channels look identical from the outside. DuoUpdater now reads the real version and channel out of the app's own configuration, so whichever track you installed is the only one you are offered — a Nightly install is never handed a Stable build, or the other way round. Updates install in one click, and the release notes for the exact build show up in the window.
App Store updates stop breaking every time DuoUpdater updates itself. Replacing the app left the background helper from the previous copy running, and macOS then never started the new one — so the helper looked switched on while every App Store update failed talking to a copy that no longer existed. Only a restart cleared it. The helper now steps aside when it has been idle for a minute, which means a replaced app heals itself by the next update. For a Mac already in that state there is a Restart Helper button in Settings → Diagnostics and on the update that failed; it asks for an administrator password and takes effect immediately, no restart.
Diagnostics can tell you whether the helper actually works. "Enabled" only ever meant "switched on", and the difference between that and "answering" showed up as a failed update. A Check button now says which one you have, in those words.
Backups: choose what to delete. "Clean Up Now" only removed backups belonging to apps you had uninstalled, so on most Macs it deleted nothing and said nothing while the size stayed put. It now opens a list — every backup with its app icon, the update it would roll back, its size and date — with everything selected and anything you want to keep unselectable. The button says how much the selection frees. Backups whose records had gone missing were previously counted in the total but impossible to see or remove; they are listed too, marked unusable.
A silent self-update no longer leaves DuoUpdater sitting in front of you. When it applied its own update in the background, macOS brought back the windows that had been open — and bringing a window back also brings the app forward, so an update nobody asked for landed on top of whatever was being worked on and stayed there. DuoUpdater now notes which application was in front before it replaces itself, and gives the front back to it on the way in. Windows still return exactly as they were.
Docker updated to the version it said it would. Docker publishes its releases in an order that puts an older one first, and DuoUpdater read the newest version from that list while taking the download link from the top of it — so it fetched 574 MB, kept a backup, installed 4.86.0 over the 4.86.0 already there, and went on offering 4.87.0. Downloads are now matched to the version each entry declares for itself, whatever order a vendor lists them in.
An update that changed nothing is no longer reported as done. The check that runs immediately after installing already knew Docker hadn't moved; it was overruled by a success message and an "Updated ✓". When an update we applied ourselves leaves the app exactly as it was, that is now shown as the failure it is, naming what was installed and what is still on disk.
Silent self-updates no longer wait for an empty screen. With the switch turned on, DuoUpdater would hold its own update back while any of its windows were open — which, for a window people leave open, meant waiting until the app was quit. Open windows no longer delay it (macOS brings them back after the restart), while a DuoUpdater you are actually using still does: it waits for the keyboard and mouse to go quiet before restarting itself.
Installing DuoUpdater's own updates silently now actually is silent. The switch introduced in 0.3.30 downloaded the new version in the background and then still asked before applying it — the one thing it was meant to spare you. It now applies the update itself, at a moment when doing so interrupts nothing: no check or install running, nothing waiting to be relaunched, no DuoUpdater window open, and you working in another app. It restarts itself there, without a prompt. Until such a moment arrives it simply waits, and if none ever comes the update is still applied when you quit — so the wait can delay a version, never lose one. Leaving the switch off is unchanged: you are asked, as before.
An App Store update no longer blames you for a permission you already gave. When DuoUpdater is replaced while it is running — by its own update, or by a rebuild during development — the previous copy of its background helper keeps holding the slot the system reserves for it, while macOS still reports the helper as switched on. Every App Store update then failed with a red line telling you to go turn it on in Login Items, where you would find it already on, and the button offered beside that message quietly did nothing. That state is now recognised and named for what it is, along with the one thing that clears it. DuoUpdater no longer tries to repair it by re-registering the helper: that was measured to switch the background item off and leave it unable to be switched back on.
DuoUpdater can now update itself without asking. Settings → Updates has a new switch for installing DuoUpdater's own updates in the background, taking effect the next time it restarts. It stays off unless you turn it on, and the prompt-and-wait behaviour is unchanged for everyone who leaves it alone.
Its own updates are noticed within the hour. DuoUpdater checked for its own new versions once a day, so a release could sit unseen for most of a day. It now checks hourly.
Eight more AI desktop apps are tracked. OpenCode Desktop and OpenChamber follow their GitHub releases; Wispr Flow, Granola, Comet, Windsurf, AionUi and Msty are read from their vendors' own version endpoints.
Installer packages stay the same package from verification to macOS Installer. DuoUpdater now seals the selected installer before closing or replacing any existing Installer window, checks it again immediately before opening, and refuses the hand-off if another local process changed the file in between. This preserves Sparkle's signature guarantee all the way to the package you see in Installer without making the menu-bar UI pause while large packages are checked.
Multi-installer disk images handle more real-world package names without guessing. Versioned beta, release-candidate, Apple Silicon, and universal package names are recognized when they identify one unique product, while similarly named helpers and sibling products remain excluded. Older bundle-style macOS installer packages are supported by the same integrity checks.
Failed installer downloads are cleaned up immediately. A bad signature, unreadable disk image, cancelled download, or rejected package no longer leaves a full installer sitting in temporary storage until the next day's cleanup.
Signed Sparkle updates that arrive as installer packages now work. A few apps publish a perfectly valid, cryptographically signed .pkg instead of an app archive. DuoUpdater offered those updates, downloaded them, and then tried to unpack the package as though it were a zip — an update that could never finish. They now go to macOS's own Installer, after DuoUpdater verifies both the Sparkle signature on the download and the installer identity inside it.
A disk image containing several installers is no longer allowed to make a guess. Some vendors put a main installer, helpers, and sibling products in one image. Matching on a fragment of the filename could pick a helper simply because its name contained the app's name. DuoUpdater now opens a package only when it is the sole choice or can be identified uniquely; otherwise it stops and leaves the decision to you instead of presenting the wrong installer.
The App Store helper is more tightly scoped to your login session. The privileged helper now takes the account identity directly from macOS's authenticated XPC connection and refuses a request whose claimed user does not match. Normal App Store updates behave exactly as before; the change closes off a signed client from redirecting the helper into another user's session.
Release notes show their formatting instead of its punctuation. Notes that come from a project's GitHub release were rendered exactly as written — **bold** with the asterisks, links as [text](url). Bold is now bold and links are links. This affected every app whose updates come from GitHub, which is most of the open-source ones.
Arrow-keying down the app list no longer crawls. Holding an arrow key felt like moving one row at a time through mud, and long release notes made it worse. Three things were doing it: a permission check on every app in the list ran again for every row drawn; the notes for whichever app you passed through were re-parsed on each keypress; and a long set of notes — one project's runs to 54,000 characters — was laid out in a single pass, which froze the window for about two seconds. The check is now computed once per list, parsed notes are kept, and long notes are laid out only as far as you have scrolled. Worst measured stall went from ~2.1 s to under 0.6 s, and what remains is the deliberate pause before the detail pane catches up rather than a freeze.
Input methods are never updated by replacing the app, and 微信输入法 (WeType)'s one-click from 0.3.25 is withdrawn. Settings were lost on a Mac during the work that added it. What we can show is that the copy in the protected system folder was never actually replaced by DuoUpdater — but an older copy of the input method was installed and launched elsewhere on that machine while testing, inside the window where the settings were rewritten. Nothing here is proven, and an input method's dictionary is not something to test a theory on: WeType now reports its version and sends you to the vendor's installer, which registers the input source with the system — a step that replacing the app bundle skips, and the likely reason that Mac then appeared twice in WeType's own device list.
The refusal is not specific to WeType: DuoUpdater no longer offers a one-click for anything installed as an input method, whichever vendor it comes from. Those apps still report their versions and link out.
Three more apps now report their updates, and all three install with one click. Hidden Bar, XQuartz and EasyFind were sitting in the list as a grey "unknown".
Hidden Bar is the interesting one: it ships with an update feed configured, so from the outside it looked like it was already covered. The feed answers, and is well-formed, and contains no releases at all — which is indistinguishable from a healthy feed until you look inside it. Its version now comes from its release tags instead. EasyFind ships no updater at all, so a copy installed from the vendor's site had no way to learn about new versions.
XQuartz installs through the system installer rather than by replacing the app, because it is not just an app: it lays down a whole X11 stack, and swapping only the app bundle would leave the rest at the old version. macOS asks for the administrator password itself, as it does for any package.
Thirteen more apps now report their updates, twelve of them with one click. GIMP, MongoDB Compass, Meld, Emacs, Tor Browser, Zotero, GrandPerspective, TigerVNC, qBittorrent, Opera, LibreOffice, pgAdmin 4 and Telegram Desktop were all sitting in the list as a grey "unknown" — installed, with nothing to say about them. Each was worked out by downloading the vendor's actual build and reading its identity out of it, so a one-click only appears where the download is signed by the same developer as the copy you already have. The exception is qBittorrent: its own build isn't signed by an identified developer at all, so it reports its version and sends you to the project's page.
Opera, LibreOffice and pgAdmin 4 nearly joined that exception. All three publish nothing but a directory listing, and listings sort alphabetically — "100" comes before "99" — so the newest release is not the first one on the page. Reading the version was never the problem; building a download link was, because the obvious way to build one would have picked whichever release happened to be listed first. They now download the release that was actually compared. That is the one mistake a signature check cannot catch for you: an older build of the right app, signed perfectly.
1Password and Inkscape now install with one click too, and both were previously written off. 1Password's official download turns out to be a small installer program rather than the app — signed and notarised by 1Password, so every safety check passes it, and installing it would have replaced your password manager with its own installer. DuoUpdater now fetches the package that installer itself downloads. Inkscape's download page hands out its file through a one-time link that changes with every release; the same file also sits at a plain, predictable address, which is what gets used.
微信输入法 (WeType) now installs with one click. It lives in a folder only an administrator can write to, which is why it used to only report its version. It now goes through the same administrator prompt as any other app in a protected location.
Release notes for Opera, Inkscape and 1Password. Opera publishes one page per major version, Inkscape one wiki page per release, and 1Password a feed — all three now render as proper change lists in the app instead of a link out. 1Password's version and its notes both come from that feed now, which is a published interface, rather than from scraping the page beside it.
Discord's version check works again. Discord moved its downloads to a different server and the check was still looking at the old address, so DuoUpdater quietly reported "no version" for Discord Stable while everything else kept working. It now keys off the part of the address that names the release channel, which is the part that actually has to be right.
Fifteen more apps now report their updates, and all but one install with one click. Rancher Desktop, Cherry Studio, RedisInsight, Upscayl, WailBrew, Wave Terminal, Lens, Termius, Unity Hub, iStat Menus, Inkscape, Google Gemini, Antigravity, AnyDesk and Kiro were all showing as a grey "unknown" — installed, with nothing to say about them. Each one was worked out by reading the vendor's own build rather than trusting a download page: the version now comes from wherever that app's own updater looks, and a one-click only appears where the download is signed by the same developer as the copy you already have. Three of them (Google Gemini, Antigravity, Kiro) publish nothing a download page can be scraped for; their real update services answer the same questions their own updaters ask, so that is what DuoUpdater asks too.
AnyDesk in particular was written off and shouldn't have been. Its download and changelog pages both refuse anything that isn't a person with a browser, so an earlier sweep concluded the app was unreachable. The plain-text changelog on the same server answers fine — and it is what AnyDesk's own Homebrew entry has always read.
Updating an app in a location that needs an administrator password now asks, once. Most apps live in /Applications, which you can write to; a few — input methods, for one — live where only an administrator can. Those used to show an Update button that could never work. Now the button asks for the password, and if you dismiss that prompt DuoUpdater takes the hint: the row switches to Open and stops asking on every release. "Ask for administrator access again" in the row's right-click menu brings the button back. The choice is remembered for that copy of the app specifically, so declining for one install doesn't silence another.
An up-to-date Xcode beta no longer claims the vendor is behind it. Under "Show all", a row whose vendor has fallen behind what you have installed shows a muted note saying so — you're ahead, nothing to do. Xcode was getting that note while sitting on exactly the build Apple was offering: it publishes a build number plus a human label ("27.0 beta 5"), and comparing that label against the plain "27.0" the bundle reports made a release look newer than its own beta. The note now settles on the build whenever both sides have one, so the same release is recognised as the same release however it is labelled. A vendor that has genuinely fallen behind is still called out.
44 more apps now report their updates. Apps that publish on GitHub but ship no update feed of their own used to sit in the list as a grey "unknown" — DuoUpdater could see them installed and had nothing to say about them. Bruno, UTM, kitty, KeePassXC, Godot, Bitwarden, VSCodium, draw.io, Podman Desktop, Anki, Raspberry Pi Imager, LuLu, MarkEdit, Clash Verge, Freelens, Tabby, Espanso, Moonlight, SwiftBar, Sequel Ace, balenaEtcher, DB Browser for SQLite, OpenLens, Headlamp, OpenMTP, Goose, Caffeine, noTunes, KeepingYouAwake, MiddleClick and a dozen more now show a real version, and 36 of them install with one click like any other app. Which ones was decided by downloading each vendor's actual build and reading the identity out of it, so a one-click only appears where the download is signed by the same developer as the copy you already have. Seven — Alacritty, Flameshot, MarkText, darktable, OWASP ZAP, BlueBubbles and Wine — publish builds Apple hasn't notarised, so those report their version and send you to the vendor rather than installing anything. LocalSend is report-only for a different reason, corrected here after this version shipped: its builds are notarised, but its newest release attaches no macOS download at all, so there is nothing to install until the project starts publishing one again.
Apps that already carry a Sparkle feed needed nothing: they were checked as part of this sweep and were already working, which is why names like Rectangle, Maccy, iTerm2 and Telegram aren't in the list above.
An update that your Mac couldn't run is now refused rather than installed. Where a developer publishes one download per processor, DuoUpdater picks between them by the file's name — and names are not always honest: three of the apps above ship an Apple silicon build under a name that says nothing about it, or says the opposite. Before an app is replaced, its new version is now checked against the processor in your Mac, read out of the program itself instead of its name. If it can't run here, the update stops and your working copy is left exactly as it was. Nothing about a normal update changes; this is the case that used to end with an app that no longer opened.
An unanswered permission prompt no longer leaves the update check hanging. To tell a TestFlight build apart from an App Store one, DuoUpdater reads TestFlight's own database, and macOS keeps that behind the "access data from other apps" permission. Until that was answered the read didn't fail — it waited, indefinitely, for a prompt that might be sitting behind another window or might never be answered at all, and the scan behind it simply never finished. Nothing timed out and nothing said why. It now waits a few seconds and then carries on without TestFlight's side of the story; the only thing missing in the meantime is whether those particular apps came from TestFlight, and it sorts itself out on the next scan once the permission is granted.
Homebrew updates work behind a proxy. If your Mac reaches the internet through a proxy, upgrading brew packages failed with curl: (28) Failed to connect while every other update went through fine. Homebrew shells out to curl, which — unlike the rest of DuoUpdater's networking — doesn't read the proxy you configured in System Settings; it only reads proxy environment variables, and an app launched from the Dock or at login has none. DuoUpdater now passes your system proxy settings down to Homebrew itself. Nothing changes on a machine with no proxy configured, and a proxy you've already exported in your own shell still wins.
Claude's updates now show up while they're still rolling out. Anthropic releases Claude in stages: a build goes to a fraction of Macs at a time, and the public download page only catches up at the end. DuoUpdater was reading that public page, so for the whole of a rollout — most of a day, in the case of 1.30096.5 — it told you Claude was up to date while Claude itself had already quietly downloaded the new version and was waiting for a relaunch. It now also asks the same endpoint Claude's own updater asks, which answers for your Mac specifically, and offers whichever of the two is further ahead. Nothing about which build you're offered has changed: it is either the public release or the one your Mac was already allocated. Claude also gains real publication times, so its releases now appear in the Release Log with the moment Anthropic shipped them rather than an estimate.
A superseded package update no longer leaves its window sitting there. Updates that go through macOS's own installer — Microsoft Office, AweSun, ToDesk — open an Installer window and then wait for you. If you left one open and a newer release came along, installing that one opened a second window, and they stacked up. The older window is now closed once its replacement is ready, and its download cleaned up with it. A window that's mid-install, or asking for your password, is left strictly alone.
duo says which copy is which when two apps share a name. Naming an app that is installed twice — two Xcode betas, say — printed both candidates as a bare "Xcode" and told you to name one exactly, which matches both again. The listing now carries each copy's version, and when the matches genuinely share a name it asks for the path instead of repeating advice that cannot work.
"Open download page" no longer downloads a file. On apps whose page DuoUpdater knows — ToDesk and UU Remote among them — that button handed your browser the installer package instead of opening anything: the link it used was the same one the updater downloads from, so clicking it started a download you didn't ask for. The page and the package are now kept apart, and the button opens the vendor's actual download page. Where a source only ever publishes a package and no page at all — a bare Sparkle feed — there is now no button rather than one that downloads something.
The app list responds to the arrow keys again. Opening the workbench window left the keyboard focus nowhere in particular, so ↑ and ↓ did nothing until you clicked a row — and after clicking into the release notes on the right, or switching to another app and back, they stopped working again. The list now takes the keyboard when it opens and takes it back at the points it used to lose it. Typing in the search box is untouched: a search you've started keeps the caret.
The Brew section starts collapsed. Casks and command-line formulae are a side channel for most people, and having that tree open by default pushed your actual apps up the sidebar every time the window opened. It now starts closed and remembers however you leave it.
Xcode betas and release candidates are now detected, and two copies can be told apart. Xcode was a grey "v27.0" with no update information at all, and if you keep more than one build around — a current beta beside the previous one — they were indistinguishable: same name, same version, same icon. Each row now reads its real build, so an update shows as "27.0 beta 1 (27A5194q) → 27.0 beta 5 (27A5237l)". Which track a copy belongs to is worked out from Apple's published builds rather than guessed from what you named the folder, and you'll only ever be pointed at something at least as finished as what you have — a beta can be superseded by a beta, a release candidate or the finished release, never the other way round. Updating still means going to Apple: the downloads need you signed in with your Apple ID, so the row links to Apple's download page and its release notes.
Cursor's release notes are shown properly instead of an embedded web page. Cursor writes its changelog as dated posts rather than numbered releases, so the notes pane fell back to loading the website. Each post is now shown as its own entry — its date, its headline and its changes — the same as every other app with readable notes.
duo check now shows what changed when the version number doesn't. Updates that keep the same version and only move the build — Surge, the JetBrains previews — printed as "6.9.0 → 6.9.0" on the command line, which was accurate and told you nothing. It now shows the builds, matching what the menu bar has always shown.
Apps that ship their own updater are now updated directly by default. These are the ones like Chrome, VS Code, Cursor and the Electron apps — and because they are also the apps you tend to leave running all day, the old default of stepping aside while they were open meant they were almost never updated at all: the row offered to open the app and left the rest to you. DuoUpdater now downloads the vendor's own installer and applies it whether or not the app is running, then quits and relaunches it so the new version takes effect. Anything that installs background components alongside the app — Tailscale, Office — ships a package that macOS's own installer handles, so those pieces are still put in place properly. If you would rather nothing was touched while an app is open, Settings → General → Self-updating apps still has the old behaviour, and changing it back does not affect anything already installed.
An app whose developer changed its update signing key can be updated again. Apps that update through Sparkle sign each release with a key, and the copy you already have carries the matching public key to check it against. If a developer generates a new key and ships it without a hand-over release signed by the old one, that check fails for everybody — the app's own updater is just as stuck as DuoUpdater was, and the update sits there refusing to install with a signature error. DuoUpdater now recognises that specific situation: when the new download carries a different key of its own and the release was signed with it, it stops trusting the signature and falls back to the same checks it uses for apps that publish no signature at all — the download must be validly signed by Apple's developer certificates, and by the same developer as the app it is replacing, for the same app. A download that fails any of that is still refused, as is a bad signature that isn't explained by a key change. Mirage Beacon 1.3.0 was the first to hit this.
Update All no longer says a running app is finished before its restart. When an update had already replaced an app on disk but Update All was still busy with other installers, the row briefly showed a green checkmark and disappeared even though the old version was still running. The app now stays visible with its running and installed versions, explains that it is waiting for the batch restart, and offers Restart now. The completion checkmark appears only when the update is actually in effect.
Apps installed by a .pkg can now be rolled back. DuoUpdater keeps a copy of the previous version before it updates an app, so a bad update can be undone. Apps that install through macOS's own installer — Microsoft Office, AweSun, ToDesk and the like — never got that copy: the rollback was skipped for them entirely, so the one kind of update DuoUpdater can't watch land was also the one you couldn't back out of. They're now backed up like everything else.
Rollback no longer refuses apps that write inside their own bundle. Some apps keep working files in amongst their own program files — ToDesk stores its settings database and logs there, and doing so breaks the seal Apple puts on an app. DuoUpdater checked that seal before restoring a backup, so for those apps it declared a perfectly good backup damaged and refused to put it back. It now checks the copy against a fingerprint taken when the copy was made, which is the thing that actually matters: that what's being restored is exactly what was saved. Tampering with a stored backup is still caught, and still refused.
When a backup isn't possible, it says so instead of failing quietly. A few apps keep program files that your account simply can't read — EasyConnect is one — and no copy of those can be made. Rather than attempting it and reporting a failure part-way through an update, DuoUpdater now checks first, tells you which file is in the way, and updates anyway; you just don't get a rollback point for that one app.
The same app no longer appears several times over. Some apps leave a dated copy of themselves behind every time they update — DuoPaste, for one, parks a DuoPaste.backup-20260716-183428.app next to the real thing on each self-update. Those copies are complete, working app bundles as far as anything on disk can tell, so DuoUpdater listed each one as its own app: three identical DuoPaste rows, each offering the same update. Worse, taking one of those offers would have installed the new version into the backup, leaving the app you actually use untouched and creating another stray copy. Backup and duplicate bundles are now recognised for what they are and left out of the list, as are exact clones of an app found in two places. Genuinely separate installs that happen to share an identity — Firefox alongside Firefox Beta, two versions of Android Studio kept side by side — still each get their own row.
The list now reliably notices apps appearing and disappearing. DuoUpdater watches your Applications folders so that an app updating itself in the background, or one you drag to the Trash, is reflected within a few seconds. That watch could quietly stop working — nothing crashed, nothing was reported, it simply stopped hearing about changes, and the list then went stale until you reopened the window. It's now rebuilt periodically and after your Mac wakes from sleep, with a fresh scan each time, so a watch that dies recovers on its own instead of staying dead for the rest of the session.
An app that gets restarted after an update no longer jumps in front of what you're doing. When DuoUpdater updates an app that's currently running, it quits and reopens it so the new version actually takes effect. Reopening it also pulled it to the front — so an update to something sitting quietly in the background could drop a window on top of the thing you were typing into. The app's position now survives the restart: whatever was in front comes back in front, and whatever was in the background comes back in the background, still there and still updated, just not in your way. The same applies to apps DuoUpdater reopens after an App Store update. Apps that weren't running at all are, as before, updated on disk and left closed — updating an app never starts it up.
Fixes AweSun's update failing with "the server returned HTTP 404". DuoUpdater worked out where to download AweSun's installer by building the filename itself from the version number. Oray then renamed the file — the same 16.6.0 build, one letter's difference — and every attempt at the update hit a dead link. It now takes the filename straight from Oray's own download listing rather than guessing at it, so a future rename won't break it again.
An installer you've already downloaded no longer downloads again. Some apps update through an installer package that macOS opens for you to confirm. If you closed that window without finishing — or quit DuoUpdater and came back — the row went back to offering "Update", and taking it fetched the whole package a second time. ToDesk's is 375 MB. The download was on your disk the entire time; nothing was pointing at it. Those rows now offer "Install" instead, which just re-opens the file you already have. If the installer window is still open it comes forward rather than opening a second one, and the offer stands until either the download is gone or a newer version comes out — at which point the old package would be the wrong one, so the row goes back to a normal "Update".
Homebrew packages that aren't apps now show up. DuoUpdater tracked outdated Homebrew formulae, and left casks alone on the grounds that a cask installs an app, which already gets its own row. That holds right up until a cask installs no app — a command-line tool like codex, a font, a driver. Those had no row anywhere: nothing for the app list to find, and not a formula either. codex sat three versions behind without a word. They're now part of the Homebrew panel, which reads "packages" rather than "formulae" to match. Casks that do install an app are still managed per-app exactly as before, and apps that update themselves are still left to their own updater.
"Update All" now includes apps that install from a package. A handful of apps — ToDesk and AweSun among them — ship their update as an installer package rather than something DuoUpdater can swap into place on its own. Those were quietly left out of "Update All" and had to be updated one row at a time; if such an app was the only other update pending, the button disappeared altogether rather than acting on just one. They're now part of the batch, and they run at the very end: everything that updates unattended finishes first, so nothing opens a window or asks for your admin password until the rest is already done. One caveat worth knowing — DuoUpdater can't tell when macOS's installer has finished, so if two package updates come up in the same batch, both installer windows open one after the other rather than waiting in line.
Fixes updates going unnoticed for days at a time. DuoUpdater re-uses the answers it gets from each app's version feed so it isn't re-downloading the same file every few minutes. The problem was how long it trusted a stored answer: when a vendor's server doesn't say how long its reply stays valid, macOS guesses — and it guesses longer the longer that feed has gone unchanged. So the very feeds that had been quiet for a while were exactly the ones DuoUpdater stopped re-reading, and a new release could sit there for days with the app still reporting "up to date" and no error to show for it. Every version check now always asks the server whether anything changed, while still skipping the download when nothing has. OrbStack 2.2.2 is the release that surfaced this; the same blind spot applied to most apps checked directly against their vendor, including Chrome, Cursor, Claude, ChatGPT, Warp, Spotify, and Visual Studio Code.
Homebrew-managed apps no longer get stuck at the version they were on when DuoUpdater started. The catalog DuoUpdater reads to learn the latest version of a Homebrew app was loaded once per launch and never refreshed, which is invisible if you quit the app daily and wrong if you leave it running for weeks. It now refreshes periodically. As a bonus, machines with no Homebrew casks installed no longer download that 5 MB catalog at all.
Uses less memory and does less work in the background. This release is entirely under the hood — nothing about what DuoUpdater does has changed, only what it costs to leave running. Every update it downloaded used to leave a small amount of memory behind that was never reclaimed; harmless once, but it adds up over the weeks a menu-bar app tends to stay open. Separately, while the main window was open DuoUpdater re-read every installed app from disk every 15 seconds and started a system process each time to see what was running — that now happens every three minutes, since the filesystem watcher already notices a real change the moment it happens. Recording the release history after each check also used to save its file once per app rather than once per check, and release notes could be fetched more than once when the same page was already on its way in.
No more beachball while an app is relaunching. Clicking Update on another app while one was being quit and relaunched could freeze DuoUpdater for a moment — the spinning rainbow cursor, an unresponsive window, a click that seemingly did nothing. Relaunching an app now happens in the background instead of on the interface, so the rest of the list stays live and clickable throughout. The same freeze could show up when opening an app from a row's right-click menu, or when handing an update off to an app's own updater; both are fixed too.
Backups from uninstalled apps are now cleaned up automatically. DuoUpdater keeps one backup of an app's previous version so an update can be rolled back. Backups for apps you've since uninstalled or moved were never reclaimed and could quietly pile up gigabytes of disk space over time. They're now deleted automatically during the regular update check. Settings shows how much space backups are currently using, with a toggle to turn off the automatic cleanup and a "Clean Up Now" button to run it on demand.
JetBrains Toolbox apps no longer show a stuck or incorrect "update available." Version checks for Toolbox-managed apps (IntelliJ, Android Studio, Fleet, Air, and others) now always ask live rather than sometimes falling back to a local cache that could never actually report a new version — it fixes both a status that lingered after Toolbox had already installed the update, and one that never appeared in the first place.
Claude Desktop's release notes are now shown in DuoUpdater. Update entries for Claude Desktop now include Anthropic's own per-version changelog instead of a generic notice.
Update All now also relaunches apps that were only waiting on a restart. If an app had already downloaded its update and just needed a relaunch to finish — Claude, for instance — clicking Update All used to skip it, leaving a stray "Relaunch" button behind. It now relaunches those too, in the same pass, whenever automatic restart-after-update is on.
App Store updates recover from a receipt hiccup instead of just failing. Occasionally a Mac App Store update downloads in full but the very last install step trips over a "receipt" error — a transient App Store glitch that a second attempt usually clears. DuoUpdater now retries once automatically. If it still doesn't take, the row offers an "Open App Store" button to finish the update from the App Store's Updates page, instead of leaving a raw error on screen.
ToDesk update detection fixed. A change to ToDesk's download page stopped DuoUpdater from reading its latest Mac version, so ToDesk updates went unnoticed. Detection now reads the version reliably again.
App Store updates no longer show a scary error for an app that's already up to date. If the Mac App Store had quietly updated an app in the background — TestFlight, say — DuoUpdater's row could go stale and, on Update, try to reinstall the version that was already there. macOS's installer rejects that with an alarming red "The upgrade failed", even though nothing was actually wrong. DuoUpdater now confirms an App Store app really is behind before reinstalling, and treats a no-op reinstall as "already up to date" — settling the row quietly instead of showing an error.
App Store updates now ride out network hiccups. A brief connection drop mid-update — a flaky link, or a proxy resetting the connection — used to fail an App Store update outright with a "could not connect to the server" error. Those updates now retry automatically a few times before giving up, so a momentary blip no longer strands an update that a second attempt lands cleanly. Clicking Update again after a failure also clears the old error immediately, instead of leaving it on screen next to the spinner.
Apps that update themselves clear from the list faster. When an app like Chrome finishes updating itself in the background while an App Store update is running, its "update available" row now clears promptly — it no longer lingers until the rest of the queue finishes.
One-click updates for four more apps. HBuilderX, JetBrains Toolbox, and Microsoft Edge's Beta and Dev channels now update in place with a single click, instead of only telling you that an update exists. HBuilderX also now reads its version straight from DCloud's own release feed, so it picks up new builds sooner and more reliably.
Self-updating apps stay in their own lane. A running app that ships its own Sparkle updater is now handed off to that updater — the same courtesy DuoUpdater already gave other self-updating apps — instead of being replaced underneath it, unless you've chosen "Always replace" in Settings.
Fixes
Fixes
See when your apps actually ship. DuoUpdater now keeps a Release Log: a running timeline of every release the apps you track put out, each stamped with its publish time. Open it from the clock icon at the bottom of the popover.
Release-habit heatmap. A new Patterns view charts releases by weekday and hour, so you can see when an app tends to ship — pick any single app for its own pattern and version history, or view all of them together. History is backfilled from each app's update feed, so the heatmap is useful right away instead of starting empty.
Honest about what it can't time. Apps that publish an exact release date (Sparkle, GitHub, Alcove) are timed to the minute. Apps that only expose a version number get a clearly-marked "≈" estimated window — bounded by when DuoUpdater last saw the old version and first saw the new one — and never skew the heatmap.
Fixes
Passwordless App Store updates. Updating Mac App Store apps no longer interrupts you for your password every time. DuoUpdater now installs a small, signed privileged helper (one-time approval) and bundles mas, so App Store updates apply directly in the background.
Cleaner "Restart to finish" lines. When an app updates itself on disk while it's still running, the pending-restart line now shows the real marketing version on both sides — e.g. 1.8.x (build) → 1.9.0 (build) instead of a bare build number on the left.
Fixes
Apps that update themselves now clear correctly. If an app updated through its own updater (for example, Chrome via "About Chrome") while DuoUpdater was busy installing other updates, it could keep showing a stale "update available" row long after it was already current. DuoUpdater now re-checks the moment the installs finish, so the row clears right away instead of lingering.
"Update All" shows the whole queue. Every app in an "Update All" run now shows a "Queued" state immediately, instead of leaving the ones further down the list looking idle with a clickable Update button. Clicking Update on an app that's already queued can no longer start a second install of it.