From ae2c786d3a64d0e44591f2b315a37360eaddf498 Mon Sep 17 00:00:00 2001 From: Ethanfel Date: Sun, 22 Feb 2026 14:00:05 +0100 Subject: [PATCH] Mark removed/disabled packages as uninstalled Packages that only exist in the DB but are no longer in NODE_CLASS_MAPPINGS or LOADED_MODULE_DIRS get status "uninstalled" and appear in a separate greyed-out section at the bottom of the dialog. Co-Authored-By: Claude Opus 4.6 --- js/nodes_stats.js | 7 +++++++ tracker.py | 8 ++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/js/nodes_stats.js b/js/nodes_stats.js index a8dc341..c12de68 100644 --- a/js/nodes_stats.js +++ b/js/nodes_stats.js @@ -88,6 +88,7 @@ async function showStatsDialog() { const considerRemoving = custom.filter((p) => p.status === "consider_removing"); const unusedNew = custom.filter((p) => p.status === "unused_new"); const used = custom.filter((p) => p.status === "used"); + const uninstalled = custom.filter((p) => p.status === "uninstalled"); let html = `

Node Package Stats

@@ -133,6 +134,11 @@ async function showStatsDialog() { html += buildTable(used, "used"); } + if (uninstalled.length > 0) { + html += sectionHeader("Uninstalled", "Previously tracked, no longer installed", "#555"); + html += buildTable(uninstalled, "uninstalled"); + } + dialog.innerHTML = html; overlay.appendChild(dialog); document.body.appendChild(overlay); @@ -168,6 +174,7 @@ const STATUS_COLORS = { consider_removing: { bg: "#2a2215", hover: "#3a2e20" }, unused_new: { bg: "#1a1a25", hover: "#252530" }, used: { bg: "#151a15", hover: "#202a20" }, + uninstalled: { bg: "#1a1a1a", hover: "#252525" }, }; function buildTable(packages, status) { diff --git a/tracker.py b/tracker.py index ae727af..bd13b42 100644 --- a/tracker.py +++ b/tracker.py @@ -130,10 +130,12 @@ class UsageTracker: } packages[pkg]["total_nodes"] = total - # For packages that came only from DB (e.g. uninstalled), fill total_nodes + # Packages only in DB (not in mapper) are uninstalled/disabled + installed_packages = set(node_counts.keys()) | mapper.get_all_packages() for pkg, entry in packages.items(): if "total_nodes" not in entry: entry["total_nodes"] = entry["used_nodes"] + entry["installed"] = pkg in installed_packages # Classify packages by usage recency now = datetime.now(timezone.utc) @@ -142,7 +144,9 @@ class UsageTracker: tracking_start = self._get_first_prompt_time() for entry in packages.values(): - if entry["total_executions"] > 0: + if not entry["installed"]: + entry["status"] = "uninstalled" + elif entry["total_executions"] > 0: # Used packages: classify by last_seen recency if entry["last_seen"] < two_months_ago: entry["status"] = "safe_to_remove"