Commit Graph
498 Commits
Author SHA1 Message Date
ausboss 8617fdc983 Version the pack's script imports so an update never meets old browser copies
ComfyUI sends no cache header for .mjs, and the 2.5.1 no-cache header cannot
reach a copy the browser already stored. Firefox then kept running files from
before the update, even through Ctrl+Shift+R, and the preview bar, cards and
editors failed to load.

The server now adds ?v=<tag> to the relative .mjs imports of the pack's
scripts as it serves them. The tag changes whenever any script changes, so
after an update the browser asks for addresses it has never stored. Files on
disk are unchanged. A test fails if a script names a .mjs in a way the tag
would miss.
2026-10-01 17:41:54 -05:00
ausboss 650714b194 Merge pull request #105 from ausboss/release/2.5.1
Release 2.5.1
2026-10-01 12:07:34 -05:00
ausboss 07b9321f7d Release 2.5.1 2026-10-01 11:53:03 -05:00
ausboss 08414d7a85 Merge pull request #104 from ausboss/fix/stale-frontend-after-update
Fix half-loaded AusBoss after a Manager update
2026-10-01 09:44:00 -05:00
ausboss a1e6940deb Keep the browser from running old frontend files after an update
ComfyUI sends no cache header for .mjs, so after a Manager update a browser
could reuse old shared modules while loading the new entry scripts. The new
entries then imported functions the old modules lack and about a third of the
pack stopped loading.

The pack now serves its .mjs files with Cache-Control: no-cache, and a small
entry (js/cache_guard) refreshes the stored copies and asks for a reload when
a tab runs older files than the installed version. It replaces the old
stale-cache toast in the appearance entry.
2026-10-01 09:10:47 -05:00
ausboss b4a2d319eb Merge pull request #103 from ausboss/fix/manager-search-name
Registry listing: make Manager search find ComfyUI-AusBoss
2026-10-01 08:46:13 -05:00
ausboss e7c811927c Registry listing: name ComfyUI-AusBoss and AusBoss nodes so Manager search finds the pack 2026-10-01 08:44:47 -05:00
ausboss c96885be7d Merge pull request #102 from ausboss/release/2.5.0
Release 2.5.0
2026-09-30 01:52:57 -05:00
ausboss 161b305c18 Release 2.5.0 2026-09-30 01:50:35 -05:00
ausboss 4c4655aa41 Merge pull request #100 from ausboss/rc/2026-09-30
Fixes from hands-on testing: seams, Krea and LTX painting, clearer errors, crop node UX
2026-09-30 01:27:51 -05:00
ausboss 0cd8a31fd5 Crop + Rotate + Pad: keep the Resize off | on pill inside the card 2026-09-30 01:00:59 -05:00
ausboss 4a60f58ff0 Merge branch 'fix/see-through-paint' into rc/2026-09-30 2026-09-30 00:33:42 -05:00
ausboss 7aa25f6c71 Merge branch 'fix/stitch-polish' into rc/2026-09-30 2026-09-30 00:26:34 -05:00
ausboss 3bbe3d4911 Stitch Inpaint: catch a gray fill handed back darker, and fit the advice
The unpainted check counted a flat block only within 10/255 of the fill.
Krea 2 can hand a 128 gray fill back as a flat 114 to 118, so a picture
with gray corners got no word. Flat blocks now count within 20/255, and so
does the picture's own flat area that is taken off first, so a flat wall
continued flat still stays quiet.

The message told still pictures that dark footage paints better when
brightened first. That line is now only for videos, in plainer words.

The warning had no changelog entry yet; it has one now.
2026-09-30 00:19:46 -05:00
ausboss ba2bc3e2d1 Stitch Inpaint: Tone match under blend in runs as a few large steps
Tone match ran about 3,700 small torch operations per picture. PyTorch
spreads each one over every CPU it sees, and a cloud container can show it
far more CPUs than it may use, so each one waited its turn: on a RunPod
container it added 37 to 146 seconds to a 1.6 MP picture.

The blurs now run once over every layer they need, and the fit, the
held-out check and the curve inversion run over whole arrays: the band's
samples are summed per knot segment (sorted once, one reduction per pass
for all three fits), every curve is solved in one batched call, and the
curves are read and inverted over the whole picture at once. That leaves
about 18 multi-threaded operations. A single picture reuses the values it
found while measuring when the correction is applied.

The result matches the old code: same decisions, and at most 0.0002 of one
8-bit level apart on real runs (the fit's sums are only added in another
order). The old code is kept in the tests as a reference, and a new test
pins the two together on turned, straight, dark, thin-feather, clip and
alpha cases.
2026-09-30 00:04:49 -05:00
ausboss ff7b751544 Merge branch 'rc/2026-09-30' into fix/see-through-paint 2026-09-29 23:53:53 -05:00
ausboss b904fad791 Docs: see-through pictures and the prompt_image output
The README and the changelog say what Image Crop + Rotate + Pad now does
with see-through parts of a picture, and what prompt_image is for.
2026-09-29 23:53:53 -05:00
ausboss 7424203063 Examples: the tested fixes, laid out for this release
Krea 2 Inpaint Masked keeps a person you leave unpainted (Mask Refine's
Max hole size at 2). Klein 9B Outpaint blends its seam in, with Tone match.
Qwen Image 2.1 Edit + Realign fills see-through parts with gray and its
prompt writer keeps what the request doesn't name. The Krea 2 Outpaint and
Rotate + Outpaint notes add a tip for pulling far on one side, and the
examples that need this release say so. LTX 2.3 Video Outpaint makes room
for the taller clip node. Every file was re-saved by the frontend and
checked in the classic view and in Nodes 2.0.

The changelog no longer says Krea 2 Outpaint keeps its 3:4 ratio lit.
2026-09-29 23:29:54 -05:00
ausboss fc4caf961e Crop + Rotate + Pad: build the prompt view in whole numbers
The same pixels as before, from integer maths over the see-through part's
bounding box only: a 17-megapixel cutout no longer spends seconds on
floating-point work across the whole canvas.
2026-09-29 23:28:41 -05:00
ausboss 9fcc0450dc Krea 2 outpaint examples: the prompt writer reads prompt_image
Krea 2 Outpaint and Krea 2 Rotate + Outpaint describe the canvas before
painting it. They now read the pad node's prompt_image, where see-through
parts of a picture show as white, so a cutout is described on a real
backdrop instead of the gray fill. For a picture with no see-through
parts prompt_image is the canvas itself, so nothing else changes.
2026-09-29 23:18:32 -05:00
ausboss a416420bfa Crop + Rotate + Pad: paint see-through parts, add prompt_image
A see-through part of a picture - a cutout's missing background, an oval
photo's corners, a hole - kept its stored colour blended over the fill.
That colour is often black or the old background, so the model got a
dark or light ring round the picture and Stitch Inpaint pasted part of it
back. A pixel less than 90% as solid as the picture's most solid pixel is
now empty, like a corner a turn leaves: filled with the fill colour,
marked in the mask, new area for both seams. Kept pixels are fully solid
in their own colour.

A new last output, prompt_image, is the image with see-through parts on
white instead of the fill, for the node that writes the prompt: shown the
gray fill, a prompt writer describes a gray backdrop and the model keeps
it. original shows see-through parts on white instead of black.

A picture at least 90% solid everywhere goes through exactly as before;
the new tests hold every output and both seams to the old transform.
2026-09-29 23:18:19 -05:00
ausboss 36a0b5ca6a Merge branch 'fix/mask-refine-fill-limit' into rc/2026-09-30
# Conflicts:
#	CHANGELOG.md
2026-09-29 22:39:30 -05:00
ausboss 11b5a6d56a Mask Refine: Max hole size, so fill holes leaves the part you kept
Paint everything except a person or a pet, turn on fill holes, and it
filled the unpainted subject too, so the part meant to stay was repainted.
The new optional max_hole_size input (a percent of the picture, 0 to 100)
sets the biggest hole fill holes fills. The default, 0, fills every hole
exactly as before, so saved workflows and API prompts run the same; at 2
the gaps a quick brush leaves still fill and a subject left unpainted
stays. Areas touching the picture's edge are never holes, as before.

- Hole sizes come from scipy's labels, the same 4-connected holes its
  fill finds; the torch fallback labels the same 8-connected holes as its
  own fill. Each picture in a batch is measured on its own, after expand.
- The card gets a Max hole size row with a % unit, dimmed while Fill holes
  is off, and a resetUnknown fallback of 0 for 2.x saves that hold the
  card's empty value in its slot.
- Tests: a hole above the limit stays, holes up to it fill, 0 matches the
  old fill, edge-touching areas never fill, the torch fallback agrees,
  batches, and older saves opening with 0.
- Node API snapshot, help page and changelog.
2026-09-29 22:38:36 -05:00
ausboss e4501b2e0c Cards: a number widget holding an old save's empty value counts as unknown
holdsUnknownValue judged only switches and choices, so a number input
appended after a release could not be given a resetUnknown fallback: an
older save hands it the card's empty value, and it stayed there, which the
prompt then fails to convert. A number widget now holds only a finite
number. Only widgets named in a card's fallbacks are ever reset, so no
existing node changes.
2026-09-29 22:38:23 -05:00
ausboss ae2af9db47 Merge branch 'fix/clip-node-ux' into rc/2026-09-30
# Conflicts:
#	CHANGELOG.md
#	example_workflows/LTX 2.3 Video Outpaint (AusBoss).json
#	js/input_preview/index.js
2026-09-29 22:16:33 -05:00
ausboss d6ca2ec6e5 Clip timeline: tidy the header comment and an unused variable 2026-09-29 22:07:50 -05:00
ausboss f7c6803f2b Crop + Rotate + Pad: the new notes no longer make the node taller
A node sized for the old face could grow into the node below once the new
notes showed. Now:
- The size line names the lit ratio where it acted ("pad to 16:9
  1821x1024") instead of adding a line, and "already 9:16: pick another
  ratio or turn it" sits on the same line when it fits.
- The Even out, To start and Full clip buttons fit their lines.
- "= the whole clip. Shorten it to move IN" fits beside the Length on the
  example workflow's node.
- A new picture only ever shrinks the picture area to its shape; it never
  grows the node.
2026-09-29 22:04:25 -05:00
ausboss 3044e16eb3 Merge branch 'fix/clear-errors' into rc/2026-09-30
# Conflicts:
#	CHANGELOG.md
2026-09-29 21:50:27 -05:00
ausboss 3283ceb1db Changelog: clearer errors for strangers' first runs 2026-09-29 21:44:06 -05:00
ausboss f909b6704e Stop a run that has no picture yet, and show a failed check once
Many shared workflows save their loaders blank so people load their own
picture. Pressing Run first started the run, and core Load Image failed
inside it with "[Errno 21] Is a directory". Now the run stops before it
is sent: one message, "Load a picture first:" and the node's name, and
the loader gets a red outline (on the classic canvas and in Nodes 2.0).

It covers core Load Image, Load Image (as Mask), Load Image (from
Outputs) and Load Video, and the pack's Load Image + Pad, Image Crop +
Rotate + Pad, Load Video and both Video Crop + Rotate + Pad nodes (the
file or the local path, whichever the mode reads). It looks at the
prompt the frontend is about to send and walks it the way ComfyUI does,
so bypassed and muted loaders, loaders fed by a link, loaders no output
needs, loaders behind a lazy input and outputs left out of "Queue
selected output nodes" never stop a run. Prompts sent straight to the
API are not checked.

The frontend has no extension hook that can stop a queue, so
app.queuePrompt is wrapped; it only reads, and builds the prompt a
second time only when a blank loader is on the canvas. Anything
unexpected lets the run through unchanged.

When ComfyUI does reject a prompt, a check that reads several inputs
comes back once per input. api.queuePrompt's answer is tidied so each
AusBoss node shows one entry per message, on the input the message is
about. Other packs' nodes are left as ComfyUI sends them.
2026-09-29 21:44:01 -05:00
ausboss 653cf2c8cc Merge branch 'fix/transform-first-pick-refit' into fix/clip-node-ux
# Conflicts:
#	CHANGELOG.md
#	js/shared/transform_editor.mjs
2026-09-29 21:43:45 -05:00
ausboss 8aaa3376b5 Test fillNodeHeight against its own contract
The test carried a copy of the frontend's space-sharing code, and ran
our helper only inside that copy. It now checks what the helper
promises in our own words: no computeSize left behind, a floor with no
ceiling, floors read on each call and made safe, options kept, and a
hide and show that leaves the panel growing again, using the pack's own
hideWidget and showWidget.
2026-09-29 21:43:40 -05:00
ausboss 341b1cef51 Check the node API snapshot in CI, without ComfyUI
The snapshot test needed a ComfyUI checkout, so CI always skipped it and
a renamed or reordered input passed every CI check. The same comparison
now also runs on an offline load of the pack: a standard-library Python
with torch, NumPy, Pillow, PyAV and SciPy replaced by stand-ins that
accept anything. Input and output names come from the node code itself;
with ComfyUI, a test checks that the offline load describes every node
exactly as the real load does. The ComfyUI load now runs in CPU mode, so
it never touches a GPU.

Also:
- The "became required" rule had no test of its own: its example also
  broke the input order, so deleting the rule failed nothing. It now has
  two cases only that rule can catch.
- --update refuses to write a snapshot that would break saved workflows
  or API prompts, unless --allow-breaking says the node never shipped.
2026-09-29 21:43:40 -05:00
ausboss 0f689e3bea Test that file reads stay inside ComfyUI's folders
Widget values reach the loaders through ComfyUI's /prompt route, and
resolve_input_path and local_preview_allowed are what keep those reads
inside ComfyUI's input, output and temp folders. No test covered them:
removing the outside-the-input-folder check, the network-path check or
local path mode's network check passed every test.

tests/test_media_paths.py covers climbing out with "..", absolute paths,
links pointing outside, "[output]" names, network paths refused before
the path is touched (even when a ComfyUI folder itself sits on the
share), and local path mode. The guards need neither torch nor PyAV, so
the media module's heavy imports are stubbed when missing and the file
runs in CI. Each guard's removal fails at least two tests.
2026-09-29 21:43:30 -05:00
ausboss 484ba61d13 Save Video: open the encoder before the first frame
The nvenc encoders are in the libav build with or without an NVIDIA card
and only fail when they open. That happened on the first frame, outside
the handler that explains it, so picking "mp4 h264 nvenc" without the
card ended in a bare "Unknown error occurred: avcodec_open2(...)". The
encoder now opens as the stream is set up, and the message leads with
what to do: the nvenc formats need an NVIDIA GPU, pick "mp4 h264". Other
encoders that fail to start name themselves without the NVIDIA advice.
2026-09-29 21:43:30 -05:00
ausboss 5a6317467a Say "No mask painted" when a picture reaches a mask node without one
Core Load Image hands out a 64x64 mask of zeros when the picture has no
mask painted on it, and picking a new picture after painting one gives
the same. Krea 2 Inpaint Masked then stopped inside Crop For Inpaint with
"Mask size (64, 64) does not match image size (1216, 832)".

Crop For Inpaint, Color Match and Mask Refine (with its picture wired)
now say "No mask painted: right-click your picture, choose Open in
MaskEditor, paint the area, then click Save." A mask made for another
picture names both sizes. LaMa Inpaint used to resize the blank stand-in
and hand the picture back unchanged; it says the same now. An empty mask
of the picture's own size still runs as before: Crop For Inpaint takes
the whole picture and stitches it back untouched.
2026-09-29 21:43:20 -05:00
ausboss cb05fcc9b7 Docs and changelog for the clearer canvas and preview controls
The help pages, the README and the changelog use the new names (Round
canvas to, Frames for, Server file, the Resize switch) and describe the
always-scrubbing timeline and its grip, the padlock rules, the "already
this shape" note, the resize warning and Even out, the preview switch
bringing its picture back, Compare's labels and the Workflow Note's Use it.
2026-09-29 21:43:07 -05:00
ausboss ac9cc58592 Report each failed input check once, and let ComfyUI check the rest
A VALIDATE_INPUTS that takes **kwargs makes ComfyUI skip its own range
and list checks for every input, and a failed check comes back once per
input: Image Crop + Rotate + Pad without a picture showed 20 copies of
"Select or upload a source file first". Each validator now names only
what it reads.

- Image Crop + Rotate + Pad, Load Video and LaMa Inpaint read one input
  and report one error, on it. Video Crop + Rotate + Pad (Frame and
  Clip) read the three that choose the source. LoRA Loader reads the
  stack and on_missing; Save Image reads its two names and output_dir.
- Save Video has no validator any more: ComfyUI's own check holds a
  typed fps to 0.01-240.
- Load Video and the Clip node check the trim window, force_rate and
  Fixed frames as they run, where a wired bound has its value. They are
  async, so ComfyUI starts them ahead of other nodes.
- The sources still skip ComfyUI's list check on purpose, so uploads,
  subfolders, MaskEditor saves and a stale video choice in local path
  mode keep working. The path checks behind them are unchanged.
- crop_aspect_ratio accepts any whole-number W:H, as the transform
  always has, so a workflow made with someone else's presets still runs;
  anything else is now refused before the run.

tests/test_validate_inputs.py pins what each validator names (runs in
CI) and, with ComfyUI, drives ComfyUI's own validation.
2026-09-29 21:43:01 -05:00
ausboss 33dae551df Merge branch 'examples-refresh' into rc/2026-09-30
# Conflicts:
#	CHANGELOG.md
#	example_workflows/Krea 2 Outpaint (AusBoss).json
#	example_workflows/LTX 2.3 Video Outpaint (AusBoss).json
2026-09-29 21:42:25 -05:00
ausboss d27040e20b Merge branch 'fix/krea2-outpaint-paint' into rc/2026-09-30
# Conflicts:
#	CHANGELOG.md
2026-09-29 21:41:09 -05:00
ausboss f9bca9927a Merge branch 'fix/stitch-seam-turned' into rc/2026-09-30
# Conflicts:
#	CHANGELOG.md
2026-09-29 21:41:09 -05:00
ausboss 67c620589e Merge branch 'feat/workflow-note-fit' into rc/2026-09-30
# Conflicts:
#	CHANGELOG.md
2026-09-29 21:41:09 -05:00
ausboss b842b15df7 Merge branch 'fix/nodes2-undo-stale-faces' into rc/2026-09-30
# Conflicts:
#	CHANGELOG.md
2026-09-29 21:41:09 -05:00
ausboss a7e7795ac2 Merge branch 'fix/ltx-outpaint-sides' into rc/2026-09-30 2026-09-29 21:40:54 -05:00
ausboss 71b354f54b Merge branch 'fix/save-image-nodes2-height' into rc/2026-09-30 2026-09-29 21:40:53 -05:00
ausboss 5b2f2508ab Preview and padlock: two leftovers after the first pass
- A node dragged taller while its preview was off keeps that height when
  the preview comes back.
- A new picture with no ratio lit starts with the padlock off, as the
  untouched picture has no shape to hold.
2026-09-29 21:40:23 -05:00
ausboss 40571ce86b Workflow Note: point loaders at a model found in a subfolder
The note said "installed" for a model kept in a subfolder while the
workflow's loader still asked for the bare file name, which ComfyUI could
not find and marked red. Such a row now says where the file is ("in
LTXV 2.3/") and has a Use it button that points those loaders at the found
copy. The check stays on the ComfyUI server's own model lists.
2026-09-29 21:33:25 -05:00
ausboss 6e5a1e4783 Compare: A and B sit on either side of the split line
The A | B badge stayed in the middle of the picture while the split line
moved. Now A rides just left of the line and B just right of it, on the
picture each one names; with one picture showing, its label sits alone.
2026-09-29 21:33:25 -05:00
ausboss 69902c61f0 Number boxes: Shift slows the drag where there is no finer step
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.
2026-09-29 21:33:25 -05:00
ausboss fe7f301264 Crop + Rotate + Pad: clearer padlock, Fit, added space and editor
The padlock:
- Reset and tapping the lit ratio turn it off.
- It does nothing on the untouched picture (the row says Source), so a
  trim there only trims.
- The row says Held while it is on, and a locked drag splits the new
  bands evenly (each move is solved from where the drag started).
- Reset crop also removes the bands the lock added.
- The lit ratio and the lock share the pack's solid teal "on" look;
  hover is a light outline.

Shapes and sizes:
- A picture within about 1% of a ratio counts as that ratio: tapping 9:16
  on a nearly 9:16 photo adds no 1 px band.
- While a ratio is lit, the line under the picture says what it did,
  and "Already 9:16: nothing to add. Pick another ratio or turn it." when
  there was nothing to do (a saved ratio re-applies to every new picture).
- The resize warning reads "1.5% taller: each side rounds to 32 px"; its
  tooltip names a Step that avoids it, and in pad mode Even out adds a few
  pixels of padding so nothing stretches.
- Fit dims and says "pick a ratio first" until a ratio is lit.
- Over the picture, the cursor and small arrows show only the ways it can
  move; with nowhere to go it is a plain pointer.

Drawing:
- Added space is drawn in the real fill colour with a faint hatch, and
  only the picture the crop cuts away is darkened, so black bands on the
  black stage show.
- The rotate knob keeps clear of the padding diamonds and crop squares.
- On a big node the controls stay at most 460 px wide, centred, and only
  the picture grows. A new picture fits the picture area to its shape,
  never taller than the height you gave it.

Words: Align is "Round canvas to", Local path is "Server file", Resize is
an off | on switch, and the canvas row labels read like the others.

The full editor is built from the node's own controls: the ratio row with
its turn button and padlock, the Fit switch, and number boxes for the
rotation (Shift for 0.1 degree) in place of the coarse slider. Ratios
from ausboss_presets.json that no button shows sit in a More list. The
size box keeps clear of the handles, and the editor's button style no
longer reaches the number boxes.
2026-09-29 21:33:25 -05:00