diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..84e994d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,27 @@ +# ComfyUI-Koolook Codex Instructions + +## Required Project Context + +Read `CLAUDE.md` before making substantive changes. It contains the +project-specific workflow, dev-sync rules, release rules, and sidebar +maintenance notes. + +## Visual QA Is Mandatory For UI Work + +For any change that affects rendered UI, guide pages, screenshots, +CSS/layout, onboarding docs, or browser-visible behavior: + +1. Do not rely on CSS coordinates, source inspection, or user screenshots alone. +2. Open the changed page/app in a browser-rendered environment that Codex can + screenshot. +3. If a `file://` guide page is blocked by browser tooling, serve the repo over + local HTTP instead, for example: + `python3 -m http.server ` from the repo root, then open + `http://127.0.0.1:/...`. +4. Take a rendered screenshot after the change and inspect the actual visual + result before committing or pushing. +5. If visual verification is blocked, say that clearly and do not present the UI + change as ready unless the user explicitly waives visual QA. + +This is especially important for overlays, icon highlights, responsive layout, +text fitting, and visual guide pages. diff --git a/CHANGELOG.md b/CHANGELOG.md index cc12175..2967fd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ The format is inspired by Keep a Changelog and SemVer. ## [Unreleased] ### Added +- **Bundled visual onboarding guide for the Kforge Labs sidebar.** The + existing Tools-row `H` help shortcut now opens `web/guide/index.html`, an + offline visual guide that frames Snapshots as a reusable project kit for + favorite nodes, cross-sidebar search, saved workflows, modules, tags, + autosaves, and starter presets. Its static styling borrows the dark, + token-driven card language from the ForgeFlow sibling project's design docs. + The first version ships annotated mock images under + `web/guide/img/` so they can be replaced by real ComfyUI screenshots later + without changing the guide structure. Linked from the README and user guide + index for users browsing docs outside ComfyUI. - **Subgraph-aware module saves.** Selection saves now carry the transitively referenced `definitions.subgraphs` entries for selected ComfyUI subgraph wrapper nodes, so the saved workflow has the definitions @@ -67,7 +77,16 @@ The format is inspired by Keep a Changelog and SemVer. save now use the approved compact letter / simple-glyph treatment from `docs/designs/sidebar-icon-proposals.html`, reducing repeated generic cloud / grid / floppy symbols while leaving all actions and tooltips - unchanged. Tools now also exposes an `H` help shortcut to the user guide. + unchanged. The existing Tools-row `H` help shortcut is now wired to the + bundled visual onboarding guide. +- **Node help text tightened for scannability.** The Easy Resize description + and HDR VAE encode/decode tooltips now use shorter, action-oriented text so + the ComfyUI node help stays readable while detailed behavior remains in the + user guide. +- **README refocused as a short product front door.** The repo landing page + now leads with the Kforge Labs sidebar, Snapshots, search, workflows, and + recovery, then links out to the deeper user/maintainer/fork docs instead of + carrying long maintainer workflow and implementation sections inline. - **Node-list hover previews now stay at the intended 300px mock-node width.** The preview card previously had only a `min-width` plus viewport `max-width`, so long node descriptions could set the card's intrinsic width and stretch the diff --git a/README.md b/README.md index a1e8909..7920d69 100644 --- a/README.md +++ b/README.md @@ -1,268 +1,86 @@ -# ComfyUI-Koolook-Nodes +# ComfyUI-Koolook -This repository provides custom nodes for ComfyUI tailored for VFX and AI image/video generation workflows. +Kforge Labs for ComfyUI: a project-kit sidebar plus Koolook nodes for VFX, +image, and video workflows. -For change history see [`CHANGELOG.md`](CHANGELOG.md). For workflow conventions and naming see [`CLAUDE.md`](CLAUDE.md) and the [glossary](docs/reference/glossary.md). Full project documentation lives under [`docs/`](docs/). +The main experience is the **Kforge Labs sidebar**. It helps you keep a +project setup together: favorite nodes, saved workflows, reusable modules, +tags, snapshots, and recovery tools. -### Koolook nodes (root package) +## Kforge Labs Sidebar -| Node | Display name | Category | Source | -|------|--------------|----------|--------| -| `EasyWan22Prompt` | Wan 2.2 Easy Prompt (Koolook) | `Koolook/Wan_Video` | `k_easy_wan22_prompt.py` | -| `EasyResize_Koolook` | Easy Resize (Koolook) | `Koolook/Image` | `k_easy_resize.py` | -| `EasyAIPipeline` | Easy AI Pipeline (Koolook) | `Koolook/Pipeline` | `k_ai_pipeline.py` | -| `easy_ImageBatch` | Easy Image Batch (Koolook) | `Koolook/Image` | `k_easy_image_batch.py` | -| `KoolookLoadCameraPosesAbsolute` | Koolook Load Camera Poses (Absolute Path) | `Koolook/Camera` | `k_easy_track.py` | +Use the sidebar as a reusable project kit. -Brief descriptions: +| Feature | What it does | +|---|---| +| **Snapshots** | Save and load the whole Kforge Labs state: favorite nodes, workflows, modules, tags, archive, and recovery data. | +| **Search** | Find nodes, workflows, directories, and tags from one field. Tags keep exact capitalization, so `Depth` and `depth` can be separate folders. | +| **Nodes** | Keep favorite nodes close, grouped by theme or repository name. | +| **Workflows** | Save the whole script, save a selection of nodes, load workflows, or insert saved modules into the current canvas. | +| **Recovery** | Use autosaves, starter presets, snapshot library settings, and missing-pack install helpers. | -- **Wan 2.2 Easy Prompt**: Dynamic prompt builder driven by `config.json` (light source, lighting type, time of day, etc.). Outputs a comma-separated prompt string and optional CLIP conditioning. -- **Easy Resize (Koolook)** — `EasyResize_Koolook`: Aspect-aware image resize that enforces divisibility (e.g., `32`) for model compatibility. Modes: stretch, letterbox, pillarbox; padding and cropping supported. Originally inspired by the `Resize Image V2` node from [kijai/ComfyUI-KJNodes](https://github.com/kijai/ComfyUI-KJNodes) (GPL-3.0 — see [`forks/THIRD_PARTY.md`](forks/THIRD_PARTY.md) for the full attribution + change log). The legacy bare-name `EasyResize` ID is kept as a deprecated alias for saved-workflow compatibility. -- **Easy AI Pipeline**: Aggregates VFX shot parameters (shot duration, seed, base path, shot name, AI method, version) into a fully formatted output file path with overwrite protection. For organized writes from Save EXR / Save Image. -- **Easy Image Batch**: Builds an `IMAGE` + `MASK` batch of length `total_frames` from 1–4 keyframe images placed at explicit frame indices (with `start_frame` offset). Empty frames are filled with black/gray and the mask marks empty=white / occupied=black. Useful for sparse keyframe control with Wan-style video models. -- **Koolook Load Camera Poses (Absolute Path)**: Loads RealEstate10k-style `CAMERACTRL_POSES` from any absolute path (no ComfyUI path stripping), with overrideable pose width/height. Pairs with AnimateDiff CameraCtrl downstream. +New users should start with the bundled visual guide: +[`web/guide/index.html`](web/guide/index.html) -### Radiance Koolook nodes (v2_3_3 fork — video-friendly VAE) +Inside ComfyUI, open it from the Kforge Labs sidebar with **Tools → Info**. -These come from [`forks/radiance_koolook/versions/v2_3_3/`](forks/radiance_koolook/versions/v2_3_3) and load through the root `__init__.py`. They are slim, rank-agnostic re-implementations of the upstream Radiance v2.3.3 VAE encoder/decoder that work correctly with video VAEs (Wan 2.2, Hunyuan, CogVideoX, LTX) — they skip the upstream's 4K cosine-blend tile engine, which conflicts with video VAEs that already handle their own internal stitching. +## Included Nodes | Node ID | Display name | Category | |---|---|---| +| `EasyWan22Prompt` | Wan 2.2 Easy Prompt (Koolook) | `Koolook/Wan_Video` | +| `EasyResize_Koolook` | Easy Resize (Koolook) | `Koolook/Image` | +| `EasyAIPipeline` | Easy AI Pipeline (Koolook) | `Koolook/Pipeline` | +| `easy_ImageBatch` | Easy Image Batch (Koolook) | `Koolook/Image` | +| `KoolookLoadCameraPosesAbsolute` | Koolook Load Camera Poses (Absolute Path) | `Koolook/Camera` | | `Easy_hdr_VAE_encode` | Easy HDR VAE Encode (Koolook) | `Koolook/VAE` | | `Easy_hdr_VAE_decode` | Easy HDR VAE Decode (Koolook) | `Koolook/VAE` | -> **History note:** the v0.1.0–v0.1.4 releases also shipped a much larger `versions/v1_0_1/` fork that wrapped 26 Radiance v1.0 classes (HDR, EXR, OCIO, log curves, etc.) under the `__koolook_v1_0_1` namespace. Those wrappers were vestigial — never used by Koolook authors — and were removed in v0.1.5. Users who want that functionality should install upstream Radiance directly. See [`forks/THIRD_PARTY.md`](forks/THIRD_PARTY.md) for full attribution and removal rationale. +The root Koolook nodes and the slim Radiance Koolook VAE wrappers have no +extra Python dependencies beyond `torch`, which ComfyUI already requires. -See [`forks/README.md`](forks/README.md) for the full fork workflow. +## Install -## Features -- **Dynamic Inputs for Prompts**: Fields and dropdowns in Wan 2.2 Easy Prompt are defined in `config.json`, allowing easy customization without code changes—great for VFX artists iterating on lighting or camera parameters. -- **Image Resizing with Aspect Control**: Easy Resize ensures precise resolutions for AI models, with options for keep_proportion preservation, padding colors, and device selection (CPU/CUDA). Supports masks for compositing in VFX. -- **Pipeline Path Generation**: Easy AI Pipeline assembles VFX-style output paths and filenames from shot/version inputs, with optional version disabling and overwrite protection. -- **Sparse Keyframe Batches**: Easy Image Batch constructs aligned `IMAGE` + `MASK` batches from up to four keyframe images, ready for sparse video-model control. -- **Camera Pose Loading**: Koolook Load Camera Poses (Absolute Path) reads RealEstate10k pose TXT files from any disk location and emits `CAMERACTRL_POSES`. -- **Startup Loading**: Nodes load configurations at ComfyUI launch; edit `config.json` and restart to update. -- **Output Formatting**: Wan 2.2 Easy Prompt outputs comma-separated strings (skipping "none"), compatible with prompt builders. Easy Resize outputs resized images, masks, and width/height integers. -- **Error Handling**: Fallbacks for missing/invalid JSON in Wan 2.2 Easy Prompt; validation for aspect ratios and divisibility in Easy Resize. -- **Compatibility**: Works with ComfyUI-Manager for easy installation via Git URL. The Koolook root nodes and the slim v2_3_3 VAE wrappers have no extra Python dependencies beyond `torch` (already required by ComfyUI itself). +### ComfyUI-Manager -## RunPod +1. Open ComfyUI Manager. +2. Choose **Install Custom Nodes**. +3. Install by Git URL: + `https://github.com/malkuthro/ComfyUI-Koolook.git` +4. Restart ComfyUI. +5. Open the **Kforge Labs** sidebar tab. -RunPod management has been moved to a separate private repository for active operations and iteration. +### Manual -- Runtime/deployment scaffolding is no longer maintained in this public repo. -- This public repo remains focused on the ComfyUI nodes/plugin code. - -## Release & Stability - -For production usage, install a pinned stable tag/commit instead of following moving branch heads. - -- **Release procedure**: [`docs/maintainers/releasing.md`](docs/maintainers/releasing.md) (canonical, step-by-step) -- **Comfy Registry API** (deprecate / yank versions): [`docs/maintainers/registry-api.md`](docs/maintainers/registry-api.md) -- **Node versioning rules** (how to change a node without breaking saved workflows): [`docs/maintainers/node-versioning.md`](docs/maintainers/node-versioning.md) -- Per-release checklist template: [`.github/ISSUE_TEMPLATE/release_checklist.md`](.github/ISSUE_TEMPLATE/release_checklist.md) -- Change history: [`CHANGELOG.md`](CHANGELOG.md) -- Fork tracking: [`forks/THIRD_PARTY.md`](forks/THIRD_PARTY.md), [`forks/forks_manifest.yaml`](forks/forks_manifest.yaml) -- Fork workflow guide: [`forks/README.md`](forks/README.md) - -### Tagging Policy (from now on) - -- Repo releases: `vMAJOR.MINOR.PATCH` (example: `v0.2.0`). -- Fork code versions in paths use underscore format: `v1_0_1`, `v2_3_3`. -- Comfy node ID namespace suffixes match fork version paths: `__koolook_v1_0_1`. -- External raw checkout naming: - - pinned: `-v-koolook` - - rolling upstream: `-main-upstream` - -## Sibling Projects - -Some related work lives in **sibling folders/repositories** outside MAIN. They are *consulted* (read-only knowledge sources, references, etc.) but never imported by MAIN at runtime. To keep the public repo free of machine-specific absolute paths, every sibling is referenced through an environment variable. - -### Conventions - -- Variable prefix: `KOLOOK_*` (matches the existing `KOLOOK_FORKS_DIR`). -- Real paths live in a local, gitignored `.env` file. The committed `.env.example` declares the variable names with placeholder values. -- Public docs and committed code reference siblings only via the env var name (and an optional portable relative default like `../`). Never hardcode an absolute path with a username. -- A sibling project is a *runtime-optional* reference. If the variable is unset and no default is documented, agents/code must treat the sibling as unavailable and continue gracefully. - -### Registered siblings - -| Role | Env var | Portable default | Status | -|------|---------|------------------|--------| -| External forks root (raw upstream clones) | `KOLOOK_FORKS_DIR` | `../ComfyUI-Forks` | documented in `forks/forks_manifest.yaml` | -| ComfyUI knowledge database | `KOLOOK_COMFYUI_KB_DIR` | `../ComfyUI_knowledge___DB` | read-only knowledge source | -| Personal knowledge database | `KOLOOK_PERSONAL_KB_DIR` | *(no default — user-specific)* | optional | - -### Local setup +Clone this repository into `ComfyUI/custom_nodes/`: ```bash -cp .env.example .env -# Edit .env to point at the real paths on your machine. +git clone https://github.com/malkuthro/ComfyUI-Koolook.git ``` -Do **not** commit `.env`. The default `.gitignore` already excludes `.env`, `.env.local`, and `.env.*.local`. +Restart ComfyUI after installation. -## External Fork Workflow (No Vendoring in MAIN) +## Learn More -This repository is the MAIN control repo. Large third-party repositories must stay outside MAIN. +- **Visual sidebar guide:** [`web/guide/index.html`](web/guide/index.html) +- **User guide:** [`docs/user_guide/`](docs/user_guide/) +- **Change history:** [`CHANGELOG.md`](CHANGELOG.md) +- **Maintainer docs:** [`docs/maintainers/`](docs/maintainers/) +- **Fork attribution and provenance:** [`forks/THIRD_PARTY.md`](forks/THIRD_PARTY.md) +- **Versioning reference:** [`docs/reference/versioning.md`](docs/reference/versioning.md) -- Default external forks root (relative): `../ComfyUI-Forks` -- MAIN stores only: - - wrappers under `forks/` - - provenance/tracking under `forks/` -- MAIN does not store full external trees (no vendored copies). +## Stability -### Radiance Koolook Version Layout - -- Package entry path: `forks/radiance_koolook/__init__.py` -- Active version path: `forks/radiance_koolook/versions/v2_3_3/` -- Modified node source is local and tracked in MAIN: - - `forks/radiance_koolook/versions/v2_3_3/nodes_vae.py` -- External checkout is reference-only raw upstream: - - default location: `../ComfyUI-Forks/radiance-v2.3.3-koolook` - - baseline used for comparison: upstream commit `f262f47ddfda01ece154bf80c22769b1e4cef795` (the v2.3.3 release commit; the cleanest tag pointing at it is the typo'd `radinace2.3.3`, so we pin by SHA) -- Node IDs in the v2_3_3 fork are exposed verbatim as `Easy_hdr_VAE_encode` / `Easy_hdr_VAE_decode` (the `__koolook_v2_3_3` namespace suffix is skipped via `SKIP_VERSION_SUFFIX` in `versions/v2_3_3/__init__.py` because the Koolook-specific names already differentiate them from upstream). -- Each version folder should include `UPSTREAM_PIN.yaml` to keep parity with external pinned references. -- The historical `v1_0_1` folder was removed in v0.1.5; see [`forks/THIRD_PARTY.md`](forks/THIRD_PARTY.md). - -### Version Pinning (Portable Across PCs/macOS) - -- Track every external repo in `forks/forks_manifest.yaml` with: - - `source_ref` (tag/version) - - `pinned_commit` (exact hash used in production) - - `external_checkout.relative_path_from_forks_root` -- Keep checkout folder names versioned, e.g.: - - `radiance-v1.0.1-koolook` - - `radiance-v2.3.3-koolook` - -### Machine Setup Example - -From the parent directory that contains `ComfyUI-Koolook`: - -```bash -mkdir -p ../ComfyUI-Forks -cd ../ComfyUI-Forks -git clone https://github.com/fxtdstudios/radiance.git radiance-v1.0.1-koolook -cd radiance-v1.0.1-koolook -git checkout f1b8ae330848fa08aba24c9d3e355cb432d3515b -``` - -This external folder is for upstream comparison/sync work only. - -## Installation -### Via ComfyUI-Manager (Recommended) -1. Open ComfyUI and access the Manager interface. -2. Go to "Install Custom Nodes" > "Install via Git URL". -3. Paste the repository URL: `https://github.com/malkuthro/ComfyUI-Koolook.git`. -4. Install and restart ComfyUI. -5. Nodes appear under these categories in the node search: - - `Koolook/Camera` — Koolook Load Camera Poses (Absolute Path) - - `Koolook/Image` — Easy Resize (Koolook), Easy Image Batch (Koolook) - - `Koolook/Pipeline` — Easy AI Pipeline (Koolook) - - `Koolook/VAE` — Easy HDR VAE Encode/Decode (Koolook) - - `Koolook/Wan_Video` — Wan 2.2 Easy Prompt (Koolook) - -### Manual Installation -1. Clone this repository into your `ComfyUI/custom_nodes/` directory: - ``` - git clone https://github.com/malkuthro/ComfyUI-Koolook.git - ``` -2. Ensure `__init__.py` and `config.json` are in the cloned folder. -3. Restart ComfyUI. - -The root Koolook nodes have no additional Python dependencies. To enable the Radiance Koolook v1.0.1 nodes that handle EXR / OCIO / HDR work, install the optional packages: `OpenEXR`, `Imath`, `PyOpenColorIO`, `colour-science`, `opencv-python`, and `imageio`. - -## Usage - -### Wan 2.2 Easy Prompt -1. Add the "Wan 2.2 Easy Prompt" node to your workflow under "Koolook/Wan_Video". -2. Select options from the dropdowns (e.g., Light Source: "Sunny lighting", Lighting Type: "Soft lighting"). -3. Add custom text in the "body" field for main prompt content. -4. Optionally connect a CLIP for conditioning output. -5. Connect the STRING outputs (combined_prompt or fields_only) to a prompt input, such as the "prompt" slot in the PromptJSON node (from [NeuralSamurAI/ComfyUI-PromptJSON](https://github.com/NeuralSamurAI/ComfyUI-PromptJSON)). -6. To customize fields: - - Edit `config.json` (see example below). - - Restart ComfyUI to apply changes. -7. VFX Tip: Use for generating consistent lighting/shot descriptions in video generation workflows, like with AnimateDiff or SVD. - -#### Example config.json -This is the default configuration based on Wan 2.2 parameters: -```json -{ - "category": "Koolook/Wan_Video", - "node_name": "Wan_2.2", - "fields": [ - { - "name": "light_source", - "type": "combo", - "options": ["none", "Sunny lighting", "Artificial lighting", "Moonlighting", "Practical lighting", "Firelighting", "Fluorescent lighting", "Overcast lighting", "Mixed lighting"], - "default": "none" - }, - { - "name": "lighting_type", - "type": "combo", - "options": ["none", "Soft lighting", "Hard lighting", "Top lighting", "Side lighting", "Underlighting", "Edge lighting", "Silhouette lighting", "Low contrast lighting", "High contrast lighting"], - "default": "none" - }, - // ... (additional fields like time_of_day, shot_size, etc.) - ], - "output_type": "STRING" -} -``` - -### Easy Resize (Koolook) -1. Add the "Easy Resize (Koolook)" node (ID `EasyResize_Koolook`) to your workflow under "Koolook/Image". -2. Connect an IMAGE (and optional MASK) input. -3. Set the base dimension (Width or Height), base size, aspect ratio (e.g., "16:9" for landscape, "9:16" for portrait), and other options like keep_proportion (stretch, letterbox, pillarbox), pad_color (e.g., "0, 0, 0" for black), crop_position, divisible_by, and device. -4. Connect the outputs: IMAGE and MASK for further processing, INT width/height for resolution-aware nodes like samplers or upscalers. -5. VFX Tip: Use for preprocessing footage in multi-resolution pipelines, ensuring divisibility for efficient GPU processing in tools like IPAdapter or ControlNet. - -## Node Code Overview -The core logic is split across files for modularity: - -Root Koolook nodes: -- **k_easy_wan22_prompt.py** — loads `config.json` at import time, builds inputs dynamically (combos for dropdowns, strings for text), and formats selections into prompt strings with optional CLIP conditioning. -- **k_easy_resize.py** — parses aspect ratios, computes divisible dimensions, resizes with `common_upscale`, and handles padding/cropping. Inspired by Resize Image V2 from ComfyUI-KJNodes. -- **k_ai_pipeline.py** — `EasyAIPipeline` builds VFX output paths/filenames from shot/version inputs and creates the output directory. -- **k_easy_image_batch.py** — `easy_ImageBatch` builds aligned `IMAGE`+`MASK` keyframe batches with placeholder fill. -- **k_easy_track.py** — `KoolookLoadCameraPosesAbsolute` loads RealEstate10k pose TXT files from any path. - -Forked/wrapped nodes: -- **forks/radiance_koolook/** — version-namespaced wrapper for the Radiance fork. Currently exposes the `v2_3_3` set; modified node sources live in `forks/radiance_koolook/versions/v2_3_3/nodes_vae.py`. The wrapper supports the `__koolook_vX_Y_Z` ID suffix pattern but lets specific Koolook-named IDs (like `Easy_hdr_VAE_encode/decode`) ship without the suffix via the `SKIP_VERSION_SUFFIX` set. -- **forks/forks_manifest.yaml**, **forks/THIRD_PARTY.md**, **forks/README.md** — fork tracking metadata. - -Glue and frontend: -- **__init__.py** — imports all node packages, merges `NODE_CLASS_MAPPINGS` / `NODE_DISPLAY_NAME_MAPPINGS`, and exposes `WEB_DIRECTORY = "./web"`. -- **web/** — JavaScript extensions loaded by ComfyUI for the Koolook nodes (e.g., `ai_pipeline.js`). - -For advanced customizations (e.g., different output formats or additional resize modes), modify the `execute` or `adjust_to_aspect` methods in the respective files. - -## Troubleshooting -- **ComfyUI Won't Start**: Check console logs for errors (run `python main.py`). Common: Missing `config.json` or invalid JSON—use a validator like jsonlint.com. -- **No Fields Visible in Wan 2.2 Easy Prompt**: Indicates JSON load failure; the node falls back to empty inputs. -- **Errors in Easy Resize**: Ensure aspect ratio is "w:h" format, divisible_by >=1, and pad_color is "r, g, b" floats (0.0-1.0). -- **Updates**: Pull latest from GitHub and restart. - -## Credits -- Based on ComfyUI custom node examples. -- Parameters for Wan 2.2 Easy Prompt derived from Wan 2.2 docs (https://alidocs.dingtalk.com/i/nodes/EpGBa2Lm8aZxe5myC99MelA2WgN7R35y). -- Easy Resize inspired by ComfyUI-KJNodes (https://github.com/kijai/ComfyUI-KJNodes), specifically the Resize Image V2 node in image_nodes.py. -- Compatible with nodes like PromptJSON for LLM workflows. +For production work, install a pinned release tag or commit instead of following +a moving branch head. Node IDs are treated carefully so saved ComfyUI workflows +continue to load across compatible updates. ## License -**GPL-3.0** (see [`LICENSE`](LICENSE)). +**GPL-3.0**. See [`LICENSE`](LICENSE). -This package incorporates and adapts code from -[fxtdstudios/radiance](https://github.com/fxtdstudios/radiance) (also -GPL-3.0) under `forks/radiance_koolook/`. Per GPL-3.0 §5(c), the entire -work is licensed as GPL-3.0. Attribution and per-fork modification notes -are tracked in [`forks/THIRD_PARTY.md`](forks/THIRD_PARTY.md) and +This package incorporates and adapts GPL-3.0 code from +[fxtdstudios/radiance](https://github.com/fxtdstudios/radiance) under +`forks/radiance_koolook/`. Attribution and per-fork modification notes are +tracked in [`forks/THIRD_PARTY.md`](forks/THIRD_PARTY.md) and [`forks/forks_manifest.yaml`](forks/forks_manifest.yaml). - -> **Note for downstream users:** any work that incorporates, links to, or -> derives from `ComfyUI-Koolook` must itself be distributed under GPL-3.0 -> (or a compatible license). If you need a non-copyleft license for any -> piece of this code, contact the maintainers — some Koolook-original -> nodes (those with no upstream Radiance lineage) may be available under -> a more permissive license on request. \ No newline at end of file diff --git a/docs/user_guide/README.md b/docs/user_guide/README.md index 4a2ead4..bd08fb7 100644 --- a/docs/user_guide/README.md +++ b/docs/user_guide/README.md @@ -22,6 +22,8 @@ attribution is visible without needing a fork-shaped directory tree. Pages here cover ideas that span more than one node: +- [Kforge Labs sidebar guide](../../web/guide/index.html) — visual onboarding for + Snapshots, favorite nodes, saved workflows, reusable modules, tags, and recovery. - [VAE encode/decode pairing](nodes/radiance_koolook_v2_3_3/encode_decode_pairing.md) — which encoder fields must match the decoder for a clean roundtrip, with worked examples for SDR / HDR / cinema-log / video workflows. diff --git a/forks/radiance_koolook/versions/v2_3_3/nodes_vae.py b/forks/radiance_koolook/versions/v2_3_3/nodes_vae.py index 7cff95e..a158629 100644 --- a/forks/radiance_koolook/versions/v2_3_3/nodes_vae.py +++ b/forks/radiance_koolook/versions/v2_3_3/nodes_vae.py @@ -103,11 +103,8 @@ class Easy_hdr_VAE_encode: EXTENDED_SOURCE_SPACES, { "default": "Linear", - "tooltip": "Color space of the input pixels. " - "Auto-converted to scene-linear Rec.709 before exposure " - "and HDR processing. Log curves (LogC3, LogC4, S-Log3, " - "V-Log, DaVinci Intermediate, Log3G10) and ACES variants " - "(ACEScg, ACES 2065-1) are decoded properly.", + "tooltip": "Input color space. Converted to scene-linear " + "Rec.709 before exposure and HDR handling.", }, ), }, @@ -119,41 +116,29 @@ class Easy_hdr_VAE_encode: "min": -10.0, "max": 10.0, "step": 0.1, - "tooltip": "Exposure adjustment in stops, applied in " - "linear space (correct semantics regardless of input " - "color space).", + "tooltip": "Exposure in stops, applied after color conversion.", }, ), "alpha_handling": ( ["Preserve", "Ignore"], { "default": "Preserve", - "tooltip": "Preserve: surface input alpha as the third " - "IMAGE output (zeros if input had no alpha). " - "Ignore: always emit zeros for alpha.", + "tooltip": "Preserve input alpha, or emit blank alpha.", }, ), "hdr_mode": ( HDR_MODES, { "default": "Soft Clip", - "tooltip": "How to handle values outside [0,1] before " - "encoding. Clip (SDR): hard clamp. Soft Clip: tanh " - "rolloff above 0.85. Compress (Log): encode through a " - "cinema log curve (uses source_space if it is a log " - "space, otherwise ARRI LogC4) — pairs with the same " - "hdr_mode on decode for HDR-clean roundtrips. " - "Passthrough: no clamp.", + "tooltip": "Out-of-range handling before encode. Match this " + "setting on decode for roundtrips.", }, ), "latent_sampling": ( LATENT_SAMPLING_MODES, { "default": "sample", - "tooltip": "How to sample from the VAE posterior. " - "'sample' is ComfyUI's default (random). 'mean' or " - "'mode' are deterministic — best for img2img where " - "you want minimum reconstruction noise.", + "tooltip": "sample is random; mean/mode are deterministic.", }, ), }, @@ -164,11 +149,8 @@ class Easy_hdr_VAE_encode: FUNCTION = "encode" CATEGORY = "Koolook/VAE" DESCRIPTION = ( - "Encode 32-bit Linear / ACEScg / cinema-log images or image " - "sequences (video) to VAE latents. 12 source spaces, 4 HDR " - "modes, deterministic sampling option, real alpha roundtrip. " - "Skips upstream Radiance's 4K tile engine for compatibility " - "with video VAEs (Wan 2.2, Hunyuan, CogVideoX, LTX)." + "Encode Linear, ACES, or cinema-log images/video to VAE latents. " + "Use matching HDR settings on decode for clean roundtrips." ) def encode( @@ -328,8 +310,7 @@ class Easy_hdr_VAE_decode: EXTENDED_TARGET_SPACES, { "default": "Linear", - "tooltip": "Color space to convert the decoded image into. " - "Same 12 spaces as the encoder.", + "tooltip": "Output color space for the decoded image.", }, ), }, @@ -341,29 +322,21 @@ class Easy_hdr_VAE_decode: "min": -10.0, "max": 10.0, "step": 0.1, - "tooltip": "Exposure adjustment in stops, applied in " - "linear space for correctness.", + "tooltip": "Exposure in stops, applied in linear space.", }, ), "hdr_mode": ( HDR_MODES, { "default": "Clip (SDR)", - "tooltip": "Must match the encode setting. " - "Compress (Log): inverts log-curve encoding with " - "soft-shoulder + log-space highlight denoise for " - "clean HDR output. Soft Clip / Passthrough: extended " - "sRGB EOTF. Clip (SDR): standard sRGB EOTF.", + "tooltip": "Match the encode HDR mode for roundtrips.", }, ), "source_space": ( EXTENDED_SOURCE_SPACES, { "default": "Linear", - "tooltip": "Only used with hdr_mode='Compress (Log)' " - "to identify which log curve was used at encode. " - "Set this to whatever you set source_space to on " - "the encoder. Ignored for other hdr_modes.", + "tooltip": "For Compress (Log), match the encoder source_space.", }, ), }, @@ -374,11 +347,8 @@ class Easy_hdr_VAE_decode: FUNCTION = "decode" CATEGORY = "Koolook/VAE" DESCRIPTION = ( - "Decode VAE latents (image or video) directly to 32-bit " - "Linear / ACEScg / cinema-log images. 12 target spaces, " - "Compress (Log) HDR pipeline with soft-shoulder + log denoise. " - "Rank-agnostic — works with whatever tensor shape the underlying " - "VAE returns." + "Decode image or video VAE latents to Linear, ACES, or cinema-log " + "images. Match encode HDR settings for clean roundtrips." ) def decode( diff --git a/k_easy_resize.py b/k_easy_resize.py index 2e4c209..f1b5994 100644 --- a/k_easy_resize.py +++ b/k_easy_resize.py @@ -52,15 +52,9 @@ class EasyResize: FUNCTION = "adjust_to_aspect" CATEGORY = "Koolook/Image" DESCRIPTION = """ -Adjusts the input image to a target resolution based on a base dimension (width or height), -an aspect ratio (e.g., '16:9' for landscape, '9:16' for portrait), ensuring both dimensions -are divisible by the specified value. Supports stretch or pad/crop modes for proportion control. -Outputs the resized image, optional mask, and final width/height for VFX pipeline integration. -Also outputs a solid color panel (canvas) of the target size using the specified panel_color_mode and optional custom panel_color. -When selecting 'Custom' for pad_color_mode or panel_color_mode, enter the color in the corresponding field as comma-separated floats, e.g., '0.5, 0.5, 0.5' for gray. -The 'composed_IMAGE' is the resized image composited onto the color panel using the mask (if provided; falls back to resized image if no mask). -If 'invert_composed_MASK' is enabled, the composed_IMAGE will use an inverted mask for compositing (swapping the roles of image and panel). -The 'inverted_MASK' is the inverted version of the mask (if provided). +Resize an image to a target aspect ratio and model-friendly divisible size. +Use stretch, letterbox, or pillarbox; optional masks can produce a composed +image, inverted mask, color panel, and final/original size outputs. """ def adjust_to_aspect(self, image, base_on, base_size, aspect_ratio, upscale_method, keep_proportion, pad_color_mode, crop_position, divisible_by, device, panel_color_mode, mask=None, pad_color="0, 0, 0", panel_color="0, 0, 0", invert_composed_MASK=False): @@ -248,4 +242,4 @@ NODE_CLASS_MAPPINGS = { NODE_DISPLAY_NAME_MAPPINGS = { "EasyResize_Koolook": "Easy Resize (Koolook)", "EasyResize": "Easy Resize (deprecated, use 'Easy Resize (Koolook)')", -} \ No newline at end of file +} diff --git a/web/guide/guide.css b/web/guide/guide.css new file mode 100644 index 0000000..e97e43e --- /dev/null +++ b/web/guide/guide.css @@ -0,0 +1,525 @@ +/* SPDX-FileCopyrightText: 2025-2026 Kforge Labs */ +/* SPDX-License-Identifier: GPL-3.0-only */ + +:root { + color-scheme: dark; + /* ForgeFlow-inspired static guide skin. + Source reference: ../ForgeFlow/docs/UI_DESIGN_SYSTEM.md */ + --bg: #0e0e0e; + --panel: #151515; + --panel-2: #1a1a1f; + --titlebar: #24242c; + --text: #f9fafb; + --muted: #707982; + --muted-deep: #4d535d; + --line: #302f2f; + --blue: #4268ba; + --sky: #052f4a; + --sky-hover: #1a6d94; + --green: #4a8058; + --amber: #461901; + --purple: #452e83; + --pink: #77234d; +} + +* { + box-sizing: border-box; +} + +body { + margin: 0; + min-width: 320px; + background: + radial-gradient(rgba(150, 150, 150, 0.08) 1px, transparent 1px), + var(--bg); + background-size: 13px 13px; + color: var(--text); + font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + line-height: 1.5; + -webkit-font-smoothing: antialiased; +} + +.hero, +main { + width: min(1180px, calc(100% - 32px)); + margin: 0 auto; +} + +.hero { + padding: 48px 0 24px; +} + +.eyebrow { + margin: 0 0 8px; + color: var(--blue); + font-size: 12px; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +h1, +h2, +h3, +p { + margin-top: 0; +} + +h1 { + max-width: 780px; + margin-bottom: 14px; + font-size: clamp(34px, 7vw, 68px); + line-height: 1; + letter-spacing: 0; +} + +h2 { + margin-bottom: 12px; + font-size: clamp(27px, 4vw, 42px); + line-height: 1.05; + letter-spacing: 0; +} + +h3 { + margin-bottom: 8px; + font-size: 18px; + letter-spacing: 0; +} + +.lead { + max-width: 700px; + color: var(--muted); + font-size: 19px; +} + +.section { + display: grid; + grid-template-columns: minmax(240px, 0.82fr) minmax(0, 1.18fr); + gap: 28px; + align-items: center; + padding: 34px 0; +} + +.section-copy { + max-width: 440px; + padding-left: 16px; + border-left: 4px solid var(--blue); +} + +.section-copy.wide { + max-width: 720px; + grid-column: 1 / -1; +} + +.section-copy p, +.band > p, +.cards p, +figcaption { + color: var(--muted); +} + +.visual { + margin: 0; +} + +.visual img { + display: block; + width: 100%; + height: auto; + border: 1px solid var(--line); + background: var(--panel); + border-radius: 8px; +} + +.overview-map { + display: grid; + grid-template-columns: minmax(240px, 0.78fr) minmax(220px, 0.72fr); + gap: 48px; + align-items: center; + padding: 22px 28px 22px 22px; + border: 1px solid var(--line); + border-radius: 8px; + background: #101010; +} + +.overview-shot { + position: relative; + width: min(100%, 450px); + margin: 0 auto; + overflow: visible; +} + +.overview-shot img { + border-color: #3c3c3c; + background: #151515; +} + +.overview-box { + position: absolute; + right: -18px; + width: 4px; + border: 0; + border-radius: 999px; + background: currentColor; + opacity: 0.78; + pointer-events: none; +} + +.overview-box::after { + content: none; +} + +.overview-snapshot { + top: 1.8%; + height: 6.8%; + color: #4a8058; +} + +.overview-tools { + top: 9.7%; + height: 6.4%; + color: #4268ba; +} + +.overview-search { + top: 17.8%; + height: 5.6%; + color: #d59b3d; +} + +.overview-nodes { + top: 26.2%; + height: 8.2%; + color: #b64747; +} + +.overview-workflows { + top: 34.9%; + height: 8%; + color: #452e83; +} + +.overview-saved { + top: 43.5%; + height: 51.8%; + color: #4a8058; +} + +.overview-callouts { + display: grid; + gap: 22px; +} + +.overview-callout { + position: relative; + padding-left: 18px; + color: var(--blue); +} + +.overview-callout::before { + content: ""; + position: absolute; + top: 4px; + bottom: 4px; + left: 0; + width: 4px; + border-radius: 999px; + background: currentColor; + opacity: 0.82; +} + +.overview-callout::after { + content: none; +} + +.overview-callout h3 { + margin: 0 0 2px; + color: currentColor; + font-size: 20px; +} + +.overview-callout p { + margin: 0; + color: var(--muted); + font-size: 14px; +} + +.overview-callout.snapshot::before, +.overview-callout.saved::before, +.overview-callout.snapshot, +.overview-callout.saved { + color: var(--green); +} + +.overview-callout.tools { + color: var(--blue); +} + +.overview-callout.search { + color: #d59b3d; +} + +.overview-callout.nodes { + color: #b64747; +} + +.overview-callout.workflows { + color: var(--purple); +} + +figcaption { + margin-top: 10px; + color: var(--muted); + font-size: 13px; +} + +.band { + margin: 28px 0; + padding: 0; + border: 1px solid var(--line); + border-radius: 6px; + background: var(--panel); + overflow: hidden; +} + +.band > div { + position: relative; + padding: 16px 22px; + background: var(--panel); + border-bottom: 1px solid var(--line); +} + +.band > div::before { + content: ""; + position: absolute; + inset: 0 auto 0 0; + width: 4px; + background: var(--green); +} + +.band > p { + max-width: 760px; + padding: 18px 22px 0; + font-size: 17px; +} + +.full { + margin: 18px 22px 22px; +} + +.steps { + margin: 0; + padding-left: 20px; + color: var(--muted); +} + +.steps li { + margin-bottom: 9px; +} + +.steps strong { + color: var(--text); + font-weight: 650; +} + +.cards { + display: grid; + grid-template-columns: repeat(5, minmax(0, 1fr)); + gap: 12px; + padding: 30px 0; +} + +.cards article { + position: relative; + min-height: 142px; + padding: 18px 16px 16px 20px; + border: 1px solid var(--line); + border-radius: 6px; + background: var(--panel); + overflow: hidden; +} + +.cards article::before { + content: ""; + position: absolute; + inset: 0 auto 0 0; + width: 4px; + background: var(--blue); +} + +.cards article:nth-child(2)::before { + background: var(--sky-hover); +} + +.cards article:nth-child(3)::before { + background: var(--purple); +} + +.cards article:nth-child(4)::before { + background: var(--green); +} + +.cards article:nth-child(5)::before { + background: var(--pink); +} + +.function-list { + display: flex; + flex-wrap: wrap; + gap: 7px; + margin-top: 14px; +} + +.function-list span { + display: inline-flex; + align-items: center; + min-height: 28px; + padding: 4px 8px; + border: 1px solid #3d3d3d; + border-radius: 4px; + background: #1a1a1f; + color: var(--text); + font-size: 12px; + font-weight: 700; + line-height: 1.2; +} + +.recipes { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 18px; + padding: 34px 0 64px; +} + +.recipe-real { + padding: 14px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--panel); +} + +.recipe-real img { + border-color: #454545; + background: #101010; +} + +.recipe-shot { + position: relative; +} + +.focus-dot { + position: absolute; + width: 72px; + height: 72px; + border-radius: 999px; + background: rgb(66 104 186 / 30%); + box-shadow: 0 0 0 2px rgb(66 104 186 / 88%); + pointer-events: none; +} + +.focus-save { + right: 3%; + bottom: 7%; +} + +.focus-load { + left: 7%; + top: 39%; +} + +.focus-module { + right: 0.5%; + bottom: 0.5%; + background: rgb(201 148 75 / 30%); + box-shadow: 0 0 0 2px rgb(201 148 75 / 88%); +} + +.focus-node-search { + left: 12%; + top: 19%; + background: rgb(74 128 88 / 30%); + box-shadow: 0 0 0 2px rgb(74 128 88 / 88%); +} + +.focus-workflow-search { + left: 10%; + top: 16%; + background: rgb(69 46 131 / 30%); + box-shadow: 0 0 0 2px rgb(69 46 131 / 88%); +} + +.recipe-callout { + width: fit-content; + max-width: min(520px, calc(100% - 44px)); + margin: 18px auto 0; + padding: 14px 18px 14px 22px; + border-left: 5px solid var(--blue); + border-radius: 8px; + background: #111111; + box-shadow: 0 14px 30px rgb(0 0 0 / 26%); +} + +.recipe-callout p { + margin: 0; + color: var(--muted); + font-size: 17px; + line-height: 1.55; +} + +.recipe-callout strong { + color: var(--text); + font-size: 18px; + font-weight: 800; +} + +.recipe-callout.amber { + border-left-color: #c9944b; +} + +.recipe-callout.green { + border-left-color: var(--green); +} + +.recipe-callout.purple { + border-left-color: var(--purple); +} + +@media (max-width: 980px) { + .cards { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} + +@media (max-width: 860px) { + .section, + .recipes { + grid-template-columns: 1fr; + } + + .overview-map { + grid-template-columns: 1fr; + } + + .cards article { + min-height: 0; + } +} + +@media (max-width: 520px) { + .hero, + main { + width: min(100% - 20px, 1180px); + } + + .hero { + padding-top: 34px; + } + + .band { + padding: 18px; + } + + .cards { + grid-template-columns: 1fr; + } +} diff --git a/web/guide/img/autosave-recovery.svg b/web/guide/img/autosave-recovery.svg new file mode 100644 index 0000000..faef066 --- /dev/null +++ b/web/guide/img/autosave-recovery.svg @@ -0,0 +1,26 @@ + + Autosave recovery recipe + Annotated mock screenshot for recovering from autosaves. + + + + Load Snapshot + + Client_Shot010 + + Lookdev_HDR + AUTOSAVES + + _autosave_periodic_01 + + + + Recover safely + Autosaves are kept in the + same Snapshot library. + Load one if state was lost. + + Library folder + Set it per project or facility. + + diff --git a/web/guide/img/project-workflow.svg b/web/guide/img/project-workflow.svg new file mode 100644 index 0000000..1b6dd68 --- /dev/null +++ b/web/guide/img/project-workflow.svg @@ -0,0 +1,18 @@ + + Project workflow + Six step workflow for using snapshots and modules. + + + PROJECT RHYTHM + Use one snapshot per project context. + + 1Load or create Client_Shot010. + 2Add favorite nodes while building. + 3Save reusable clusters as modules. + 4Quick Save during the session. + 5Save named snapshots by shot or task. + 6Load the right kit when you return. + + + + diff --git a/web/guide/img/screenshots/all-icons-new.png b/web/guide/img/screenshots/all-icons-new.png new file mode 100644 index 0000000..128629b Binary files /dev/null and b/web/guide/img/screenshots/all-icons-new.png differ diff --git a/web/guide/img/screenshots/load-snapshot.png b/web/guide/img/screenshots/load-snapshot.png new file mode 100644 index 0000000..3f4b23b Binary files /dev/null and b/web/guide/img/screenshots/load-snapshot.png differ diff --git a/web/guide/img/screenshots/save-snapshot.png b/web/guide/img/screenshots/save-snapshot.png new file mode 100644 index 0000000..8084c75 Binary files /dev/null and b/web/guide/img/screenshots/save-snapshot.png differ diff --git a/web/guide/img/screenshots/search-B.png b/web/guide/img/screenshots/search-B.png new file mode 100644 index 0000000..1a953e6 Binary files /dev/null and b/web/guide/img/screenshots/search-B.png differ diff --git a/web/guide/img/screenshots/search-C.png b/web/guide/img/screenshots/search-C.png new file mode 100644 index 0000000..3a16464 Binary files /dev/null and b/web/guide/img/screenshots/search-C.png differ diff --git a/web/guide/img/screenshots/sidebar-overview.png b/web/guide/img/screenshots/sidebar-overview.png new file mode 100644 index 0000000..e9cb577 Binary files /dev/null and b/web/guide/img/screenshots/sidebar-overview.png differ diff --git a/web/guide/img/snapshot-flow.svg b/web/guide/img/snapshot-flow.svg new file mode 100644 index 0000000..0b57ebe --- /dev/null +++ b/web/guide/img/snapshot-flow.svg @@ -0,0 +1,37 @@ + + Snapshot mental model + Sidebar state becomes a snapshot file in a library, then can be loaded later. + + + MENTAL MODEL + Snapshot saves the whole project kit. + + + Sidebar state + favorite nodes + workflows / modules + tags + + + + + + Snapshot file + Client_Shot010 + portable JSON + saved on disk + + + + + + Project library + one folder for a show + or one per client + load it later + + + + Return to the project without rebuilding your setup + + diff --git a/web/guide/index.html b/web/guide/index.html new file mode 100644 index 0000000..27941f7 --- /dev/null +++ b/web/guide/index.html @@ -0,0 +1,214 @@ + + + + + + + Kforge Labs Sidebar Guide + + + +
+

Kforge Labs

+

Use the sidebar as a project kit.

+

Save the nodes, modules, workflows, tags, and snapshot state you need for a project, then load that setup again when the work comes back.

+
+ +
+
+
+

Start here

+

The sidebar has six main areas.

+

Snapshot, Tools, Search, Nodes, Workflows, and saved lists work together to keep each project kit easy to save, find, and reload.

+
+
+
+
+ Kforge Labs sidebar overview screenshot + + + + + + +
+
+
+

Snapshot row

+

Load, Quick Save, Save, Settings.

+
+
+

Tools row

+

Maintenance plus the Help guide.

+
+ +
+

Nodes action bar

+

Switch tree or list view, then add a favorite node.

+
+
+

Workflows action bar

+

Save the canvas or selected nodes, then browse saved workflows.

+
+
+

Saved lists

+

Nodes, Workflows, and Tags stay visible below.

+
+
+
+
First read the sidebar from top to bottom: Snapshot, Tools, Search, Nodes, Workflows, Tags.
+
+
+ +
+
+

Most important idea

+

Snapshot = your project kit

+
+

A Snapshot saves Kforge Labs state: favorite nodes, saved workflows, modules, tags, archive, and the current sidebar organization. Use one named snapshot per project, shot, client, or experiment.

+
+ Snapshot flow from sidebar state to saved file to project library and later reload +
+
+ +
+
+

Project rhythm

+

A simple workflow

+
    +
  1. Load or create a snapshot, for example Client_Shot010.
  2. +
  3. Add favorite nodes while building the shot.
  4. +
  5. Save reusable node clusters as modules.
  6. +
  7. Quick Save during the session.
  8. +
  9. Save named snapshots for each project, shot, or task.
  10. +
  11. Load the right snapshot when you return.
  12. +
+
+
+ Six step project workflow for snapshots and modules +
The goal is not to remember every button. The goal is to keep each project setup reusable.
+
+
+ +
+
+

Snapshots

+

Save and reload the whole project kit.

+
+ Load + Quick Save + Save + Settings +
+
+
+

Nodes

+

Keep favorite nodes organized and easy to update.

+
+ Search + Add + Remove + Group +
+
+
+

Search

+

Find saved work from one field. Tags keep exact capitalization.

+
+ Nodes + Workflows + Folders + Tags +
+
+
+

Workflows

+

Save full scripts or reusable node selections.

+
+ Save script + Save selection + Load + Insert module +
+
+
+

Safety / setup

+

Quiet helpers protect projects and make saved kits portable.

+
+ Autosaves + Missing packs + Starter preset + Library folder +
+
+
+ +
+
+

Visual recipes

+

Common things you will do

+
+
+
+ Save snapshot dialog showing library folder and save options + +
+
+

Save updates the current project kit. Save as new creates another named snapshot.

+
+
Save the current sidebar state as a named project snapshot.
+
+
+
+ Load snapshot dialog showing saved snapshots and recovery autosaves + +
+
+

Snapshot row restores that saved project kit. Recovery auto-saves are available below saved snapshots.

+
+
Load a snapshot when you switch projects or return to a shot.
+
+
+
+ Sidebar toolbar screenshot with workflow save-selection highlighted + +
+
+

Workflow save-selection is the bottom-right workflow action. Use it after selecting nodes on the canvas.

+
+
Save selected nodes as a module, then insert that module into another canvas.
+
+
+
+ Search results showing matching favorite nodes + +
+
+

Node search narrows favorites so useful nodes are easier to scan and add.

+
+
Search narrows the Nodes list so useful favorites are easier to scan and add.
+
+
+
+ Search results showing matching nodes and workflows + +
+
+

One search field finds nodes and workflows, including saved workflows found through tags.

+
+
Search finds both nodes and workflows from the same field, including saved workflows found through tags.
+
+
+ Annotated mockup showing autosave recovery +
If something goes sideways, load an autosave from the Snapshot Load dialog.
+
+
+
+ + diff --git a/web/sidebar/constants.js b/web/sidebar/constants.js index 85caa33..c995c5f 100644 --- a/web/sidebar/constants.js +++ b/web/sidebar/constants.js @@ -79,6 +79,7 @@ export const WORKFLOWS_FALLBACK_KEY = "koolook.workflows.fallback.v1"; export const WORKFLOWS_SEEDED_KEY = "koolook.workflows.seeded.v1"; export const WORKFLOWS_CHANGED_EVENT = "koolook-workflows-changed"; export const WORKFLOWS_DEFAULTS_URL = new URL("../workflow_defaults.json", import.meta.url).href; +export const GUIDE_URL = new URL("../guide/index.html", import.meta.url).href; // Convention-driven "module" classification — a saved workflow tagged with // this literal string is treated as a reusable building block (insert into diff --git a/web/sidebar/tree.js b/web/sidebar/tree.js index b42a108..632684d 100644 --- a/web/sidebar/tree.js +++ b/web/sidebar/tree.js @@ -23,6 +23,7 @@ import { GROUP_MODE_KEY, GROUP_MODE_DEFAULT, MODULE_TAG, + GUIDE_URL, ensureStyle, toast, compareNames, @@ -118,8 +119,6 @@ const SECTION_ID_WORKFLOWS = "workflows"; const SECTION_ID_TAGS = "tags"; const SVG_NS = "http://www.w3.org/2000/svg"; -const HELP_URL = "https://github.com/malkuthro/ComfyUI-Koolook/tree/main/docs/user_guide"; - const TOOLBAR_ICONS = { loadSnapshot: { kind: "letter", text: "L" }, saveSnapshot: { kind: "letter", text: "S" }, @@ -2452,8 +2451,13 @@ export function renderPanel(container) { toolsRow.appendChild(makeToolbarButton({ icon: TOOLBAR_ICONS.help, - title: "Open Kforge Labs user guide", - onClick: () => window.open(HELP_URL, "_blank", "noopener,noreferrer"), + title: "Open the Kforge Labs visual guide", + onClick: () => { + const opened = window.open(GUIDE_URL, "_blank", "noopener,noreferrer"); + if (!opened) { + toast("Could not open the guide. Allow pop-ups for this page, then try again."); + } + }, })); container.appendChild(toolsRow);