Register artttaku/ComfyUI-BatchVideoLoader (#3179),
rattskr/ComfyUI_CivitaiAdvanceLoader (#3218),
Winlensky/comfyui_compvis_ldm (#3229) and two entropicnoise MiniMax-H3
packs (#3185, #3202) at the end of the git-clone body, above the
copy/unzip tail zone. Relocate the already-merged ethanfel H3 Prompt IDE
(#3186) from array head to the ethanfel author group. Sync all six into
node_db/new. All six passed verify-security (SAFE), locale (English UI),
and quality gates.
The array tail is the copy/unzip special zone; over many sessions new
git-clone entries were wrongly appended after it, burying the zone under
~600 entries. Re-place each into the git-clone body (author-adjacent for
existing authors, grouped-at-body-end for new authors) so the array ends
with the copy/unzip zone again. Pure reorder: entry count, reference set,
and per-entry formatting all preserved.
Base carried the scanner-abbreviated title 'h3_sage_amd' and a one-line
description; replace with the author's canonical title and description
from PR #3144 in both the root list and node_db/new.
Post-registration full re-verify (§14.7) found an unauthenticated CSRF-reachable
arbitrary-directory delete: DatasetProject.make(reset=True) runs shutil.rmtree on an
uncontained os.path.join(output_dir, dataset_name) (nodes/common.py:169-173) — an
absolute or ..-containing name escapes the output dir. Removed from default + node_db/new,
added to node_db/dev with [SECURITY ISSUE] suffix (reversible install-block, §4.7-H mechanic).
Restore to default on author fix (realpath+commonpath containment) + re-verify pass.
PR conflicted on the list tail; manually registered. Deep-verify SAFE (unauth routes are inference/model-load only, no side-effect sink), Non-English PASS.
Relocate ANe5s/ComfyUI-MiniMax-H3-Hybrid (#3154) from array head to tail.
Manually register Flow-Wrangler (#3142), minimax-h3-latent (#3151),
buqi-minimax-h3-multigpu (#3158), H3-Continuum (#3159) — their PRs
conflicted on the list tail after the batch merges. buqi-minimax-h3-multigpu
description trimmed to English-only (author's zh restatement dropped, §4.7-D desc policy).
Sync all 7 into node_db/new (newest-first).
The dialog renders HTML, so run the server body and the pack title
(registry-derived) through the existing sanitizeHTML() at both sites. The
title is wrapped in String() so a missing title can't throw inside the error
handler; rendered text is unchanged for ordinary values.
The batch install/uninstall paths replaced the server's 404 body with a
false "default channel" lead. Drop the 404 branch so a 404 falls through to
the existing server-text path; uninstall never returns 404 anyway. Fixes
#3128 (section 1), reported by plz12345.
write_config() rebuilt config.ini's [default] section entirely from the
startup snapshot into a fresh parser opened 'w'. Any Manager settings
change therefore silently reverted values hand-edited while ComfyUI was
running (the same config['default'] flags those messages tell users to
edit), deleted the two read-but-never-written keys (http_channel_enabled,
default_cache_as_channel_url), and erased every non-[default] section.
get_config() now tracks which keys callers actually change, and
write_config() re-reads config.ini and overlays only those keys plus the
live preview_method. After a successful write the just-persisted keys are
cleared from the tracker, so a key changed once through the UI does not
stay dirty for the life of the process and re-clobber a later hand-edit of
that same key on the next unrelated write. Hand-edited values, unknown
keys, and foreign sections survive; CRLF sanitization still applies to
every value written; an unparsable config.ini falls back to a full rewrite
instead of failing every settings endpoint.
configparser.read() suppresses OSError, so a config.ini that exists but
cannot be read comes back as an empty parser rather than an exception,
which would silently route the merge into the bootstrap branch and rewrite
the file from defaults. write_config() now detects that case (the file
exists but read() loaded nothing) and refuses the write with a raised
error, leaving the file untouched, rather than destroying its contents
while reporting success.
tests/test_write_config_persistence.py pins the three loss classes
(hand-edit revert, key deletion, section erasure), the settings
round-trip, the persisted-key re-clobber guard, and the silent-read-failure
refusal.
The install-denial diagnostics named the wrong gate, sending users to
settings that could not resolve their denial:
- SECURITY_MESSAGE_FLAG_GIT_URL / _FLAG_PIP omitted the loopback half of
the flag-AND-loopback predicate, telling users to enable a flag that
was often already enabled. They now state both conditions, print the
live --listen value at every emission site, and explain that both
values are read once at startup (stop the server, edit, then start).
- SECURITY_MESSAGE_MIDDLE_OR_BELOW instructed setting security_level to
'middle', a value that does not exist; it now names only real values
(any level other than 'strong': normal, normal-, weak).
- The blocked-risk arm reused SECURITY_MESSAGE_GENERAL, blaming
security_level although no value of it can help there; it now emits a
dedicated SECURITY_MESSAGE_BLOCKED_RISK stating this is not a
configuration problem.
- SECURITY_MESSAGE_NORMAL_MINUS_MODEL now names its loopback-listener
condition and the same restart guidance.
- The js/common.js dedicated-403 messages mirror the loopback clause.