Document all five nodes (Image Pool, Pool Profile, Folder Image Loader,
Image Gate, Text Gate) with IO tables and behavior, plus shared concepts
(blocking gates, mask polarity, storage/profiles layout) and dev layout.
Refresh the stale pyproject description.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Connecting a Pool Profile no longer overwrites the pool's pool_id. The pool is
switched only when the user actively selects a profile in the dropdown; picking
an empty profile while a pool with images is connected offers to copy those
images into it (new seed_profile op + /grid_pool/profiles/seed route), so the
current pool is never silently lost.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Named, portable profiles for the Image Pool: a Pool Profile companion node
(create/select/rename/delete/duplicate/export-import) outputs a POOL_PROFILE
id into the pool's new optional input; profile or pool_id wins. Registry
(name->id) in profiles.json; live edit-time grid switch via cross-node
propagation. TDD plan with a pure stdlib profiles layer incl. zip round-trip.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Blocking text gate: pauses, shows incoming text in an editable box, Pass
emits the edited text. Optional any-type signal input + signal passthrough
output for ordering. Reuses gate_bus via an additive string payload channel
with a should_cancel hook so the Pass-only gate still honors global Cancel
(processing_interrupted). TDD plan; comfy imports stay lazy for testability.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
After a route choice the node now keeps the image and shows a 'Run from here'
re-queue button instead of blanking. The last painted mask is remembered and
auto-re-stashed on each new pause (with a Clear control) so it is not lost
between runs. The preview image area now scales with the node width.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Interactive chooser/router: pauses execution, shows the image with up to
10 labeled route buttons + edit-mask + stop. Chosen route gets the image,
others ExecutionBlocker-ed; gate-painted mask on a fixed output; stop
raises InterruptProcessingException. TDD plan with a pure torch-free
gate_bus; lazy comfy imports keep node logic unit-testable.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
MaskEditor alpha comes through as 0 in painted areas; bake 255-a so the
MASK output is white where painted (region of interest).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The DOM-widget width doesn't reliably track the node width in frontend
1.45, so force a fixed column count clipped the grid and the width floor
blocked resizing down. Use flex-wrap (cells wrap to fit, never clip),
drop the computeSize width floor (resize freely), and re-sync the widget
width + reflow on manual resize.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ComfyUI snaps the node to computeSize() on selection, and computeSize's
width ignores DOM widgets, so the grid collapsed/clipped on click.
Override node.computeSize to floor the width at the column-fit width.
Lay the grid out as a fixed 4 columns (128px cells) with the node sized
to fit; base width doubled to 560.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Index badge, has-mask dot, count, and empty-state message were added in
Phase 1; add drag affordances (grab cursor, cell hover) now that
reorder exists.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pool.reorder() permutes slots (validated permutation) and keeps the
active selection on its slot; exposed via /grid_pool/reorder. The grid
thumbnails are drag handles; dropping on another cell reorders.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>