* feat(system): run thumbnail generation as an Activity job
GET /prompt_manager/images/thumbnails/plan counts what a run would do
(targets, fresh, remaining past the cap, source labels) and writes
nothing. POST /prompt_manager/jobs/thumbnails {mode, size, quality}
starts the "thumbnails" job: admission guarded, cancellable at a file
boundary, outcome groups generated / skipped / errors. size is the
longest edge (128-2048), quality the encoder, and rebuild writes fresh
previews again through the same atomic rename, so a failed file keeps
its old preview and originals are only read.
The legacy gallery stream now starts or attaches to the same job and
streams its unchanged frames. A client that goes away no longer stops
the work; the gallery's Cancel asks the server to cancel the job.
* feat(activity): per-kind job descriptors
One descriptor table (activity-kinds.mjs) decides each job kind's pill
verb, toasts, line, tiles, outcomes, openable rows and labels; the
store re-exports it. The scan and image tagging views are unchanged.
A thumbnail job counts Generated, Skipped and Errors, reads
"Generating thumbnails" in the pill and "Thumbnails finished · N
generated · M errors" when it ends.
Any other kind (the health check, a held legacy-page operation) gets
the generic descriptor with no tiles and no Results, instead of the
scan's zero tiles. A running job without a known total shows an
indeterminate progress bar and no percentage, and only a job the
server can cancel shows Cancel.
* feat(system): review and start thumbnail jobs
Sources' Thumbnail generation -> Review options and Overview's Review
thumbnails open the concept's Thumbnail maintenance dialog: scope, quality
(preselected from Image loading quality) and preview size limit, a plan
line from the read-only thumbnail plan (D99) and Start, which starts the
thumbnails Activity job and opens it. A size outside 128-2048 requests
nothing; a refused start shows the busy link toast.
* fix(system): thumbnail job review fixes (#249 S5)
- The legacy stream's first frame is job {id, started}, sent after the
subscription so no runner frame is missed; it reads the registry after
prepare, so a job started in that gap is attached to, not refused.
- Every exit sets a truthful final status line; nothing to do never
reads "Processing file 0 of 0".
- Cancel is checked per file during the planning walk; a job cancelled
there publishes no start frame.
- The ffmpeg fallback keeps the chosen quality (-q:v) and the aspect
ratio; the placeholder uses the chosen JPEG settings.
- A locked preview on Windows reads "Preview in use by another program;
the old one was kept", not the raw WinError.
- Thumbnail work no longer defers the monitor's Needs review recording:
it writes previews only, never records.
- The disconnect test now proves the job outlives its stream (one worker,
9 files, three batches); the attach test waits on an event.
* fix(gallery): cancel the stream's own thumbnail job by id
The settings panel and the startup dialog cancel the job named by the
stream's job frame, and only one their stream started. A Cancel before
the frame waits for it, a double Cancel posts once, and a job another
tab or System started keeps running. The startup dialog now settles on
Cancel instead of staying on "Cancelling...".
* fix(activity): indeterminate pill bar and the nothing-to-do line
The pill's mini bar sweeps while a job's total is unknown instead of
showing an empty fill. A finished thumbnail job with nothing to do shows
the server's final line. Coverage floors raised for gallery.js and
activity.mjs.
Viewer.js maintenance
ComfyUI serves the committed files in web/lib/viewerjs/. Node and npm are only
needed by maintainers and CI. Keep upstream files pristine; application behavior
belongs in web/js/, and theme overrides belong in comfyui-theme.css.
Install and verify
Use Node 24 or newer. From the repository root:
npm ci --prefix tools/vendor --ignore-scripts
npm run --prefix tools/vendor check
npm run --prefix tools/vendor test
node --test tests/js/*.test.js
npx --prefix tools/vendor playwright install chromium
npm run --prefix tools/vendor test:browser
On Linux, use playwright install --with-deps chromium when browser system
libraries are missing. The browser tests use synthetic images and mock the
ComfyUI API boundary; they run production viewer methods and the committed
Viewer.js JS/CSS, without a running ComfyUI instance.
check is read-only and fails if any JS, CSS, license, or provenance file differs
from the installed package. The manifest, lockfile, installed package, and asset
version banners must agree. The lockfile records npm's archive integrity;
provenance.json records the upstream source, package integrity, and SHA-256 of
each copied file. A normal npm ci --ignore-scripts verifies archive integrity.
Full-page workflows, frontend coverage gates, and required merge checks are
documented in TESTING.md. The viewerjs CI check runs both
the fixture tests above and the real-page workflows on every PR.
Update
npm run --prefix tools/vendor update
# Or select a specific stable version:
npm run --prefix tools/vendor update -- --version 1.15.2
The command installs an exact version with lifecycle scripts disabled and copies
dist/viewer.min.js, dist/viewer.min.css, and LICENSE. It writes deterministic
provenance with no timestamps. Repeat the checks above and commit the manifest,
lockfile, and all vendor files together. To regenerate files from the current
pin without changing versions, run npm run --prefix tools/vendor sync.
Automated update PRs
Update vendored Viewer.js checks npm's stable release daily at 07:30 UTC and
supports Actions → Update vendored Viewer.js → Run workflow, with an optional
version. It tests the generated update before opening deps/viewerjs-X.Y.Z.
Existing open or closed PRs for that release are left alone. A failed test does
not publish a branch or PR. Changes require review; the workflow never merges
or approves PRs.
The organization and repository must enable Actions → General → Workflow
permissions → Allow GitHub Actions to create and approve pull requests.
Keep default workflow permissions read-only. Only the update job requests
contents: write, pull-requests: write, and actions: write.
The workflow uses GITHUB_TOKEN; no personal token is needed. Because bot-token
pushes do not normally trigger other workflows, it explicitly dispatches the
read-only Viewer.js vendor and compatibility workflow on the update branch.
Both workflow files must be merged into the default branch before scheduling or
manual dispatch becomes available.
Compatibility checklist
Check gallery grid/list views, navigation across 100-image windows, metadata, slideshow/fullscreen, keyboard navigation, Escape and focus cleanup. Check the admin gallery/filmstrip and tag viewer. On touch devices, test long swipes, short drags, and pinch/rotate gestures. Confirm the ComfyUI theme remains usable.
The gallery keeps its bounded viewer and custom slideshow. Upstream navbar windowing is not a replacement for bounding the supplied image list: native slideshow playback can still preload every supplied original. Review new preloading defaults, gesture behavior, CSS changes, and any adapter use of Viewer.js internal methods before adopting another release.
Shared ComfyAssets test tooling
The exact toolkit commit archive in package.json / package-lock.json supplies
host orchestration and coverage helpers. comfyui-host.mjs is PromptManager's
configuration adapter; keep reusable lifecycle changes in the toolkit source.
The existing npm scripts remain the public maintainer entry points. See
TESTING.md for the managed real-host matrix and update policy.
Shared ComfyAssets browser controls
Prompt Manager (Classic) consumes the same pinned toolkit's browser controls.
The node identifier remains PromptManager; existing workflows, sockets, and
immediate result selection are preserved. PromptManager Text is unchanged.
Committed assets in web/js/shared/toolkit/ work without npm or KikoTools installed.
Maintain common controls in ComfyAssets Toolkit,
then update the exact archive pin and lockfile here. Regenerate using
npm run --prefix tools/vendor sync:toolkit; npm run --prefix tools/vendor check
verifies both Viewer.js and the toolkit without rewriting files. The toolkit
distribution includes its license, source history, archive integrity and per-file
hashes. Do not edit its copied files directly. Classic's controller and layout
remain in web/js/classic-node.js and web/js/classic-node.css.
Run the frontend coverage/browser suites and managed Classic/Nodes 2.0 matrix after updates. Shared modules participate in the frontend coverage gate. Pixaroma's reusable framework inspired this architecture; no Pixaroma code, styles or assets are included.