Add a success color token and replace scattered textContent assignments
with setElementStatusText / setStatusMode so local DB, base models,
HF index, and cache-clearing statuses consistently use is-pending,
is-valid, and is-invalid classes.
Support both Comfy-Org and Kijai author indexes as known HuggingFace fallbacks, aggregate their status in the backend, refresh the cached author index, and update the frontend UI and tests.
Backend:
- Move SHA256 normalization logic from path_utils._normalize_header_sha256
into core/type_utils.normalize_sha256, adding support for 0x-prefixed
hashes and unifying the normalization path used by
extract_safetensors_header_sha256.
- Add tests for the 0x prefix normalization cases.
Frontend:
- Introduce copyTextWithFeedback in web/resolver/utils/html_utils.js
as a shared clipboard helper with configurable feedback text, CSS class,
and duration, replacing repeated inline clipboard copy logic in
globals.js, model_info_methods.js, and the notification utility.
- Centralize showNotification on ResolverManagerDialog and remove the
duplicate implementation from missingBrowserMethods.
- Replace local const localStorage = safeStorage aliases in
model_info_methods.js, missing_browser_methods.js, and
options_methods.js with direct safeStorage usage.
- Add run_in_background_thread() in __init__.py to unify success/cancel/error
handling for hash calculation and local metadata build progress
- Extract match_model_by_title_generic() in core/matcher.py and use it from
both CivitAI and CivArchive providers to remove duplicated version/file
selection logic
- Enable safetensors header SHA256 extraction by default and report hash source
through progress updates
- Update options_methods.js to match backend progress behavior
- Add tests/test_title_matching_hashing.py covering title matching and hashing
- Minor metadata updates
- Add core/network_utils.py with URL validation, public-IP enforcement,
redirect validation, and safe request_public_url/validate_public_http_url helpers
- Replace direct requests calls in downloader/type_utils/sources with
request_public_url so redirects are validated before follow-up
- Replace netloc string checks with host_matches_domain for CivitAI,
CivArchive, and HuggingFace host matching
- Add HuggingFace Xet download backend with progress reporting and
cancellation support via hf_xet/huggingface_hub
- Harden aria2 installer: reject symlinks/special files in archives,
restrict custom aria2c paths to the managed install, and update UI copy
- Normalize paths with realpath and enforce configured model roots in
local hash/metadata routes, plus remove caller-selected metadata_path
injection in sidecar writing
- Sanitize download/network errors to strip signed query strings before
logging or showing them to the user
This change introduces a complete Local Metadata Builder feature in the resolver
options panel. It allows users to scan local model files, create or update
.metadata.json sidecars, fill missing SHA256 hashes from safetensors headers or
file hashing, and review run history with cancel/error handling.
Changes include:
- backend API: /model_resolver/metadata-build/{capabilities,start,progress/{id},cancel}
- backend worker: core/metadata_builder.py with parallel metadata generation
- frontend section: Local Metadata Builder tab in Options
- frontend polling UI: progress, worker breakdown, history table, status/notifications
- Introduce get_filename_from_path in path_utils and replace repeated
os.path.basename calls across core/downloader.py, core/resolver.py,
core/sources/civarchive.py, core/sources/civitai.py, and
core/sources/huggingface.py
- Move duplicated inline HTTP response size helpers (_response_file_size,
_parse_size_header, _parse_content_range_size) into core/type_utils.py
and update civarchive.py and huggingface.py to import them
- Remove inline normalize_sha256_value from __init__.py and reuse the
existing normalize_sha256 helper
- Refactor options_methods.js localStorage read/write logic into a
SETTINGS_MAP-driven loop to reduce repetition
- Add /aria2/start and /aria2/stop API endpoints for explicit daemon lifecycle control
- Track aria2 daemon state (managed/running/version/active_transfers) in get_aria2_status
- Implement idle auto-stop timer (5 minutes) with aria2_auto_stop_daemon setting
- Add start_aria2_daemon() and stop_aria2_daemon() helpers in core/downloader.py
- Migrate legacy release-* install directories to normalized versioned paths
- Normalize aria2 version strings (strip release-/v prefixes) in installer metadata
- Update aria2 archive extraction to extract-to-temp then copy into canonical dir
- Add frontend daemon controls: status display, stop button, auto-stop toggle
- New core/aria2_installer.py module downloads the latest aria2c release
from GitHub for Windows, macOS, and Linux with safe path extraction.
- New POST /model_resolver/aria2/install endpoint triggers installation
and saves the resolved aria2c_path plus download_backend=aria2.
- Options UI adds an Install aria2 button, hides aria2-specific fields
when another backend is selected, and updates status on completion.
- Includes .gitignore entry for tools/aria2/ so installed binaries are
not committed.
Integrates aria2c as an alternative download backend alongside the built-in
Python downloader. Adds settings for selecting the backend and configuring
the aria2c executable path, plus a status check button in the options panel.
Backend changes:
- core/downloader.py: aria2 daemon lifecycle, JSON-RPC client, pause/resume
state machine, and transfer tracking
- core/settings.py: download_backend normalization and aria2c_path setting
- __init__.py: new API routes for pause, resume, and aria2 status checks
Frontend changes:
- options_methods.js: backend selector, aria2c path input, check button,
and local storage persistence
- resolve_download_methods.js: pause/resume handlers, pending status
transitions, and progress rendering for aria2 downloads
- queue_methods.js: queue panel pause/resume buttons, backend badge, and
debounced panel updates
- search_panel.js: actionsHtml support for composite action buttons
Replace scattered api.fetchApi(...) + response.ok + response.json() boilerplate
across all web/modules with a unified this.fetchJson() helper defined on the
base dialog class.
Changes:
- dialog.fetchJson(url, options, context) handles headers, status checks, and
JSON parsing in one place
- Extracts server-side error messages (errData.error) for better UX
- Optional silent flag suppresses notifications for background/refresh requests
- All callers simplified: async return, shorter bodies, consistent error handling
- BOM removed from workflow_update_methods.js and tabs_loaded_methods.js
- Moved formatting helpers (formatBytes, formatDuration, getDownloadEtaText,
formatDownloadProgressMeta) and getLocalMatchDisplayInfo from
resolve_download_methods.js and missing_browser_methods.js into
render_format_methods.js for shared reuse.
- Relocated settings-related methods (getStoredTokens,
applyFrontendLoggingPreference, loadSettingsFromServer) and their
log_system imports from download_target_methods.js into
options_methods.js, where they are actually consumed by the options UI.
- Simplified missing_browser_methods.js to use
getLocalMatchDisplayInfo instead of inline local-match code.