Skip to content

Report git-managed plugins that are behind their origin - #10326

Open
x3m wants to merge 1 commit into
omacom:quattrofrom
x3m:plugin-updates-in-update-check
Open

Report git-managed plugins that are behind their origin#10326
x3m wants to merge 1 commit into
omacom:quattrofrom
x3m:plugin-updates-in-update-check

Conversation

@x3m

@x3m x3m commented Sep 5, 2026

Copy link
Copy Markdown

Nothing checks plugins for updates. omarchy-update-available covers the dev checkout and the Omarchy package, and omarchy-update reloads plugins without ever pulling them, so a git-managed plugin can sit indefinitely behind its origin with nothing saying so. On my own machine this change immediately found two:

plugin io.github.pablo-merino.altswitch 5 new commits
plugin mirador has an update

The check is read-only

git ls-remote asks each origin for its HEAD without writing an object or moving a ref in the user's checkout. Fetching belongs to omarchy plugin update, which shows the diff before it pulls, and a background check that runs every six hours should not be mutating repositories on the side.

A plugin is reported only when origin holds a commit the checkout does not, so a plugin carrying local commits is left alone rather than nagged. The commit count is printed when the remote commit is already present locally — which it is whenever someone has looked at an update and declined it, since that path fetches before showing its diff — and omitted when it is not, because "the remote has moved somewhere this checkout has never seen" is all that can honestly be said then.

Each plugin gets five seconds, and an unreachable or authenticating origin is quiet: GIT_TERMINAL_PROMPT=0 and ssh -oBatchMode=yes keep a private remote from hanging on a prompt.

Why this also touches omarchy-update

The widget only sees the exit code, and its button launches omarchy-update. Letting a plugin flip that exit code on its own would light the icon and hand the user a button that does nothing about what was reported. So omarchy-update now offers each behind plugin's diff for confirmation, after the packages and migrations are done and before the restart that reloads them.

Two constraints kept: unattended runs (omarchy update -y) skip plugins rather than fast-forward third-party code nobody has read, and a plugin whose remote is unreachable cannot take the system update down with it.

If you would rather keep the update pipeline untouched, I am happy to reshape this — but the two halves have to agree about whether a plugin update is something the user is told about.

Tests

test/shell.d/update-available-test.sh gains three cases. The plugin checkouts in them are real repositories with a real local origin rather than a mock, so what is asserted is the ancestry logic itself, and the git stub now hands anything that is not the dev checkout to real git. Covered: behind with the commit already fetched (exact count), behind without it (no count), current, ahead of origin, a directory that is not a checkout, a checkout with no remote, no plugins installed at all, and a plugin-only update still signalling the widget.

The suite's run_checker now always points HOME at a controlled directory, so the developer's own plugins cannot decide the result of a test.

./test/cli passes. ./test/shell reports 223 of 226 files passing; the three failures (config-test, snapper-test, unowned-system-paths-test) fail identically on a clean checkout of this machine and are unrelated.

Nothing checked plugins, so a plugin could sit years behind with nothing
saying so: omarchy-update-available covered the dev checkout and the
Omarchy package, and omarchy-update reloaded plugins without ever pulling
them.

The check is read-only. git ls-remote asks each origin for its HEAD
without writing an object or moving a ref in the user's checkout, because
fetching belongs to omarchy plugin update, which shows the diff before it
pulls. A plugin is reported only when origin holds a commit the checkout
does not, so one carrying local commits is left alone. The commit count is
printed when the remote commit is already local — which it is whenever the
user has looked at an update and declined it, since that path fetches
first — and omitted when it is not. Each plugin gets five seconds and an
unreachable origin is quiet.

Since the widget only sees the exit code, and its button runs
omarchy-update, that command now offers each behind plugin's diff for
confirmation once the packages are done. Unattended runs skip plugins
rather than fast-forward third-party code nobody has read, and a plugin
whose remote is unreachable cannot take the system update down with it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UFJYYVe1KDFKDbrT8yMbFf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant