{"id":"plugin-updates","repo":"xpufx/paseo","url":"https://github.com/xpufx/paseo/tree/main/plugins/plugin-updates","name":"plugin-updates","description":"Monitor installed Paseo plugins for git-source updates, with per-subdirectory status, source links, and one-click pulls.","categories":["other"],"platforms":[],"caveats":[],"images":["https://raw.githubusercontent.com/xpufx/paseo/0ae17457a644cbc325beb5a35163b5e2995b08bb/plugins/plugin-updates/screenshots/plugin-updates-main.jpg","https://raw.githubusercontent.com/xpufx/paseo/0ae17457a644cbc325beb5a35163b5e2995b08bb/plugins/plugin-updates/screenshots/plugin-updates-action.jpg"],"health":{"manifestValid":true,"hasReadme":true,"hasLicense":true,"hasTests":true,"hasTypecheckScript":true,"updatedRecently":true},"scannedAt":"2026-09-18T07:58:09.262Z","addedAt":"2026-09-18T07:51:04Z","path":"plugins/plugin-updates","version":"0.1.0","security":{"status":"passed","blockingFindings":0,"advisoryFindings":0,"scannedAt":"2026-09-18T07:55:34.572Z","commit":"0ae17457a644cbc325beb5a35163b5e2995b08bb"},"license":"MIT","paseoVersionRequirement":">=0.8.0","manifest":{"id":"plugin-updates","requirements":{"paseo":">=0.8.0"}},"repoMeta":{"stars":1,"defaultBranch":"main","pushedAt":"2026-09-17T11:33:39Z"},"owner":{"login":"xpufx","avatarUrl":"https://avatars.githubusercontent.com/u/25581961?v=4"},"installNotesHtml":"<p>Install from the public monorepo subpath (GitHub shorthand):</p>\n<pre><code class=\"language-sh\">paseo plugin add xpufx/paseo --path plugins/plugin-updates\n</code></pre>\n<blockquote>\n<p>[!NOTE]\nBare <code>owner/repo</code> shorthand resolves against <strong>GitHub</strong> only. For any other forge, pass the full git URL instead, for example <code>https://git.example.com/owner/repo</code>.</p>\n</blockquote>\n<p>For local development:</p>\n<pre><code class=\"language-sh\">git clone https://github.com/xpufx/paseo.git\ncd paseo\npaseo plugin add ./plugins/plugin-updates\n</code></pre>","limitationsNotesHtml":"<ul>\n<li><strong>Local git installs are report-only.</strong> With no upstream remote or recorded ref, there is nothing to compare against or pull, so no <strong>Update</strong> button is offered for them. Use a git remote + subpath to get updates.</li>\n</ul>","readmeText":"# plugin-updates\n\nGit-source update monitor and updater for [Paseo](https://github.com/getpaseo/paseo) plugins (v0.8+).\n\n<table align=\"center\">\n  <tr>\n    <td align=\"center\"><strong>main</strong><br><img src=\"screenshots/plugin-updates-main.jpg\" alt=\"Plugin updates — main view\" width=\"300\"></td>\n    <td align=\"center\"><strong>updating</strong><br><img src=\"screenshots/plugin-updates-action.jpg\" alt=\"Plugin updates — updating\" width=\"300\"></td>\n  </tr>\n</table>\n\nAdds a header button to every workspace that opens a popover listing the installed plugins. Each row reports whether the plugin's installed git source is current, behind, pinned, missing, or has no upstream, and offers a one-click update when a pullable change exists.\n\nBuilt on [paseo-plugin-helper](https://github.com/xpufx/paseo/tree/main/packages/paseo-plugin-helper), the shared Paseo plugin runtime.\n\n> [!NOTE]\n> **Prerequisites & Platform Support**:\n> - The system `git` CLI must be available, because update checks and pulls shell out to `git`.\n> - Developed and tested primarily on **Linux**.\n\n## Core Capabilities\n\n### 1. Workspace Header Button\n- Registers a header button once per workspace, titled **Plugin updates**, that opens a popover listing every installed plugin.\n- The button shows a refresh glyph while a check is running, and a status dot in the corner: green when everything is fresh, amber while checking or when an update is available, and red when a check fails.\n\n### 2. Per-plugin Git Status\nEach row resolves the plugin to its git repository root, ref, and subdirectory, then probes the remote to classify the install:\n\n- **current**: the local commit or subdirectory tree matches the tracked ref, or the local checkout is ahead of the remote.\n- **behind**: the remote ref has commits the local checkout does not, so an update is available.\n- **pinned**: the install is pinned to a fixed tag or commit. Pinned installs are report only; nothing is ever pulled for them.\n- **no-upstream**: no upstream remote is configured, or the tracked branch or tag no longer exists on the remote.\n- **missing**: the remote is reachable but the plugin subdirectory does not exist at the tracked ref.\n- **unpinned**: a detached HEAD, or a managed install with no recorded ref. Report only.\n- **not-a-repo**: the plugin is not a git checkout, so no git update is possible.\n- **error**: the check itself failed, for example because the remote was unreachable.\n\n### 3. Per-subdirectory Scoping\n- Plugins installed from a monorepo subpath track only that subdirectory tree. A commit that touches other paths in the same repository does not register as an update.\n- The row shows the resolved **Subdir** (`(repo root)` when the plugin is the repository root), alongside the local and remote tree hashes and the tracked ref.\n\n### 4. Source Links\n- Each row resolves a browsable source URL from the remote the plugin was installed from, falling back to `package.json` `repository` and `homepage` metadata when no install remote exists.\n- GitHub, GitLab, and unknown forges get an appropriate glyph, and links deep-link into the subdirectory for GitHub (`/tree/<ref>/<subdir>`) and Forgejo/Gitea-style (`/src/branch/<ref>/<subdir>`) hosts.\n- A `dirty` badge appears on a directory install when the plugin scope has uncommitted changes.\n\n### 5. Update Action\n- Available updates show an **Update** button in the row. After a failed pull that needs an override, the button becomes **Force update**.\n- **git-managed installs** delegate to `paseo plugin update <id>`.\n- **directory (path-linked) installs** resolve the repository root and run a fast-forward `git pull`. The pull is refused when the working tree is dirty unless forced, and refused when the local branch has diverged from its upstream.\n- After a successful pull, every plugin that shares the same repository root is reloaded.\n- When more than one plugin has an update, an **Update all** button appears. If any failure requires an override, **Force update all** is offered instead.\n\n### 6. Orphaned Directory Flagging\n- Directories left behind in Paseo's managed plugin location by an uninstalled or failed install are listed in a separate **Orphaned directories** section with a name and path.\n- Orphans are reported only; they are never probed or updated.\n\n### 7. Live Refresh\n- The popover re-checks on a 30 second interval and on demand through the refresh button, and reports the available update count in its header.\n\n## Installation\n\nInstall from the public monorepo subpath (GitHub shorthand):\n\n```sh\npaseo plugin add xpufx/paseo --path plugins/plugin-updates\n```\n\n> [!NOTE]\n> Bare `owner/repo` shorthand resolves against **GitHub** only. For any other forge, pass the full git URL instead, for example `https://git.example.com/owner/repo`.\n\nFor local development:\n\n```sh\ngit clone https://github.com/xpufx/paseo.git\ncd paseo\npaseo plugin add ./plugins/plugin-updates\n```\n\n## Usage & Configuration\n\n- No settings are required. The header button registers automatically in each workspace that has an agent session.\n- Open the button to see installed plugins, their status, and available updates, then use the row **Update** button or **Update all** to pull and reload.\n- Checks run against the plugin's install remote only, so a fork or mirror installed as the source is what gets compared.\n- Pulls run with `--ff-only`. A dirty working tree or a diverged branch must be reconciled manually before an update can apply.\n\n## Limitations\n\n- **Local git installs are report-only.** With no upstream remote or recorded ref, there is nothing to compare against or pull, so no **Update** button is offered for them. Use a git remote + subpath to get updates.\n\n## Development\n\n```sh\n# Typecheck\nnpm run typecheck --workspace=plugins/plugin-updates\n\n# Typecheck plus the test suite (tsx --test)\nnpm run test --workspace=plugins/plugin-updates\n\n# Reload in a running Paseo daemon\npaseo plugin reload plugin-updates\npaseo plugin logs plugin-updates\n```\n\n## License\n\nMIT\n"}