chore: bump version to 3.1.0, update changelog, fix tag styling and filters
- Add append: to autotag skip-tagged filter alongside prepend: - Update tag chip styling to dark fill with white text - Add v3.1.0 changelog entry covering all changes since v3.0.26
This commit is contained in:
@@ -830,6 +830,20 @@ MIT License - see LICENSE file for details.
|
||||
|
||||
## Changelog
|
||||
|
||||
### v3.1.0 (WD14 Tagger, Tailwind v4 & Major Refactors)
|
||||
|
||||
- **🏷️ WD14 Tagger Support**: Added WD14 SwinV2 and WD14 ViT as new auto-tag model options — fast ONNX-based classifiers (~400MB) that output Danbooru tags with confidence scores, no prompt needed
|
||||
- **🎚️ Threshold Controls**: Adjustable general tag (default 0.35) and character tag (default 0.85) confidence thresholds for WD14 models via UI sliders
|
||||
- **🎨 Tailwind v4 Migration**: Complete frontend redesign with ComfyUI theme token system (`--pm-*` design tokens) that adapts to ComfyUI's color palette
|
||||
- **🏗️ API Refactor**: Split monolithic `api.py` into domain-specific route modules for better maintainability
|
||||
- **🗃️ Junction Table Tags**: Migrated tag storage from JSON column to normalized junction tables with proper foreign keys
|
||||
- **📄 Tags Page**: Dedicated tag management page with search, rename, merge, and delete operations
|
||||
- **🔍 Load More Button**: Progressive prompt loading instead of traditional pagination
|
||||
- **🔒 Security Hardening**: Resolved 15 GitHub code scanning alerts, prevented stack trace exposure in SSE errors
|
||||
- **🧪 Test Coverage**: Added comprehensive unit tests for validators, hashing, metadata, config, and prompt tracker; API integration tests; database tests with CI pipeline
|
||||
- **⚙️ CI/CD Improvements**: Added code quality scanning, security scanning, Dependabot, and pre-commit hooks with Black formatting
|
||||
- **🐛 Bug Fixes**: Fixed custom image scan directory config (#108), gallery crash on thumbnail linking, broken imports after API refactor, widget value sync issues, and prepend/append metadata tag filtering in auto-tagger
|
||||
|
||||
### v3.0.26 (Top Bar Button)
|
||||
|
||||
- **🔘 Top Bar PM Button**: Added a "PM" button to the ComfyUI top bar for quick access to the admin dashboard
|
||||
|
||||
@@ -216,7 +216,9 @@ class AutotagRoutesMixin:
|
||||
real_tags = [
|
||||
t
|
||||
for t in prompt_tags
|
||||
if t != "auto-scanned" and not t.startswith("prepend:")
|
||||
if t != "auto-scanned"
|
||||
and not t.startswith("prepend:")
|
||||
and not t.startswith("append:")
|
||||
]
|
||||
if real_tags:
|
||||
tagged_prompt_ids.add(prompt_id)
|
||||
|
||||
@@ -874,6 +874,7 @@ class AutoTagService:
|
||||
"photo_",
|
||||
"photo:",
|
||||
"prepend:",
|
||||
"append:",
|
||||
)
|
||||
|
||||
# Split by common delimiters
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "promptmanager"
|
||||
description = "A powerful ComfyUI custom node that extends the standard text encoder with persistent prompt storage, advanced search capabilities, and an automatic image gallery system using SQLite."
|
||||
version = "3.0.37"
|
||||
version = "3.1.0"
|
||||
license = {file = "LICENSE"}
|
||||
dependencies = ["# Core dependencies for PromptManager", "# Note: Most dependencies are already included with ComfyUI", "# Already included with Python standard library:", "# - sqlite3", "# - hashlib", "# - json", "# - datetime", "# - os", "# - typing", "# - threading", "# - uuid", "# Required for gallery functionality:", "watchdog>=2.1.0 # For file system monitoring", "Pillow>=8.0.0 # For image metadata extraction (usually included with ComfyUI)", "# Optional dependencies for enhanced search functionality:", "# fuzzywuzzy[speedup]>=0.18.0 # For fuzzy string matching (optional)", "# sqlalchemy>=1.4.0 # For advanced ORM features (optional)", "# Development dependencies (optional):", "# pytest>=6.0.0 # For running tests", "# black>=22.0.0 # For code formatting", "# flake8>=4.0.0 # For linting", "# mypy>=0.910 # For type checking"]
|
||||
|
||||
|
||||
+5
-5
@@ -539,9 +539,9 @@
|
||||
<div class="tags-accordion" data-prompt-id="${prompt.id}">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
${tags.slice(0, 10).map(tag => `
|
||||
<span class="inline-flex items-center space-x-1 bg-pm-accent-tint text-pm-accent px-3 py-1 rounded-full text-sm border border-pm-accent">
|
||||
<span class="inline-flex items-center space-x-1 bg-pm-input text-pm px-3 py-1 rounded-full text-sm border border-pm">
|
||||
<span>${this.escapeHtml(tag)}</span>
|
||||
<button class="remove-tag-btn text-pm-accent hover:text-pm-accent ml-1" data-prompt-id="${prompt.id}" data-tag="${this.escapeHtml(tag)}">×</button>
|
||||
<button class="remove-tag-btn text-pm-secondary hover:text-pm ml-1" data-prompt-id="${prompt.id}" data-tag="${this.escapeHtml(tag)}">×</button>
|
||||
</span>
|
||||
`).join("")}
|
||||
<button class="inline-flex items-center space-x-1 bg-pm-input hover:bg-pm-hover text-pm-secondary px-3 py-1 rounded-full text-sm transition-colors" onclick="window.admin.addTag(${prompt.id})">
|
||||
@@ -553,9 +553,9 @@
|
||||
<div class="tags-hidden hidden mt-2">
|
||||
<div class="flex flex-wrap items-center gap-2 max-h-[180px] overflow-y-auto p-2 bg-pm-surface rounded-pm-sm">
|
||||
${tags.slice(10).map(tag => `
|
||||
<span class="inline-flex items-center space-x-1 bg-pm-accent-tint text-pm-accent px-3 py-1 rounded-full text-sm border border-pm-accent">
|
||||
<span class="inline-flex items-center space-x-1 bg-pm-input text-pm px-3 py-1 rounded-full text-sm border border-pm">
|
||||
<span>${this.escapeHtml(tag)}</span>
|
||||
<button class="remove-tag-btn text-pm-accent hover:text-pm-accent ml-1" data-prompt-id="${prompt.id}" data-tag="${this.escapeHtml(tag)}">×</button>
|
||||
<button class="remove-tag-btn text-pm-secondary hover:text-pm ml-1" data-prompt-id="${prompt.id}" data-tag="${this.escapeHtml(tag)}">×</button>
|
||||
</span>
|
||||
`).join("")}
|
||||
</div>
|
||||
@@ -3945,7 +3945,7 @@ Seed: ${this.currentMetadata.seed || 'Unknown'}`;
|
||||
// Check if tags array has "real" tags (excluding auto-scanned and prepend:* metadata)
|
||||
getRealTags(tags) {
|
||||
if (!tags || !Array.isArray(tags)) return [];
|
||||
return tags.filter(tag => tag !== 'auto-scanned' && !tag.startsWith('prepend:'));
|
||||
return tags.filter(tag => tag !== 'auto-scanned' && !tag.startsWith('prepend:') && !tag.startsWith('append:'));
|
||||
}
|
||||
|
||||
// Show the re-tag confirmation modal
|
||||
|
||||
@@ -176,23 +176,23 @@
|
||||
.tag-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 2px 8px;
|
||||
padding: 4px 12px;
|
||||
background: var(--pm-bg-input);
|
||||
border: 1px solid var(--pm-border);
|
||||
border-radius: var(--pm-radius-sm);
|
||||
border-radius: 9999px;
|
||||
font-size: 12px;
|
||||
color: var(--pm-text-secondary);
|
||||
color: var(--pm-text);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.tag-chip:hover { background: var(--pm-bg-hover); }
|
||||
.tag-chip:hover { opacity: 0.85; }
|
||||
|
||||
.tag-chip .tag-remove {
|
||||
margin-left: 6px;
|
||||
padding: 2px;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
color: var(--pm-text-muted);
|
||||
color: var(--pm-text-secondary);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user