The duplicate scan walked the output tree and hashed every file on the
aiohttp event loop, and the duplicate delete removed files inline; the
output scan ran its per-file database work one executor hop at a time.
- _find_duplicate_images_sync / _describe_media_file do the walk and
hashing; find_duplicate_images() runs them via _run_in_executor.
- _delete_duplicate_images_sync / _delete_one_duplicate do the removal
(absolute or output-relative paths) off the loop.
- The output scan is split into _collect_output_media_sync,
_extract_batch_metadata_sync and _ingest_scan_batch_sync (one
executor call per batch for all DB work) with a small SSE generator.
- Media collection is shared and de-duplicates by normcase'd path.
Settings, diagnostics, duplicate/output scans and the logging endpoints
returned absolute filesystem paths, and several error envelopes echoed
str(e) which for OSError carries the full path.
- _public_path() renders a path relative to the ComfyUI base directory
(folder_paths.base_path, else the output dir's parent) or to the
parent of an opted-in extra gallery root, falling back to the
basename; _public_error() reduces OSError to strerror + basename.
- GET /settings returns gallery roots and monitored directories in that
form; POST /settings resolves relative roots against the same anchors
(GalleryConfig.resolve_gallery_root) so the GET output round-trips.
- Diagnostics output_dirs, monitored_directories and the missing-DB
message no longer carry absolute paths; the image monitor is reached
through the package-or-top-level import fallback instead of a
three-dot relative import that failed outside the package.
- Duplicate scan 'path' is now relative to the output root and the
delete endpoint accepts relative paths.
- /logs/files 'path' and /logs/stats 'log_directory' use the public
form; unexpected errors answer with a generic message.
A gallery root could be set to '/' (or 'C:\') through POST
/prompt_manager/settings because the deny list only matched a few
system prefixes. The root was persisted to config.json and fed into the
image-serving containment check, which then allowed any file on disk to
be read through /prompt_manager/images/serve/.
- GalleryConfig.validate_gallery_root() accepts a directory only when its
realpath lies inside a ComfyUI directory (folder_paths output/input/
temp/user) or a directory listed in PROMPT_MANAGER_EXTRA_GALLERY_ROOTS;
filesystem roots, the home directory, files and missing paths are
rejected.
- save_settings returns 400 and persists nothing when any root fails.
- _get_all_output_dirs() filters configured roots through the validator
and never falls back to a rejected root.
- PROMPT_MANAGER_CONFIG_PATH relocates config.json; load/save default
to it.