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.
+
+
+
+
+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:
+
+
+
+
Used
+
Actively used within the last month
+
+
+
Recently Unused
+
Not used yet, but tracking started less than a month ago — too early to judge
+
+
+
Consider Removing
+
Unused for 1–2 months — worth reviewing
+
+
+
Safe to Remove
+
Unused for 2+ months — confident removal candidate
+
+
+
Uninstalled
+
Previously 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 @@
+