') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); emrg: GUI upgrade banner — show version range from→to (rant 2026-08-21T12:44:34) by argszero · Pull Request #913 · argszero/emrg · GitHub
Skip to content

emrg: GUI upgrade banner — show version range from→to (rant 2026-08-21T12:44:34) - #913

Merged
argszero merged 2 commits into
masterfrom
feature/gui-upgrade-banner-from-to
Aug 21, 2026
Merged

emrg: GUI upgrade banner — show version range from→to (rant 2026-08-21T12:44:34)#913
argszero merged 2 commits into
masterfrom
feature/gui-upgrade-banner-from-to

Conversation

@argszero

Copy link
Copy Markdown
Owner

Summary

Fixes rant 2026-08-21T12:44:34 (banner item) — the GUI upgrade-complete banner now shows the version range instead of only the target version: "EMRG 已从 0.2.57 升级到 0.2.61,重启后生效".

Changes

  • emrg/server/daemon.py — new _previous_installed_version() reading ~/.emrg/install/previous-version.txt; pong payload now carries both current_version and previous_version (raw data only, zero judgment).
  • emrg/server/prompts/upgrade_prompt.j2 — instructs the upgrade agent to copy the current version.txt content to previous-version.txtbefore overwriting it (and to remove a stale previous-version.txt on first install).
  • emrg/gui/main.js — init + status pushes forward previous_version from the pong.
  • emrg/gui/renderer/js/app.jsmaybeShowUpgradeBanner(currentVersion, previousVersion) shows the from→to message when a previous version is available (and differs), falling back to the old single-version message otherwise. state.previousVersion initialized from init and updated on pong.
  • emrg/gui/renderer/js/i18n.js — new app.upgradeBannerMsgFromTo key (zh + en).
  • emrg/gui/test/renderer.smoke.test.js — banner test extended to assert the from→to text.
  • tests/test_daemon.py — new test_pong_includes_previous_version (positive + missing-file + pong payload).
  • Agent.md — Python count 988→989.

Verification

  • Python: uv run pytest tests/ — 988 passed + 1 skipped (989 collected), incl. the new pong test
  • GUI: npm test — 255 tests, 247 pass, 8 skipped, 0 fail
  • node --check + import + CLI OK

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle

Fresh review of the upgrade-banner range change (rant 2026-08-21T12:44:34):

  • daemon: _previous_installed_version() reads ~/.emrg/install/previous-version.txt (raw data, "" when missing — dev/first-install safe); pong carries both current_version and previous_version.
  • upgrade_prompt.j2: agent instructed to copy current version to previous-version.txt before overwriting version.txt (and clear stale record on first install) — closes the persistence loop so even a fresh GUI launch shows the range.
  • GUI: maybeShowUpgradeBanner(current, previous) shows from→to when previous differs, falls back to the old single-version message otherwise; state.previousVersion threaded from init + pong. i18n added for both zh/en.
  • Tests: banner test asserts "0.2.57 → 0.2.61" text; new daemon pong test covers positive + missing-file + payload. Agent.md Python 988→989.
  • Verified: Python pytest 988 passed + 1 skipped, GUI npm test 255 (247+8), import + CLI OK. CI test + test-windows PASS.

1/3.

@pm25coder

Copy link
Copy Markdown
Collaborator

Independent test report (Contributor, pm25coder):

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle

2nd review (head cc6e14c, CI test + test-windows PASS on run 32449902478):

  • Fresh local verification: Python pytest 988 passed + 1 skipped (989 collected, matches Agent.md), GUI npm test 255 (247 pass / 0 fail / 8 skipped), import + CLI OK.
  • daemon: _previous_installed_version() reads ~/.emrg/install/previous-version.txt with OSError/ValueError fallback to "" (dev/first-install safe); pong now carries previous_version alongside current_version.
  • upgrade_prompt.j2: agent copies the pre-overwrite version into previous-version.txt before writing version.txt, and clears stale record on first install — closes the persistence loop so the banner range survives a fresh GUI launch.
  • GUI: maybeShowUpgradeBanner(current, previous) renders from→to when previous differs, falls back to the single-version message otherwise; state.previousVersion threaded from init + status events. i18n zh/en keys added.
  • Tests: banner smoke asserts both "0.2.57" and "0.2.61" in the message; new daemon pong test covers previous-version payload. Both positive/negative paths exercised.

2/3. Note: master advanced since this PR's base (#912 merged) — the final merge will need the resolved tree re-verified, but no code conflicts expected (Agent.md Python line vs #912's GUI line merge cleanly).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle

3rd consecutive review (head ec88809 — conflict-resolved merge of master, CI test + test-windows PASS on the resolved tree):

  • Fresh local verification on the merged tree: pytest 988 passed + 1 skipped (989 collected, matches Agent.md), import + CLI OK.
  • Conflict resolution: #912's heartbeat merge touched main.js + Agent.md; merged tree has both #912 heartbeat and #913 banner changes; Agent.md now Python 989 / GUI 256 (127 renderer smoke); no conflict markers left.
  • Code (from earlier review, unchanged in substance): daemon _previous_installed_version() reads ~/.emrg/install/previous-version.txt (raw data, '' when missing — dev/first-install safe); upgrade_prompt.j2 copies version.txt → previous-version.txt before overwrite; pong carries current + previous version; GUI banner shows from→to when previous version differs, falls back to single-version message; i18n key zh+en.

3/3.

@argszero
argszero merged commit bd3797e into masterAug 21, 2026
2 checks passed
@argszero
argszero deleted the feature/gui-upgrade-banner-from-to branch August 23, 2026 02:26
Sign up for freeto 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.

2 participants

@argszero@pm25coder