diff --git a/backend/app/api/extension.py b/backend/app/api/extension.py index 54d569f..4f4766f 100644 --- a/backend/app/api/extension.py +++ b/backend/app/api/extension.py @@ -93,10 +93,20 @@ def _read_manifest_sync() -> dict | None: asyncio.to_thread (ASYNC240: no pathlib I/O in async functions).""" if not XPI_DIR.is_dir(): return None - xpis = sorted(XPI_DIR.glob("fabledcurator-*.xpi"), key=lambda p: p.stat().st_mtime) - if not xpis: + # Exclude the `fabledcurator-latest.xpi` alias when picking the file to + # extract a version from — it's a copy of the latest versioned XPI, + # written at the same mtime by build.yml, and would otherwise tie or + # win the sort (operator-flagged 2026-05-26: UI displayed "v latest" + # because `_extract_version("fabledcurator-latest.xpi")` returns + # the literal "latest"). The alias still serves as `latest_url`. + versioned = [ + p for p in XPI_DIR.glob("fabledcurator-*.xpi") + if p.name != "fabledcurator-latest.xpi" + ] + if not versioned: return None - latest = xpis[-1] + versioned.sort(key=lambda p: p.stat().st_mtime) + latest = versioned[-1] return { "installed": True, "version": _extract_version(latest.name), diff --git a/frontend/src/components/settings/BrowserExtensionCard.vue b/frontend/src/components/settings/BrowserExtensionCard.vue index 2dbe591..db5d3a3 100644 --- a/frontend/src/components/settings/BrowserExtensionCard.vue +++ b/frontend/src/components/settings/BrowserExtensionCard.vue @@ -34,11 +34,18 @@