The four mode buttons become one switch, Slide | A | B | Erase, whose
marker slides to the choice. In Erase the brush's two jobs and the
picture on top are switches of the same kind, and PSD is a plain
off | on.
Save moves to the bottom right of the node, larger, with a disk icon,
in a row of its own with the name of the files and the PSD choice.
The files can be named. A Name field on the node takes letters,
digits, spaces, dots, dashes and underscores; the server checks the
same rule and refuses anything else, so a folder is never part of a
name. A new optional filename input takes a wired name, such as the
source picture's file name: its folder and extension are dropped. The
save route still names no file to read.
Size and Soft scrub from their label and from the unit inside the box
as well as from the number (the scrub control gains handle() for this).
Workflows saved before load as they were: 60 that use the node were
opened (the pack's examples, published workflows, the oldest saved
shapes), 72 nodes kept their size, mode and links. The node is one
input socket taller.
Found in a sweep of the pack against ComfyUI's own nodes: things the normal
node does that the pack's node did not.
- Every number box takes a sum. Click a number, type 1024*1.5 or
(1920-64)/2 and press Enter, as in ComfyUI's own number boxes: + - * / %,
brackets and a sign. The reader is the pack's own (sumValue in
js/shared/scrub_input.mjs) and is only asked when the text is not a plain
number.
- Show Text takes any wire. Its input was STRING only. A number, an on/off
value or a list is shown too; a picture or a latent is shown by its size.
The output stays STRING and carries the text that is shown, so text
passes through unchanged and a number comes out as text.
- Save Image takes name tokens in the file name, as ComfyUI's own Save
Image does: %date:yyyy-MM-dd% and %Node.setting% are filled in the
browser when a run is sent (js/shared/name_tokens.mjs, now shared with
Save Video), %width% %height% and the time tokens on the server. The
path preview shows them. A linked filename is never read for tokens.
- Ctrl + Up and Ctrl + Down change a word's weight in the pack's prompt
boxes (Text, Krea 2 Encode). The card's text box stopped the key before
ComfyUI's own listener saw it; those two keys now go on from a multiline
box, and from nowhere else.
- Image Size shows what it measured beside its outputs after a run
("width: 1024"). The numbers go into the output labels, so the node keeps
its size. ComfyUI says nothing about a node whose answer came from its
cache, so the numbers are kept in the node's properties and come back
when a workflow is opened again; a changed picture wire clears them.
No input was added, renamed or reordered. Help pages, README lines, tests
and CHANGELOG entries are included.
A Float wired to a sampler's denoise could be set above 1, where ComfyUI's
own Primitive node stops at 1. Both number boxes now follow their output to
every input it reaches, through Reroutes and into subgraphs, and keep to the
range all of those inputs allow: by typing, by the arrows and by a drag. A
value that is outside when the wire is made comes to the nearest limit, the
card shows the limits beside the value (0–1), and an unwired box takes any
number as before. No input was added, so saved workflows and API requests
are unchanged.
With it:
- A new box takes the value of the first input it is wired to, as the
Primitive does. A box that came with a workflow or a paste, or one that
was already set, keeps its own value.
- Float shows the decimals its steps reach (1.00 wired to denoise, 8.0
wired to CFG) and goes past them only for a value that uses more. It read
1.000 everywhere before.
- Integer's own limit goes from 2,147,483,647 to 9,007,199,254,740,991, the
largest whole number a browser holds exactly, so a seed fits.
The walk over the graph is js/shared/wired_limits.mjs; the scrub control
gains setRange and a way to drop the zeroes its steps never reach. Help
pages, tests and the CHANGELOG entries are included.
Every field on a node face stopped all key presses, so ComfyUI's shortcuts did nothing while the cursor was in a Text node, a number box, the Seed box or a file name box. Ctrl + Enter only queued a run after a click outside the node.
The fields now keep the keys they type and edit with (so Delete or Ctrl + A never reach the canvas) and pass app shortcuts on to ComfyUI, as its own text boxes do. One helper, keepKeyInField in js/shared/canvas_passthrough.mjs, is used by the shared card's text, multiline and colour fields, the number boxes, the Seed box, Save Image's name fields, Load Video's IN and OUT boxes and LoRA Loader's strength boxes.
Round canvas to on Image Crop + Rotate + Pad and both Video Crop + Rotate
+ Pad nodes is now labelled Divisible by. Its tooltip says what it does
(a few pixels of fill on the right and bottom so the width and height
divide evenly by the number), when to use it (models that need sizes
divisible by 8, 16 or 32) and that 1 is off. The input is still
canvas_multiple, so saved workflows keep their value.
Its arrows and drags added 8 to whatever was there, so from 1 (off) they
went 9, 17, 25. makeScrubInput gets a snap option: whole steps land on
multiples of the step (1, 8, 16, 24 and back down to 1), while Shift's
fine step and typed values are left alone. The resize Step box on the
same nodes and Multiple on Load Image + Pad had the same problem and use
it too.
The editor's status panel now refreshes when Divisible by changes, as it
already did for every other size control.
Shift is the fine step on every number box, but on whole-number boxes such
as Feather the fine step was the step, so Shift did nothing. There it now
slows the drag four times instead. Pressing or letting go of Shift during
a drag carries on from the current value instead of jumping.
- Rotating keeps the crop's size over the same part of the picture from
the knob, slider, number box and Reset rotation (cropForRotation).
- A readout under the picture names every step that sets the output size
(crop -> pad -> align -> resize) and warns when the resize Step
stretches the picture or Align pads fill ahead of a resize; ticking
Resize shows Megapixels and Step on the face.
- Locked-aspect crops use integer maths (_ratio_box / ratioBox), so the
size shown equals the run.
- Image Crop + Rotate + Pad's four resize inputs are optional, so API
prompts saved before them validate again.
- Video Crop + Rotate + Pad -> Clip: one Length switch replaces the Fixed
frames and Limit boxes; OUT sits on the last output frame; a connected
fixed_frames / frame_load_cap takes over the length.
- The stitcher pastes the unfaded canvas when feather > 0
(transform_pil_layers / keep_unfaded). Superseded by mask-only feather
and dropped in the next commit.
Carries a copy of the editor Cancel / discard-prompt change from
feat/editor-cancel-discard (#73), which this work was built on.
The info card's suggested-strength bounds were bare number inputs and
the gear menu's default strength and step were typed text boxes, the
last numbers in the pack that did not scrub. The scrub control gains an
optional empty state for bounds that may be absent ("any"), and gear
menu scrub rows take their own step and precision.
makeScrubInput in js/shared/scrub_input.mjs is the LoRA strength box's
interaction made reusable: drag the value to scrub (dead zone keeps
clicks clicks), click to type an exact value, chevron arrows step,
ArrowUp/Down step from the keyboard, Shift always means the fine step.
Values are quantized through one choke point, and edit mode re-asserts
itself a frame after the click because the graph canvas can steal focus
mid-sequence.
The gesture math is pure and tested (tests/scrub_input.test.mjs).
AGENTS.md and the brand skill record the convention - numeric fields in
pack panels use this control, never a bare input[type=number] - and
AGENTS.md also picks up the lab shared-code vendoring pull step.