feat: native disable/enable fallback and package whitelist; bump to 1.8.0
Publish to Comfy registry / Publish Custom Node to registry (push) Waiting to run
Publish to Comfy registry / Publish Custom Node to registry (push) Waiting to run
Disable/enable no longer require ComfyUI Manager: - New pack_fs.py moves packs in/out of custom_nodes/.disabled/ (no import, delete, or re-clone). Fallback for hand-cloned packs, loose single-file nodes, or when Manager is absent. enable strips the @version suffix so packs restore as clean, importable dir names. - Routes: native-disable, native-enable, disabled-packs. - Frontend routes each disable per-pack (Manager queue vs native move), and shows an Enable button on recoverable packs in the Uninstalled tier. The restart banner degrades to a manual-restart notice when no Manager exists. Whitelist (packages-only): a star toggle protects a pack — pulled into its own pinned group, no Disable button, skipped by the 7-day trial auto-disable. - New whitelist_packages table; whitelisted flag on package stats. - Routes: whitelist, whitelist/add, whitelist/remove. Tests: test_pack_fs.py, test_whitelist.py (60 passing). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+51
@@ -57,6 +57,11 @@ CREATE TABLE IF NOT EXISTS trial_packages (
|
||||
budget INTEGER NOT NULL DEFAULT 7
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS whitelist_packages (
|
||||
package TEXT PRIMARY KEY,
|
||||
added_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_node_usage_package ON node_usage(package);
|
||||
CREATE INDEX IF NOT EXISTS idx_prompt_log_timestamp ON prompt_log(timestamp);
|
||||
CREATE INDEX IF NOT EXISTS idx_model_usage_type ON model_usage(model_type);
|
||||
@@ -286,6 +291,13 @@ class UsageTracker:
|
||||
tracking_start, one_month_ago, two_months_ago, "unused_new"
|
||||
)
|
||||
|
||||
# Flag whitelisted packages so the UI can pull them into their own group
|
||||
# and suppress disable actions. Whitelist entries are kept verbatim; match
|
||||
# case-insensitively since directory names vary by how users clone/symlink.
|
||||
whitelist = {w.lower() for w in self.get_whitelist()}
|
||||
for entry in packages.values():
|
||||
entry["whitelisted"] = entry["package"].lower() in whitelist
|
||||
|
||||
result = [p for p in packages.values() if p["package"].lower() not in EXCLUDED_PACKAGES]
|
||||
result.sort(key=lambda p: p["total_executions"])
|
||||
return result
|
||||
@@ -480,6 +492,44 @@ class UsageTracker:
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
def add_to_whitelist(self, package):
|
||||
"""Protect a package: keep it out of disable actions and its own group."""
|
||||
now = datetime.now(timezone.utc).isoformat()
|
||||
with self._lock:
|
||||
self._ensure_db()
|
||||
conn = self._connect()
|
||||
try:
|
||||
conn.execute(
|
||||
"""INSERT INTO whitelist_packages (package, added_at) VALUES (?, ?)
|
||||
ON CONFLICT(package) DO NOTHING""",
|
||||
(package, now),
|
||||
)
|
||||
conn.commit()
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
def remove_from_whitelist(self, package):
|
||||
"""Remove a package from the whitelist."""
|
||||
with self._lock:
|
||||
self._ensure_db()
|
||||
conn = self._connect()
|
||||
try:
|
||||
conn.execute("DELETE FROM whitelist_packages WHERE package = ?", (package,))
|
||||
conn.commit()
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
def get_whitelist(self):
|
||||
"""Return the set of whitelisted package names."""
|
||||
with self._lock:
|
||||
self._ensure_db()
|
||||
conn = self._connect()
|
||||
try:
|
||||
rows = conn.execute("SELECT package FROM whitelist_packages").fetchall()
|
||||
return {r[0] for r in rows}
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
def reset(self):
|
||||
"""Clear all tracked data."""
|
||||
with self._lock:
|
||||
@@ -490,6 +540,7 @@ class UsageTracker:
|
||||
conn.execute("DELETE FROM prompt_log")
|
||||
conn.execute("DELETE FROM model_usage")
|
||||
conn.execute("DELETE FROM trial_packages")
|
||||
conn.execute("DELETE FROM whitelist_packages")
|
||||
conn.commit()
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
Reference in New Issue
Block a user