From 43a4fdee169992521345150c782e141af811e5c7 Mon Sep 17 00:00:00 2001 From: Ethanfel Date: Sun, 22 Feb 2026 14:01:39 +0100 Subject: [PATCH] Rewrite README with classification docs, logo, and status icons Updated documentation to reflect the 4-tier classification system and uninstalled detection. Added SVG logo and color-coded status indicator dots. Added architecture diagram and collapsible API response example. Co-Authored-By: Claude Opus 4.6 --- README.md | 136 ++++++++++++++++++++++++++---------- docs/logo.svg | 32 +++++++++ docs/status_consider.svg | 4 ++ docs/status_safe.svg | 4 ++ docs/status_uninstalled.svg | 4 ++ docs/status_unused_new.svg | 4 ++ docs/status_used.svg | 4 ++ 7 files changed, 153 insertions(+), 35 deletions(-) create mode 100644 docs/logo.svg create mode 100644 docs/status_consider.svg create mode 100644 docs/status_safe.svg create mode 100644 docs/status_uninstalled.svg create mode 100644 docs/status_unused_new.svg create mode 100644 docs/status_used.svg diff --git a/README.md b/README.md index c182dde..eb40de2 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,46 @@ # ComfyUI Node Usage Stats -A ComfyUI custom node package that silently tracks which nodes and packages you actually use. Helps identify never-used packages that are safe to remove. +

+ Node Stats logo +

+ +A ComfyUI custom node package that silently tracks which nodes and packages you actually use. Helps identify unused packages that are safe to remove — keeping your ComfyUI install lean. ## Features -- Tracks every node used in every workflow execution -- Maps each node to its source package -- SQLite storage for efficient querying -- Per-package aggregated stats (total nodes, used/unused, execution counts) -- Frontend dialog with never-used packages highlighted for removal -- Expandable rows to see individual node-level stats within each package +- **Silent tracking** — hooks into every prompt submission, zero config needed +- **Per-package classification** — packages are sorted into tiers based on usage recency +- **Smart aging** — packages gradually move from "recently unused" to "safe to remove" over time +- **Uninstall detection** — removed packages are flagged separately, historical data preserved +- **Expandable detail** — click any package to see individual node-level stats +- **Non-blocking** — DB writes happen in a background thread, no impact on workflow execution + +## Package Classification + +Packages are classified into tiers based on when they were last used: + + + + + + + + + + + + + + + + + + + + + + +
UsedActively used within the last month
Recently UnusedNot used yet, but tracking started less than a month ago — too early to judge
Consider RemovingUnused for 1–2 months — worth reviewing
Safe to RemoveUnused for 2+ months — confident removal candidate
UninstalledPreviously tracked but no longer installed — shown for reference
## Installation @@ -24,28 +55,26 @@ Restart ComfyUI. Tracking starts immediately and silently. ### UI -Click the **"Node Stats"** button in the ComfyUI menu. A dialog shows: +Click the **Node Stats** button (bar chart icon) in the ComfyUI top menu bar. A dialog shows: -- Summary: how many packages are never-used vs used -- **Never Used** section (highlighted) — safe to remove -- **Used** section sorted by least-to-most executions -- Click any row to expand and see individual node stats +- **Summary bar** with counts for each classification tier +- **Sections** for each tier, sorted from most actionable to least +- **Expandable rows** — click any package to see per-node execution counts and timestamps ### API | Endpoint | Method | Description | |----------|--------|-------------| -| `/nodes-stats/packages` | GET | Per-package aggregated stats | +| `/nodes-stats/packages` | GET | Per-package aggregated stats with classification | | `/nodes-stats/usage` | GET | Raw per-node usage data | | `/nodes-stats/reset` | POST | Clear all tracked data | -Example: - ```bash curl http://localhost:8188/nodes-stats/packages | python3 -m json.tool ``` -### Package stats response format +
+Example response ```json [ @@ -54,8 +83,9 @@ curl http://localhost:8188/nodes-stats/packages | python3 -m json.tool "total_executions": 42, "used_nodes": 5, "total_nodes": 30, - "never_used": false, "last_seen": "2026-02-22T12:00:00+00:00", + "installed": true, + "status": "used", "nodes": [ { "class_type": "SAMDetectorCombined", @@ -65,34 +95,70 @@ curl http://localhost:8188/nodes-stats/packages | python3 -m json.tool "last_seen": "2026-02-22T12:00:00+00:00" } ] + }, + { + "package": "ComfyUI-Unused-Nodes", + "total_executions": 0, + "used_nodes": 0, + "total_nodes": 12, + "last_seen": null, + "installed": true, + "status": "safe_to_remove", + "nodes": [] } ] ``` -## File Structure - -``` -__init__.py # Entry point: prompt handler, API routes -mapper.py # class_type -> package name mapping -tracker.py # SQLite persistence and stats aggregation -js/ - nodes_stats.js # Frontend: menu button + stats dialog -pyproject.toml # Package metadata -``` +
## How It Works +``` +Queue Prompt ──> Prompt Handler ──> Extract class_types ──> Background Thread + │ + ┌─────────────────────────┘ + ▼ + SQLite DB + usage_stats.db + ┌──────────┐ + │node_usage │ per-node counts & timestamps + │prompt_log │ full node list per prompt + └──────────┘ + │ + GET /nodes-stats/packages ◄──┘ + │ + ▼ + Mapper merges DB data + with NODE_CLASS_MAPPINGS + │ + ▼ + Classify by recency ──> JSON response ──> UI Dialog +``` + 1. Registers a prompt handler via `PromptServer.instance.add_on_prompt_handler()` -2. On every prompt submission, extracts `class_type` from each node -3. Maps each class_type to its source package using `RELATIVE_PYTHON_MODULE` -4. Stores per-node counts and timestamps in SQLite (`usage_stats.db`) -5. Also logs the full set of nodes per prompt for future trend analysis +2. On every prompt submission, extracts `class_type` from each node in the workflow +3. Offloads recording to a background thread (non-blocking) +4. Maps each class_type to its source package using `RELATIVE_PYTHON_MODULE` +5. Upserts per-node counts and timestamps into SQLite +6. On stats request, merges DB data with current node registry and classifies by recency ## Data Storage -All data is stored in `usage_stats.db` in the package directory. Two tables: +All data is stored in `usage_stats.db` in the package directory. -- **node_usage**: per-node counts, first/last seen timestamps -- **prompt_log**: JSON array of nodes used per prompt, with timestamp +| Table | Contents | +|-------|----------| +| `node_usage` | Per-node: class_type, package, execution count, first/last seen | +| `prompt_log` | Per-prompt: timestamp, JSON array of all class_types used | -Use `POST /nodes-stats/reset` to clear all data. +Use `POST /nodes-stats/reset` to clear all data and start fresh. + +## File Structure + +``` +__init__.py Entry point: prompt handler, API routes +mapper.py class_type → package name mapping +tracker.py SQLite persistence and stats aggregation +js/nodes_stats.js Frontend: menu button + stats dialog +pyproject.toml Package metadata +``` diff --git a/docs/logo.svg b/docs/logo.svg new file mode 100644 index 0000000..8b11637 --- /dev/null +++ b/docs/logo.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/status_consider.svg b/docs/status_consider.svg new file mode 100644 index 0000000..8f650e1 --- /dev/null +++ b/docs/status_consider.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/status_safe.svg b/docs/status_safe.svg new file mode 100644 index 0000000..1875d8f --- /dev/null +++ b/docs/status_safe.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/status_uninstalled.svg b/docs/status_uninstalled.svg new file mode 100644 index 0000000..e72ba1d --- /dev/null +++ b/docs/status_uninstalled.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/status_unused_new.svg b/docs/status_unused_new.svg new file mode 100644 index 0000000..c570fca --- /dev/null +++ b/docs/status_unused_new.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/status_used.svg b/docs/status_used.svg new file mode 100644 index 0000000..bbe07d0 --- /dev/null +++ b/docs/status_used.svg @@ -0,0 +1,4 @@ + + + +