dependabot/github_actions/github-actions-30f7f1d3b7
30
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
040b30733d |
feat(matte): first-party mask-guided one-step video matting nodes (#269)
* feat(matte): first-party mask-guided one-step video matting nodes
Adds matte/ — an independent implementation of the published VideoMaMa
one-step SVD method (matte/pipeline.py) plus Koolook's temporal windowing,
subject-focused crop/stitch, resolution control (/64, shortest-side) and
auto OOM resolution-backoff. Nodes: KoolookMatteLoader, KoolookMatteSampler,
KoolookMatteFocusCrop, KoolookMatteFocusStitch.
Registered via the existing guarded _merge_node_group("Koolook Matte",
".matte"), so a missing diffusers disables only these nodes. diffusers is
already pulled in by the radiance/whatdreamscost forks, so no new dependency.
Loads (never bundles) the VideoMaMa UNet (CC-BY-NC) + SVD VAE at runtime;
matte/NOTICE records the model licenses and user responsibility.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* chore(dev-sync): include matte/ in RUNTIME_PATHS
So `sync_to_dev` copies the new matte node package into the live ComfyUI
install alongside the rest of the koolook pack.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(matte): raw cond latents; fp16 default; preserve checkpoints on dev-sync
pipeline.py: _encode_latents must NOT divide by vae scaling_factor. The
VideoMaMa UNet is trained on raw VAE latents (matching okdalto's
VideoInferencePipeline, which multiplies by scaling_factor then divides it
back out -> net x1). Dividing over-scaled the conditioning ~5.5x and produced
a systematically blurry matte on every frame. Verified 5/5 vs the desktop /
vanilla reference on identical single-frame inputs.
nodes.py: harden the loader precision fallback so fp16 is the true default -
only an explicit "bf16" opts out; a stale "auto" widget now resolves to fp16
instead of bf16.
sync_to_dev.py: the rmtree+copytree mirror deleted matte/checkpoints/ (the
gitignored ~10GB SVD+VideoMaMa weights) on every matte sync, forcing a
re-download. Add PRESERVE_IN_DEST + selective _clean_dest so runtime-
downloaded model data survives a sync.
docs: add docs/maintainers/matte-pipeline.md (latent-scaling invariant,
black-output causes, fidelity levers, single-frame + vanilla-oracle debug
loop, checkpoint preservation).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(matte): address PR #269 review
- license: align matte to the repo's GPL-3.0 (was self-contradictory: claimed
"MIT licensed - see LICENSE" while LICENSE is GPL-3.0). pipeline.py header,
NOTICE, and the maintainer doc updated. NOTICE still credits VideoMaMa
(CC BY-NC) + SVD (Stability Community License).
- nodes.py _ensure_2d_mask: squeeze first, then handle [H,W,C]/[C,H,W]
explicitly and RAISE on ambiguous shapes -- previously [H,W,3] silently
became [W,3] (wrong geometry).
- nodes.py OOM backoff: catch RuntimeError (OutOfMemoryError subclasses it, but
cuBLAS/cuDNN/older paths raise plain "RuntimeError: CUDA out of memory"); the
existing message guard still filters non-OOM errors.
- nodes.py: warn when the guide mask is empty instead of silently falling back
to full-frame.
- sync_to_dev.py: PRESERVE_IN_DEST is now an exact relative path
("matte/checkpoints"), not a bare name matched at any depth; handle symlinks
before is_dir() in _clean_dest so a symlinked dir isn't recursed/rmtree'd.
- CHANGELOG: add the Koolook Matte nodes under [Unreleased] with the
non-commercial model-license caveat.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(matte): address PR #269 re-review
- sync_to_dev.py [BLOCKING]: a top-level symlinked dest (e.g. target/matte -> X)
was passed straight into _clean_dest()/copytree(), which follow the link and
can mutate files outside the target. Now unlink a symlinked dest and own the
path as a real dir (checked before exists(), which follows symlinks). Verified
with a repro: the symlink target's file survives.
- nodes.py: force float32 on a CPU fallback (CUDA unavailable). Half precision
is unreliable on CPU; fp16 kernels would error. Warn that CPU is very slow.
- docs: correct the preserved-path guidance to the target-relative
"matte/checkpoints" (was a bare "checkpoints" name); reword "near-verbatim
reimplementation" -> "independent implementation targeting behavioural parity"
to match the NOTICE/pipeline framing.
- nodes.py: also warn on a degenerate (<8px) guide-mask region before the
full-frame fallback (was silent).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(matte): address PR #269 re-review (CI red + FocusCrop frame check)
- nodes.py: KoolookMatteFocusCrop now validates images vs coarse_mask frame
counts (raises like KoolookMatteSampler.run_inference). A mismatch previously
made cropped_images/cropped_mask diverge and silently drop/misalign frames at
FocusStitch.
- pipeline.py: split "vae.to('cpu'); _clear_cache(...)" onto two lines (Ruff
E702 was failing Lint & Smoke).
- constraints-test.txt: bump pillow 12.2.0 -> 12.3.0 (pip-audit CVE, fixed in
12.3.0). Pillow is a leaf dep so the closure is unaffected; CI re-audits.
- README: note the Koolook Matte nodes need diffusers (already via the LTX /
Radiance forks) and huggingface_hub for runtime weight downloads.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: AI Machine <ai.machine@x.baconcph.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
b6b95d8a85 | docs: add Ko-fi funding link (#260) | ||
|
|
ae7abba73b |
docs: refresh shipped help and tooltips (#249)
* docs: refresh shipped help and tooltips * docs: add snapshot transfer guide section * docs: refresh guide screenshots |
||
|
|
8c8546c17c |
Add queue-driven loop status controller (#205)
* Add queue-driven loop status node * Document ComfyUI server API testing * Harden loop queue controller * Guard loop controller HTTP requests |
||
|
|
67e9d55e98 |
docs(nodes): add user guides and tooltips (#200)
* docs(nodes): add user guides and tooltips * chore: clean up node preflight nits |
||
|
|
8058e17456 |
fix(snapshot): paired drift-corruption fix — duplicate-install guard + boot-time mismatch (#161, #162) (#186)
* fix(snapshot): prevent drift corruption from duplicate installs + boot-time mismatch (#161, #162) Closes #162 and #161 as the paired fix the issues describe — both touch the same data-loss surface and verify against the same dev-sync rig. installs at import time, log critical, register nothing in the alphabetical loser; client-side `window` sentinel as belt-and-suspenders; align .env.example / dev-iteration-loop / sync_to_dev / README at the Registry-derived `koolook/` path. compare against live /userdata + picks, set a drift flag on mismatch; gate periodic + pre-load autosave routing to `_unsaved_autosave/` while drifted; promote status pill to "drifted" precedence over "saved" with a recovery tooltip; auto-clear on the next markStateSaved (Save / Load). 26 new tests (14 install guard, 4 sidebar sentinel, 8 boot drift) — 316 total passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(snapshot): apply review fixes — canonical fingerprint + early loser exit + drift timestamp Review-driven follow-ups on PR #186: 1. **Symmetrize file-side fingerprint (MEDIUM).** `detectBootDrift` now uses a new `_canonicalStateFingerprint()` that normalizes the workflows tree through `normalizeWorkflowsStore` AND deep-sorts keys via `sortJsonValue`. Without this, hand-edited / cross-machine / pre-v0.3 files would false-positive as drifted on first boot (e.g. `archived: "false"` string vs `false` bool, missing `directories: {}`, key insertion-order asymmetry from the `{...wf, archived, module, tags}` spread). `_computeFingerprint` stays unchanged so the localStorage save baseline contract holds for existing users. New regression test verifies a shape-only diff does NOT trigger drift. 2. **Gate fork imports on `_is_winning_install` (LOW).** Non-winning duplicate installs now short-circuit before the heavy torch / PIL / diffusers / aiohttp imports, exiting in ~5 LoC instead of paying full import cost just to discard the mappings. 3. **Drift timestamp uses `driftDetectedAt`, not stale `lastNamedSaveAt` (LOW).** The localStorage save baseline could be from a prior session whose live state was already corrupt — surfacing it as "Last named save" in the drift tooltip would mislead. Replaced with the session-noticed-at timestamp from `_bootDriftDiagnostics`. 352 tests passing (316 prior + 26 from PR #186 + 1 new normalize- symmetry case). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(install-guard): fail safe on unreadable / non-UTF-8 siblings (#162) Re-review follow-up. The import-time duplicate-install scan could crash the entire plugin load (fail-silent — the alphabetical winner vanished too, not just the loser) on two unguarded paths: - detect_duplicate_koolook_installs: the per-entry is_dir()/is_file() over custom_nodes/ siblings was unguarded, so a non-traversable sibling (restrictive perms, broken mount, a special dir) raised PermissionError up into __init__.py. No duplicate even required. Now caught per-entry and skipped. - read_pyproject_version: read_text(encoding="utf-8") raises UnicodeDecodeError (a ValueError, NOT OSError) on a non-UTF-8 / binary pyproject.toml, escaping the `except OSError`. Now degrades to "?" via `except (OSError, ValueError)`. - __init__.py: wrapped the guard call site as a final backstop — any unforeseen guard failure now degrades to register-normally rather than aborting the import. Both paths reproduced before the fix; the first surfaced while running the suite from a /tmp checkout whose parent held a root-owned dir. 3 regression tests added (non-traversable sibling skipped; non-UTF-8 pyproject -> "?"; report survives a non-UTF-8 sibling). Full suite: 452 passed (449 + 3). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: kflame99 <261674183+kflame99@users.noreply.github.com> |
||
|
|
4739dd4203 |
feat: Easy_Utility, Easy_LoadVideo, and preview fixes (#184)
* feat(nodes): add Easy_Utility — INT → padded STRING dispatcher First mode `int_to_padded_string`: takes an INT widget (with up/down arrows) and emits a zero-padded STRING (default `001`, no `v` prefix). The downstream `koolook_versioning.resolve_version_token` prepends `v` and re-pads, so wiring this into `EasyAIPipeline.version` / `Easy_VideoCombine.version` yields the standard `vNNN` token at execution. Designed for extension: the `mode` widget shipped from day one so adding further conversions (string→int, formatting variants, etc.) doesn't rewire saved workflows. Note: the previously-attempted JS preview-resolver refactor that aimed to fix the "preview shows stale version" bug was reverted in this worktree before commit — it didn't actually fix the bug (the real cause is the JS resolver not descending into ComfyUI subgraphs) and it broke shot_name resolution in the process. The preview-resolver work is NOT in this commit; only the Python node + tests. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(nodes): guard version widget against pysssss .replace crash PR #180 added a STRING `version` widget to EasyAIPipeline and Easy_VideoCombine. Three workflow states leave widget.value undefined or non-string when graphToPrompt iterates widgets: - Pre-#180 workflows replay an INT (e.g. `1`) into the new STRING slot. - Widget-to-input conversion voids the value in newer LiteGraph. - Easy_VideoCombine's dict-based widgets_values omits the new key entirely on workflows saved before #180. With pysssss/ComfyUI-Custom-Scripts installed, presetText.js patches every STRING TextWidget.serializeValue to run callbacks that do `value.replace(...)` for `{variable}` substitution. Any of the states above crashes graphToPrompt and turns Run into a no-op for the whole workflow ("Cannot read properties of undefined (reading 'replace')"). Fix: trap `widget.value` reads/writes on the version widget via `Object.defineProperty` so the property is always coerced to a string regardless of caller. `configurable: true` so downstream code can still override the descriptor if it needs to. Tests: 231 passing; both JS files parse OK. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(ai-pipeline): resolve subgraph version preview * feat(video): add path-aware load video node * fix(ai-pipeline): preview connected text names * fix(pr184): address review cleanup --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
7d46d1cdf2 |
Release v0.3.7 (#175)
* Release v0.3.7: support docs and fixes * docs: align bug report privacy guidance |
||
|
|
ff79b0f418 |
feat(video): add Easy_VideoCombine (#154)
* feat(video): add Easy_VideoCombine with absolute-path support Adds a Koolook subclass of VHS VideoCombine that bypasses ComfyUI's output-directory sandbox when filename_prefix is an absolute path — the VFX-pipeline missing piece for writing renders into a project tree (e.g. E:/projects/shot01/v003) instead of ComfyUI/output/. Implementation: - k_video_combine.py: ~60 LoC subclass + a pure _resolve_abs_target helper. Scoped-patches folder_paths.get_save_image_path for the duration of one combine_video() call so upstream's encoder, audio mux, batch manager, and progress bar run unchanged. No VHS code copied. Self-skips registration when VHS isn't importable (clean one-line stderr notice). - Discriminator: os.path.isabs(filename_prefix). No new input pin; pattern borrowed from spacepxl/ComfyUI-HQ-Image-Save's SaveEXR. - Optional create_path_if_missing BOOLEAN (default False) so typos surface as FileNotFoundError instead of spawning stray dirs. License audit (2026-05-16): - VHS upstream: GPL-3.0 (verified via raw LICENSE fetch). - HQ-Image-Save pattern source: MIT, copyright 2023 spacepxl. - Koolook: already GPL-3.0; both upstreams are compatible. - No source code from either upstream is incorporated. Verification: 18 pytest cases green (12 existing + 6 new covering relative passthrough, absolute resolution, create-on/off branches, trailing-separator normalization, and empty-basename rejection). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(starter-preset): pre-favourite Easy_VideoCombine Adds the new node to the shipped starter_preset.json picks so fresh installs surface it in the Kforge Labs sidebar's Nodes section without the user having to discover it via Comfy's stock search first. Pairs naturally with the existing LoadEXR / SaveEXRFrames picks from HQ-Image-Save. Existing installs with non-empty picks are unaffected (the seeder skips them by design); they can either Load -> "starter" in the Snapshot dialog or hit "+" once in the Nodes section to pull it in. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(dev-sync): include k_video_combine.py in RUNTIME_PATHS Without this entry the new Easy_VideoCombine module is never copied into the dev ComfyUI install, so the node fails to register on restart with a silent ImportError. Caught when the maintainer restarted ComfyUI and couldn't find the node in the search palette. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(starter-preset): include all Koolook nodes in default picks Fresh installs should land on a populated Nodes (favorites) panel that immediately surfaces what Koolook provides — otherwise new users see only third-party picks and have no entry point into the Koolook-native workflow. Adds the 8 currently-registered Koolook node IDs to the shipped starter preset alongside the existing third-party essentials: EasyAIPipeline, EasyResize_Koolook, EasyWan22Prompt, Easy_Pattern, Easy_VideoCombine, Easy_hdr_VAE_decode, Easy_hdr_VAE_encode, KoolookLoadCameraPosesAbsolute, easy_ImageBatch Also adds Easy_VideoCombine to the README's Included Nodes table. Existing installs with non-empty picks are unaffected by the seeder (by design). To pull the Koolook defaults into an existing install, Quick Save first, then Snapshot -> Load -> "starter". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(video): reach VHS_VideoCombine via nodes.NODE_CLASS_MAPPINGS The previous `from videohelpersuite.nodes import VideoCombine` fails inside ComfyUI's loader context because VHS uses relative imports throughout (`from .logger ...`, `from .utils ...`) that only resolve when VHS is loaded through ComfyUI's importlib spec — not through a plain absolute import path. The error surfaced as No module named 'utils.install_util'; 'utils' is not a package at Koolook load time, which caused the node to self-skip with an empty NODE_CLASS_MAPPINGS — invisible in ComfyUI's search palette. Fix: look up VHS_VideoCombine through `nodes.NODE_CLASS_MAPPINGS`, which is the documented cross-pack interface. ComfyUI's loader (custom_nodes/.../__init__.py exec_module → merge into global) runs to completion for each pack before moving to the next, and VHS sorts before Koolook alphabetically in every layout we've seen, so by the time Koolook's __init__.py runs the global registry already has VHS_VideoCombine in it. Verified against ComfyUI's nodes.py load_custom_node() at load_custom_node() lines 2196 (exec_module) and 2225-2228 (merge), which guarantee this ordering. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(video): add output_directory input for split path/name editing Overloading filename_prefix for absolute paths means losing the "just type a name" affordance — once you put the path there, there's nowhere to specify just the file root. Across many renders into the same project tree this becomes tedious: every iteration retypes the whole path. Adds an optional `output_directory` STRING input. When set: - filename_prefix is treated as just the filename root; any path components are stripped (so accidental typos like "sub/clip" don't double-up under the directory). - Absolute output_directory writes directly to that location. - Relative output_directory joins under ComfyUI's output/. When output_directory is empty, the original overloaded filename_prefix behavior is preserved unchanged (back-compat for the one-field flow). Implementation: - New pure helper `_compose_prefix(filename_prefix, output_directory)` combines the two fields into one effective prefix. The existing isabs discrimination then handles sandboxed vs absolute writes uniformly downstream. - 6 new tests cover all combinations: empty/abs/relative directory, path stripping from filename_prefix, trailing-separator trim, empty-name fallback. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(video): coerce frontend 'undefined' STRING values to empty The ComfyUI frontend serializes a STRING widget with empty default as the literal string "undefined" when left untouched (a known long-running quirk). Without defensive normalization, an untouched output_directory was treated as a real directory name and prepended to the user's path: filename_prefix = "E:/renders/clip_v003" (typed by user) output_directory = "undefined" (frontend default, not typed) _compose_prefix(...) -> "undefined/clip_v003" (relative) _resolve_abs_target -> None (not absolute) super().combine_video -> writes to <output>/undefined/clip_v003_* The QuickTime ended up at <ComfyUI>/output/undefined/<name>.mov with a spurious `undefined/` subfolder, instead of at the absolute path the user actually specified. Fix: a `_normalize_text_input()` helper coerces the literal strings "undefined" / "null" / "None" (case-insensitive, post-strip) to "". Applied to both filename_prefix and output_directory at the top of combine_video() before any path composition. 4 new tests cover the sentinels and a regression test for the exact path-composition behavior that produced the bug. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(video-fe): wire format-specific widgets for Easy_VideoCombine VHS's frontend extension (web/js/VHS.core.js:2030) gates its format-widget machinery on `nodeData?.name == "VHS_VideoCombine"` — strict-equality on the registered node ID. Our subclass uses a different ID (`Easy_VideoCombine`), so none of VHS's per-format widget rendering ran. The user saw: [VideoHelperSuite] - WARNING - Missing input for p has been set to hq on every execution (profile defaulting to "hq" for ProRes), and had no way to pick anything other than the default — because the profile dropdown was never rendered. Fix: a minimal frontend extension at web/easy_video_combine.js (~80 LoC) that replicates `addFormatWidgets` for our node name. Hooks the format dropdown's callback to add/remove per-format widgets the same way upstream does. Self-contained — does not import from VHS's module (their helpers aren't exported as ES imports). Verifies via the actual ComfyUI install after dev-sync; static preview servers can't exercise it (depends on LiteGraph's registered_node_types at runtime). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(video): strip 'undefined' from anywhere + one-shot debug log The previous normalization only caught the EXACT literal "undefined" / "null" / "None" at field-level. Adds two stronger defenses for the case where a sentinel still slips through: 1. _normalize_text_input now also strips surrounding quotes (paste- from-Explorer artifact) and handles embedded newlines by taking the first non-empty non-sentinel line (defends against multi-line Text Multiline inputs with trailing blank or junk lines). 2. New _strip_sentinel_components helper drops any path component that is exactly a sentinel string from the composed effective_ prefix — belt-and-suspenders for any path that somehow carries `\undefined\` as a literal segment by the time it reaches us. Also adds a one-shot print() of fp_raw, od_raw, normalized values, and effective_prefix at the top of combine_video. The user is seeing an undefined/ folder under their custom path despite the field-level normalization, and pure code tracing doesn't reproduce it — the log will surface what kwargs actually contains at run time so we can fix the real cause if defensive stripping doesn't already handle it. To be removed in a follow-up once root cause is known. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(video): trim node docstring + tooltips, remove debug print - Class docstring collapsed from ~20 lines to a single sentence (the frontend was showing it as the node description on right-click, cluttering the UI). - Widget tooltips trimmed to one short sentence each — same intent, no walls of text. - Debug print() added in |
||
|
|
9dab85c695 |
feat(easy_pattern): add test-pattern node + auto-restart dev-sync (#135)
* feat(easy_pattern): add test-pattern node + auto-restart dev-sync Adds an `Easy_Pattern` node (Koolook/Testing) for solid-color frame batches with optional per-frame index overlays — verifies sequence merging, frame insertion, batch indexing, and video-pipeline frame order at a glance. Color inputs use the same `White/Black/Gray/Custom` dropdown idiom `EasyResize_Koolook` already exposes for pad/panel colors, so "Gray" means the same 50% sRGB across nodes. `scripts/sync_to_dev.py` now restarts the live ComfyUI server after a successful sync (via ComfyUI-Manager's `/manager/reboot`). Default-on because dev-sync is only ever invoked to see new code, and Python custom-node files load once at server start — `--no-restart` is the escape hatch. The `RUNTIME_PATHS` manifest also picks up `k_easy_pattern.py` so adding a new top-level node doesn't silently break the pack at import time on the next sync. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(sync-dev): restrict restart URL to http(s) for Bandit B310 `urllib.request.urlopen` accepts arbitrary schemes including `file://`, which Bandit B310 flags as a path-traversal vector. The script's typical caller is the maintainer's own shell, but a typo in `--restart-url` could surprise — and the static gate is right to flag it. Validate the scheme is http/https before the urlopen call and annotate it so Bandit accepts the now-truthful narrowing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
f8f8adf55d |
Use KForge spotlight as onboarding front door (#124)
* docs: use KForge spotlight and refresh guide showcases * docs: address guide showcase review polish * docs: fix auto-save showcase anchor |
||
|
|
8bbedfe3f7 |
docs: host visual guide on GitHub Pages, retire wiki URL (#117)
The bundled visual sidebar guide is now also live at https://malkuthro.github.io/ComfyUI-Koolook/web/guide/ — pulled from main via GitHub Pages (legacy mode, source=main/, enabled out-of-band via the repos/.../pages API). README's "get started" and "Learn More" sections, plus pyproject.toml's Documentation URL (used by the Comfy Registry package page), now point at the Pages site instead of the unmaintained wiki. The in-app Tools → Help (`H`) button continues to open the bundled local copy via `import.meta.url`, so the guide still works offline. While here, fixed README's stale "Tools → Info" wording — the actual button has the H help glyph and a tooltip reading "Open the Kforge Labs visual guide" (verified in web/sidebar/tree.js). Closes the wiki-URL part of #114; the rest of #114 (cross-ref polish, glossary, snapshot-schema reference page) stays open. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
27705be037 |
feat(sidebar): add onboarding guide (#107)
* feat(sidebar): add onboarding guide * docs(guide): clarify tag search casing * docs(guide): clarify workflow save copy * docs(guide): refine sidebar visuals * docs(guide): refresh save snapshot visual * docs(guide): refresh load snapshot visual * docs(guide): refresh module save visual * docs(guide): use real sidebar screenshot * docs(guide): render sidebar overview screenshot directly * docs(guide): soften sidebar overview annotations * docs(guide): clarify nodes action bar callout * docs(guide): clarify workflow action bar callout * docs(guide): simplify sidebar overview markers * docs(guide): align sidebar overview intro * docs(guide): use real snapshot recipe screenshots * docs(guide): simplify project workflow diagram * docs(guide): make function cards scannable * docs(guide): sketch module recipe icon focus * docs(guide): use real icon screenshot for module recipe * docs(guide): add cropped workflow action screenshot * docs(guide): use full toolbar screenshot for module recipe * docs(guide): use real search screenshot * docs(guide): use real node search screenshot * docs(guide): standardize screenshot recipe cards * docs(guide): tighten recipe callout styling * docs: require visual QA for UI work * docs(guide): address pass-2 review nits |
||
|
|
428d4f538b |
chore(nodes): drop Easy_Version + bump 0.1.9 (#41)
Per maintainer direction: Easy_Version was a one-line node that turned
an INT N into the string `vNNN` (zero-padded). The first trivial node
ever written for the pack, never used in production workflows. Removed
to keep the pack's surface focused on the higher-value nodes.
Anyone needing the exact behavior can either inline `f"v{N:03d}"`
downstream of an INT primitive in their workflow, or pull a more
general string-format node from KJ Nodes / ComfyUI-Custom-Scripts.
BREAKING for any saved workflow that references the `Easy_Version` ID
(node will fail to load on import). Same migration shape as the v0.1.5
__koolook_v1_0_1 cleanup.
Also rolls the [Unreleased] PR #39 LATENT-dict-wrap fix into [0.1.9]
so it ships in the same release.
Touched:
- Deleted: k_easy_version.py
- __init__.py: removed version_mappings / version_display imports + merges
- README.md: removed node-table row, Pipeline category list update,
Features bullet, Usage section, Node Code Overview line, install
category list — Easy Version no longer mentioned anywhere
- pyproject.toml: 0.1.8 -> 0.1.9
- CHANGELOG.md: [0.1.9] entry covering the removal + the carried-over
PR #39 fix
Net effect: pack drops from 8 nodes to 7. Koolook/Pipeline subfolder
now has only EasyAIPipeline.
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
b7a17b570b |
chore(categories): split Koolook/VFX into Pipeline / Image / VAE + fix VAE display names (#38)
Three small UX fixes from the v0.1.7 post-release inspection:
1. Categories: the catch-all `Koolook/VFX` subfolder is replaced with
three more granular ones:
- Easy_Version, EasyAIPipeline -> Koolook/Pipeline
- easy_ImageBatch -> Koolook/Image (joins EasyResize)
- Easy_hdr_VAE_encode/decode -> Koolook/VAE
2. Easy_hdr_VAE_encode / Easy_hdr_VAE_decode display names: previously
the display equalled the node ID (`Easy_hdr_VAE_encode`) so the user
couldn't find them by typing `koolook` in the node-add search filter
— they were registered correctly but invisible to the filter. Now:
"Easy_hdr_VAE_encode" -> "Easy HDR VAE Encode (Koolook)"
"Easy_hdr_VAE_decode" -> "Easy HDR VAE Decode (Koolook)"
Matches the title-case " (Koolook)"-suffixed convention used by the
rest of the pack since v0.1.7.
3. README node tables + categories list updated to match.
Class IDs unchanged everywhere -- saved workflows that reference any of
these IDs continue to load and run unchanged. CATEGORY is purely a UI
hint and only affects the node-add menu hierarchy.
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
ee8ccefdf8 |
docs(reorg) + chore: roll [Unreleased] forward + bump 0.1.7 (#37)
Bundles two changes for v0.1.7: 1. PR #36 (already on main, just rolling [Unreleased] -> [0.1.7]): suffix all node display names with " (Koolook)" so they group together in ComfyUI's node-add search. Class IDs unchanged. 2. Docs reorg: - git mv Glossary.md -> docs/reference/glossary.md - git mv RELEASING.md -> docs/maintainers/releasing.md - Three audience buckets under docs/: user_guide/ (end users), reference/ (lookups), maintainers/ (project ops). Each gets a short index README.md. - Top-level docs/README.md as the navigation entry point. - New: docs/maintainers/registry-api.md captures the Comfy Registry undocumented version-management API (deprecate/yank/status enum, auto-deprecation behavior, curl recipes, optional GH Actions workflow YAML for codified mgmt without exposing the token). - New: docs/maintainers/node-versioning.md codifies the rules from the v0.1.5 PR-review discussion for changing INPUT_TYPES / RETURN_TYPES / class names without breaking saved workflows. - Imported the existing untracked docs/ images that the maintainer started locally (node inventory screenshot, Easy Image Batch helper image). - Cross-references updated in README.md, CLAUDE.md, the issue template, and .claude/skills/add-external-fork/SKILL.md. Root drops from 6 -> 4 markdown files. The four that stay (README, LICENSE, CHANGELOG, CLAUDE.md) are the ones that *must* live there for GitHub / Comfy Registry / tooling / Claude Code reasons. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
f57ea38b71 |
feat(EasyResize): rename to EasyResize_Koolook + proper KJ Nodes attribution (#35)
Resolves the genuine `EasyResize` node-ID collision with `ComfyUI-EasyFilePaths` (orange-triangle warning #8 in ComfyUI-Manager). Both packs were registering the bare class name `EasyResize` — load order determined which one a user actually got. Changes: - k_easy_resize.py: - Add SPDX-License-Identifier: GPL-3.0-or-later header. - Add proper attribution block crediting kijai/ComfyUI-KJNodes (Resize Image V2, GPL-3.0) as the original interface inspiration, with a per-feature list of how the Koolook implementation materially extended the surface (aspect-ratio parser, keep_proportion modes, mask + composed outputs, device selection, target/original W/H reporting, color-panel passthrough). - Register both `EasyResize_Koolook` (canonical, new) AND `EasyResize` (deprecated alias) IDs pointing at the same class. Saved workflows using the legacy `EasyResize` ID continue to load and run; new workflows pick `EasyResize_Koolook` from the search and avoid the conflict. - Display name on legacy alias reads `Easy Resize (deprecated, use 'Easy Resize (Koolook)')` to nudge users to switch. - forks/THIRD_PARTY.md: full attribution entry for KJ Nodes (was missing — manifest had it as `license: "unknown"` / `sync_state: "needs-upstream-reference"`). License verified as GPL-3.0 against upstream `LICENSE` file (same as our pack — no relicense pressure). - forks/forks_manifest.yaml: KJ Nodes entry upgraded from `license: "unknown"` to `license: "GPL-3.0"` + `license_verified_at`, `status: "inspired_reimplementation"` (more accurate than `modified`), and the two exposed_node_ids are now recorded explicitly. - README.md: node table, category list, "Easy Resize" section, and Wan-related descriptions all updated to use the new canonical `EasyResize_Koolook` ID and display name. - pyproject.toml: 0.1.5 -> 0.1.6. - CHANGELOG.md: [0.1.6] entry covering the rename + attribution work. Follows the node-versioning rules from the `node-versioning` discussion in PR review: rename via alias, never break saved workflows, document the deprecation in CHANGELOG. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
60e90ec6c8 |
Release v0.1.5: registry hygiene + drop unused v1_0_1 Radiance fork (44 nodes → 8) (#34)
* chore: remove maintainer dev workspaces from git tracking + bump 0.1.4 ComfyUI-Manager was reporting "44 nodes / 13 conflicts" for this pack because the Comfy Registry's static scanner walks every `*.py` in the published archive and reads `NODE_CLASS_MAPPINGS` dicts — including the ones inside vendored third-party clones sitting in two folders that were never meant to be part of the package: upscaler_FIX/github_repos/ComfyUI-SuperUltimateVaceTools/ upscaler_FIX/github_repos/ComfyUI-multigpu/ nuke_CAM_exporter/wrapper_FIX/wrapper_fun_camera_*-code/ nuke_CAM_exporter/_Utils-CAM-track/Github-Repos/... These folders were the maintainer's local debugging / camera-tracking scratchpads, accidentally committed in Dec 2025 commits |
||
|
|
5881e8a808 |
Release v0.1.3: GPL-3.0 relicense, Easy_hdr_VAE_encode/decode (v2.3 fork), license/fork skills (#33)
* chore: relicense to GPL-3.0 and backfill upstream attribution ComfyUI-Koolook v0.1.0 and v0.1.1 shipped under a claimed MIT license while already incorporating GPL-3.0-derived code from fxtdstudios/radiance under forks/radiance_koolook/. GPL-3.0 §5(c) requires the entire combined work to be GPL-3.0 — relicensing the whole package is the simplest honest fix and aligns with the dominant license posture of the ComfyUI custom-node ecosystem. Changes: - Add full GPL-3.0 LICENSE text at repo root (pyproject.toml already referenced LICENSE but the file did not exist). - Update README.md "## License" section to declare GPL-3.0 and explain the §5(c) implication for downstream users. - Backfill forks/THIRD_PARTY.md with full attribution entries for the Radiance v1.0.1 baseline (already in the repo) and the upcoming Radiance v2.3.3 VAE subset (scaffolded in v0.1.2). - Update forks/forks_manifest.yaml: set the existing entry's license field to "GPL-3.0" (was "to_verify_at_source_ref"), add a license_verified_at field, and pre-register the v2.3.3 VAE entry with verified license metadata. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(skills): add license-pre-check + port add-external-fork to .claude/skills/ Two skills to prevent the v0.1.0/v0.1.1 license-incompatibility class of bug from happening again on future forks: - license-pre-check: blocking compatibility audit run BEFORE any code is copied or written based on upstream. Reads the upstream LICENSE, compares against ours via an SPDX matrix, refuses to proceed on incompatible combinations, and records the result for the manifest. - add-external-fork: ports the existing .cursor/skills/add-external-fork procedure to .claude/skills/ so Claude Code can run it directly. The port adds a mandatory Phase 0 ("run license-pre-check first") and expands Phase 3c to require GPL §5(a) modification headers on derived files. The .cursor/ copy is left in place for Cursor users; the two should be kept in sync manually until a unifying mechanism is adopted. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(forks): port v2.3 VAE Encode/Decode as slim video-friendly wrapper Adds forks/radiance_koolook/versions/v2_3_3/ — a slim re-implementation of RadianceVAEEncode / RadianceVAEDecode under the namespace suffix __koolook_v2_3_3. Mirrors the input surface of upstream's RadianceVAE4KEncode / RadianceVAE4KDecode (fxtdstudios/radiance v2.3.3, GPL-3.0) but deliberately skips the 4K cosine-blend tile engine. Why skip the tile engine: that pipeline errors with `size of tensor a (192) must match the size of tensor b (132) at non-singleton dimension 4` when chained into Wan 2.2 video workflows, because the tiler's spatial layout disagrees with the video VAE's internal temporal-aware encoding. Modern video VAEs (Wan 2.2, Hunyuan, CogVideoX, LTX) handle their own internal stitching, so the tiler is redundant and actively breaks the chain. What ships: - forks/radiance_koolook/versions/v2_3_3/nodes_vae.py — RadianceVAEEncode and RadianceVAEDecode classes (~330 lines), rank-agnostic, with a STRING `debug_info` second return that mirrors the pattern from v1's RadianceOCIOColorTransformV2. - forks/radiance_koolook/versions/v2_3_3/__init__.py — applies __koolook_v2_3_3 namespace suffix and " (Koolook v2.3.3)" display suffix, mirroring the v1_0_1 wrapper layout. - forks/radiance_koolook/versions/v2_3_3/UPSTREAM_PIN.yaml — pinned upstream commit f262f47 + license metadata. - forks/radiance_koolook/__init__.py — merges v1_0_1 + v2_3_3 mappings. - pyproject.toml — version bumped to 0.1.2. - CHANGELOG.md — full [0.1.2] entry covering the license relicense, the new v2_3_3 fork, the two new skills, and the carry-over RELEASING.md docs that landed on main since 0.1.1. Existing __koolook_v1_0_1 nodes are unchanged and remain available for backward compatibility with saved workflows. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * refactor(forks/v2_3_3): rename VAE nodes to Easy_hdr_VAE_encode/decode + bump 0.1.3 Per user direction, the new video-friendly VAE wrappers are now exposed under clean Koolook-style IDs and display names — no more `__koolook_v2_3_3` suffix in the ComfyUI node-add UI: - `Easy_hdr_VAE_encode` (was `RadianceVAEEncode__koolook_v2_3_3`) - `Easy_hdr_VAE_decode` (was `RadianceVAEDecode__koolook_v2_3_3`) Why: when both upstream Radiance v2.3.3 and our pack are installed, both expose `Radiance VAE Encode` in the search — the Koolook-suffixed display name still buried "Koolook" at the end of a long line, so users were likely to mis-pick. The new names lead with the Koolook brand and the Easy_* family convention used elsewhere in this pack (Easy_Version, EasyAIPipeline, EasyResize, etc.). Mechanism: new `SKIP_VERSION_SUFFIX = {...}` set in `versions/v2_3_3/__init__.py` opts specific IDs out of the auto-suffix. The version is still tracked structurally (file path) and textually (file header, UPSTREAM_PIN.yaml, forks/THIRD_PARTY.md). Future Koolook-original nodes in this fork can opt out the same way; ports of upstream-named classes still get the suffix by default for collision safety. 0.1.2 was test-published to the registry with the previous IDs but never tagged or formally released; bumping to 0.1.3 publishes the renamed version cleanly. Old 0.1.2 entry retained in CHANGELOG with a "superseded" note for transparency. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
3ad73aac3a |
docs: add RELEASING.md as canonical release procedure (#32)
The v0.1.1 release surfaced two latent gaps: 1. The v0.1.0 tag was on an orphaned merge commit (PR #26 was re-merged), so `git describe --tags` failed and ComfyUI-Manager showed the installed version as "unknown". 2. `[tool.comfy] PublisherId` was the placeholder "CristianP", which does not exist on the Comfy Registry. Every `Publish to Comfy registry` workflow run since at least Feb 2026 failed with the misleading `400 "Failed to validate token"`. Both were the consequence of cutting releases ad-hoc. RELEASING.md codifies the procedure so future releases follow the same path: - pre-release validation - release branch + PR with version bump and CHANGELOG entry - registry publish validated via workflow_dispatch BEFORE merge (catches PublisherId / token / version-conflict errors in PR review) - squash-merge (single commit per release prevents the orphan-tag class) - annotated tag at the squash-merge SHA - GitHub Release from the matching CHANGELOG section - post-release verification (Manager UI + registry status) Also updates the per-release issue template to mirror RELEASING.md, and adds links from README and CLAUDE.md so both humans and agents land on the canonical doc. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
9069560379 |
docs+chore: README sync, sibling-projects pattern, skill, and path-leak cleanup (#27)
Squash of 4 commits from docs/readme-sync-current-nodes. Out of scope (tracked in #28): de-vendor upstream copies under upscaler_FIX/ and nuke_CAM_exporter/. |
||
|
|
52712f05b6 |
Align release references and define clean tagging policy.
Remove stale links to deleted docs, document forward tagging conventions for repo/fork/version namespaces, and keep release checklist aligned with current workflow. Made-with: Cursor |
||
|
|
7f8eda4809 |
Restructure fork tracking and versioned Radiance layout.
Consolidate fork metadata into forks/, move Radiance custom code into versioned folders, and align external reference naming so upgrades and cross-machine parity are easier to manage. Made-with: Cursor |
||
|
|
075ef223e8 | Remove RunPod scaffold from public repo after private migration | ||
|
|
f3f87eba1d | Address PR feedback: lock parsing safety, token auth, and path refs | ||
|
|
29cae9672d | feat(runpod): scaffold reproducible RunPod ComfyUI setup | ||
|
|
7e159780fe | chore: add release workflow and third-party tracking scaffold | ||
|
|
46f78cf7bc | Readme update | ||
|
|
f24db5ce96 | update README | ||
|
|
51dd290912 | add readme |