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
@@ -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 <port>` from the repo root, then open
|
||||
`http://127.0.0.1:<port>/...`.
|
||||
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.
|
||||
@@ -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
|
||||
|
||||
@@ -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: `<repo>-v<version>-koolook`
|
||||
- rolling upstream: `<repo>-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 `../<folder>`). 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.
|
||||
@@ -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.
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)')",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,525 @@
|
||||
/* SPDX-FileCopyrightText: 2025-2026 Kforge Labs <https://github.com/malkuthro/ComfyUI-Koolook> */
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="600" viewBox="0 0 900 600" role="img" aria-labelledby="title desc">
|
||||
<title id="title">Autosave recovery recipe</title>
|
||||
<desc id="desc">Annotated mock screenshot for recovering from autosaves.</desc>
|
||||
<rect width="900" height="600" fill="#131315"/>
|
||||
<g font-family="Arial, sans-serif">
|
||||
<rect x="82" y="92" width="300" height="396" rx="18" fill="#151515" stroke="#302f2f"/>
|
||||
<text x="112" y="136" fill="#f9fafb" font-size="24" font-weight="700">Load Snapshot</text>
|
||||
<rect x="112" y="176" width="240" height="52" rx="9" fill="#0e0e0e" stroke="#302f2f"/>
|
||||
<text x="136" y="209" fill="#f9fafb" font-size="16">Client_Shot010</text>
|
||||
<rect x="112" y="246" width="240" height="52" rx="9" fill="#0e0e0e" stroke="#302f2f"/>
|
||||
<text x="136" y="279" fill="#f9fafb" font-size="16">Lookdev_HDR</text>
|
||||
<text x="112" y="348" fill="#4268ba" font-size="15" font-weight="700">AUTOSAVES</text>
|
||||
<rect x="112" y="368" width="240" height="52" rx="9" fill="#162556" stroke="#4268ba"/>
|
||||
<text x="136" y="401" fill="#f9fafb" font-size="15">_autosave_periodic_01</text>
|
||||
<path d="M352 394 H548" stroke="#4268ba" stroke-width="4"/>
|
||||
<path d="M548 394 l-18 -12 v24 z" fill="#4268ba"/>
|
||||
<rect x="574" y="296" width="250" height="172" rx="16" fill="#1a1a1f" stroke="#4268ba"/>
|
||||
<text x="602" y="342" fill="#f9fafb" font-size="25" font-weight="700">Recover safely</text>
|
||||
<text x="602" y="384" fill="#707982" font-size="17">Autosaves are kept in the</text>
|
||||
<text x="602" y="410" fill="#707982" font-size="17">same Snapshot library.</text>
|
||||
<text x="602" y="436" fill="#707982" font-size="17">Load one if state was lost.</text>
|
||||
<rect x="574" y="114" width="250" height="122" rx="16" fill="#1a1a1f" stroke="#c9944b"/>
|
||||
<text x="602" y="160" fill="#f9fafb" font-size="25" font-weight="700">Library folder</text>
|
||||
<text x="602" y="202" fill="#707982" font-size="17">Set it per project or facility.</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,18 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="760" height="640" viewBox="0 0 760 640" role="img" aria-labelledby="title desc">
|
||||
<title id="title">Project workflow</title>
|
||||
<desc id="desc">Six step workflow for using snapshots and modules.</desc>
|
||||
<rect width="760" height="640" fill="#151515"/>
|
||||
<g font-family="Arial, sans-serif">
|
||||
<text x="56" y="62" fill="#4268ba" font-size="15" font-weight="700" letter-spacing="2">PROJECT RHYTHM</text>
|
||||
<text x="56" y="106" fill="#f9fafb" font-size="32" font-weight="700">Use one snapshot per project context.</text>
|
||||
<g transform="translate(56 150)" fill="#707982" font-size="18">
|
||||
<circle cx="26" cy="30" r="24" fill="#4268ba"/><text x="20" y="37" fill="#0e0e0e" font-weight="700">1</text><text x="74" y="37" fill="#f9fafb">Load or create Client_Shot010.</text>
|
||||
<circle cx="26" cy="110" r="24" fill="#4a8058"/><text x="20" y="117" fill="#0e0e0e" font-weight="700">2</text><text x="74" y="117" fill="#f9fafb">Add favorite nodes while building.</text>
|
||||
<circle cx="26" cy="190" r="24" fill="#c9944b"/><text x="20" y="197" fill="#0e0e0e" font-weight="700">3</text><text x="74" y="197" fill="#f9fafb">Save reusable clusters as modules.</text>
|
||||
<circle cx="26" cy="270" r="24" fill="#452e83"/><text x="20" y="277" fill="#0e0e0e" font-weight="700">4</text><text x="74" y="277" fill="#f9fafb">Quick Save during the session.</text>
|
||||
<circle cx="26" cy="350" r="24" fill="#a04040"/><text x="20" y="357" fill="#0e0e0e" font-weight="700">5</text><text x="74" y="357" fill="#f9fafb">Save named snapshots by shot or task.</text>
|
||||
<circle cx="26" cy="430" r="24" fill="#4a8058"/><text x="20" y="437" fill="#0e0e0e" font-weight="700">6</text><text x="74" y="437" fill="#f9fafb">Load the right kit when you return.</text>
|
||||
<path d="M26 55 V85 M26 135 V165 M26 215 V245 M26 295 V325 M26 375 V405" stroke="#302f2f" stroke-width="4"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 80 KiB |
@@ -0,0 +1,37 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="520" viewBox="0 0 1200 520" role="img" aria-labelledby="title desc">
|
||||
<title id="title">Snapshot mental model</title>
|
||||
<desc id="desc">Sidebar state becomes a snapshot file in a library, then can be loaded later.</desc>
|
||||
<rect width="1200" height="520" fill="#131315"/>
|
||||
<g font-family="Arial, sans-serif">
|
||||
<text x="60" y="72" fill="#4268ba" font-size="17" font-weight="700" letter-spacing="2">MENTAL MODEL</text>
|
||||
<text x="60" y="116" fill="#f9fafb" font-size="34" font-weight="700">Snapshot saves the whole project kit.</text>
|
||||
<g transform="translate(72 178)">
|
||||
<rect width="210" height="190" rx="16" fill="#1a1a1f" stroke="#302f2f"/>
|
||||
<text x="24" y="42" fill="#f9fafb" font-size="22" font-weight="700">Sidebar state</text>
|
||||
<text x="24" y="82" fill="#707982" font-size="16">favorite nodes</text>
|
||||
<text x="24" y="112" fill="#707982" font-size="16">workflows / modules</text>
|
||||
<text x="24" y="142" fill="#707982" font-size="16">tags</text>
|
||||
</g>
|
||||
<path d="M306 273 H430" stroke="#4268ba" stroke-width="4"/>
|
||||
<path d="M430 273 l-18 -12 v24 z" fill="#4268ba"/>
|
||||
<g transform="translate(456 178)">
|
||||
<rect width="210" height="190" rx="16" fill="#162556" stroke="#4268ba"/>
|
||||
<text x="24" y="42" fill="#f9fafb" font-size="22" font-weight="700">Snapshot file</text>
|
||||
<text x="24" y="82" fill="#707982" font-size="16">Client_Shot010</text>
|
||||
<text x="24" y="112" fill="#707982" font-size="16">portable JSON</text>
|
||||
<text x="24" y="142" fill="#707982" font-size="16">saved on disk</text>
|
||||
</g>
|
||||
<path d="M690 273 H814" stroke="#4a8058" stroke-width="4"/>
|
||||
<path d="M814 273 l-18 -12 v24 z" fill="#4a8058"/>
|
||||
<g transform="translate(840 178)">
|
||||
<rect width="260" height="190" rx="16" fill="#1a1a1f" stroke="#302f2f"/>
|
||||
<text x="24" y="42" fill="#f9fafb" font-size="22" font-weight="700">Project library</text>
|
||||
<text x="24" y="82" fill="#707982" font-size="16">one folder for a show</text>
|
||||
<text x="24" y="112" fill="#707982" font-size="16">or one per client</text>
|
||||
<text x="24" y="142" fill="#707982" font-size="16">load it later</text>
|
||||
</g>
|
||||
<path d="M970 388 V432 H177 V392" fill="none" stroke="#c9944b" stroke-width="4"/>
|
||||
<path d="M177 392 l-12 18 h24 z" fill="#c9944b"/>
|
||||
<text x="418" y="462" fill="#c9944b" font-size="19" font-weight="700">Return to the project without rebuilding your setup</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,214 @@
|
||||
<!--
|
||||
SPDX-FileCopyrightText: 2025-2026 Kforge Labs <https://github.com/malkuthro/ComfyUI-Koolook>
|
||||
SPDX-License-Identifier: GPL-3.0-only
|
||||
-->
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Kforge Labs Sidebar Guide</title>
|
||||
<link rel="stylesheet" href="./guide.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="hero">
|
||||
<p class="eyebrow">Kforge Labs</p>
|
||||
<h1>Use the sidebar as a project kit.</h1>
|
||||
<p class="lead">Save the nodes, modules, workflows, tags, and snapshot state you need for a project, then load that setup again when the work comes back.</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section class="section">
|
||||
<div class="section-copy">
|
||||
<p class="eyebrow">Start here</p>
|
||||
<h2>The sidebar has six main areas.</h2>
|
||||
<p>Snapshot, Tools, Search, Nodes, Workflows, and saved lists work together to keep each project kit easy to save, find, and reload.</p>
|
||||
</div>
|
||||
<figure class="visual">
|
||||
<div class="overview-map">
|
||||
<div class="overview-shot">
|
||||
<img src="./img/screenshots/sidebar-overview.png" alt="Kforge Labs sidebar overview screenshot">
|
||||
<span class="overview-box overview-snapshot" aria-hidden="true"></span>
|
||||
<span class="overview-box overview-tools" aria-hidden="true"></span>
|
||||
<span class="overview-box overview-search" aria-hidden="true"></span>
|
||||
<span class="overview-box overview-nodes" aria-hidden="true"></span>
|
||||
<span class="overview-box overview-workflows" aria-hidden="true"></span>
|
||||
<span class="overview-box overview-saved" aria-hidden="true"></span>
|
||||
</div>
|
||||
<div class="overview-callouts" aria-label="Sidebar sections">
|
||||
<article class="overview-callout snapshot">
|
||||
<h3>Snapshot row</h3>
|
||||
<p>Load, Quick Save, Save, Settings.</p>
|
||||
</article>
|
||||
<article class="overview-callout tools">
|
||||
<h3>Tools row</h3>
|
||||
<p>Maintenance plus the Help guide.</p>
|
||||
</article>
|
||||
<article class="overview-callout search">
|
||||
<h3>Search</h3>
|
||||
<p>Find nodes, workflows, folders, and tags.</p>
|
||||
</article>
|
||||
<article class="overview-callout nodes">
|
||||
<h3>Nodes action bar</h3>
|
||||
<p>Switch tree or list view, then add a favorite node.</p>
|
||||
</article>
|
||||
<article class="overview-callout workflows">
|
||||
<h3>Workflows action bar</h3>
|
||||
<p>Save the canvas or selected nodes, then browse saved workflows.</p>
|
||||
</article>
|
||||
<article class="overview-callout saved">
|
||||
<h3>Saved lists</h3>
|
||||
<p>Nodes, Workflows, and Tags stay visible below.</p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
<figcaption>First read the sidebar from top to bottom: Snapshot, Tools, Search, Nodes, Workflows, Tags.</figcaption>
|
||||
</figure>
|
||||
</section>
|
||||
|
||||
<section class="band">
|
||||
<div>
|
||||
<p class="eyebrow">Most important idea</p>
|
||||
<h2>Snapshot = your project kit</h2>
|
||||
</div>
|
||||
<p>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.</p>
|
||||
<figure class="visual full">
|
||||
<img src="./img/snapshot-flow.svg" alt="Snapshot flow from sidebar state to saved file to project library and later reload">
|
||||
</figure>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="section-copy">
|
||||
<p class="eyebrow">Project rhythm</p>
|
||||
<h2>A simple workflow</h2>
|
||||
<ol class="steps">
|
||||
<li>Load or create a snapshot, for example <strong>Client_Shot010</strong>.</li>
|
||||
<li>Add favorite nodes while building the shot.</li>
|
||||
<li>Save reusable node clusters as modules.</li>
|
||||
<li>Quick Save during the session.</li>
|
||||
<li>Save named snapshots for each project, shot, or task.</li>
|
||||
<li>Load the right snapshot when you return.</li>
|
||||
</ol>
|
||||
</div>
|
||||
<figure class="visual">
|
||||
<img src="./img/project-workflow.svg" alt="Six step project workflow for snapshots and modules">
|
||||
<figcaption>The goal is not to remember every button. The goal is to keep each project setup reusable.</figcaption>
|
||||
</figure>
|
||||
</section>
|
||||
|
||||
<section class="cards" aria-label="Main sidebar functions">
|
||||
<article>
|
||||
<h3>Snapshots</h3>
|
||||
<p>Save and reload the whole project kit.</p>
|
||||
<div class="function-list" aria-label="Snapshot functions">
|
||||
<span>Load</span>
|
||||
<span>Quick Save</span>
|
||||
<span>Save</span>
|
||||
<span>Settings</span>
|
||||
</div>
|
||||
</article>
|
||||
<article>
|
||||
<h3>Nodes</h3>
|
||||
<p>Keep favorite nodes organized and easy to update.</p>
|
||||
<div class="function-list" aria-label="Node functions">
|
||||
<span>Search</span>
|
||||
<span>Add</span>
|
||||
<span>Remove</span>
|
||||
<span>Group</span>
|
||||
</div>
|
||||
</article>
|
||||
<article>
|
||||
<h3>Search</h3>
|
||||
<p>Find saved work from one field. Tags keep exact capitalization.</p>
|
||||
<div class="function-list" aria-label="Search functions">
|
||||
<span>Nodes</span>
|
||||
<span>Workflows</span>
|
||||
<span>Folders</span>
|
||||
<span>Tags</span>
|
||||
</div>
|
||||
</article>
|
||||
<article>
|
||||
<h3>Workflows</h3>
|
||||
<p>Save full scripts or reusable node selections.</p>
|
||||
<div class="function-list" aria-label="Workflow functions">
|
||||
<span>Save script</span>
|
||||
<span>Save selection</span>
|
||||
<span>Load</span>
|
||||
<span>Insert module</span>
|
||||
</div>
|
||||
</article>
|
||||
<article>
|
||||
<h3>Safety / setup</h3>
|
||||
<p>Quiet helpers protect projects and make saved kits portable.</p>
|
||||
<div class="function-list" aria-label="Safety and setup functions">
|
||||
<span>Autosaves</span>
|
||||
<span>Missing packs</span>
|
||||
<span>Starter preset</span>
|
||||
<span>Library folder</span>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="recipes">
|
||||
<div class="section-copy wide">
|
||||
<p class="eyebrow">Visual recipes</p>
|
||||
<h2>Common things you will do</h2>
|
||||
</div>
|
||||
<figure class="visual recipe-real">
|
||||
<div class="recipe-shot">
|
||||
<img src="./img/screenshots/save-snapshot.png" alt="Save snapshot dialog showing library folder and save options">
|
||||
<span class="focus-dot focus-save" aria-hidden="true"></span>
|
||||
</div>
|
||||
<div class="recipe-callout blue" aria-label="Save snapshot notes">
|
||||
<p><strong>Save</strong> updates the current project kit. <strong>Save as new</strong> creates another named snapshot.</p>
|
||||
</div>
|
||||
<figcaption>Save the current sidebar state as a named project snapshot.</figcaption>
|
||||
</figure>
|
||||
<figure class="visual recipe-real">
|
||||
<div class="recipe-shot">
|
||||
<img src="./img/screenshots/load-snapshot.png" alt="Load snapshot dialog showing saved snapshots and recovery autosaves">
|
||||
<span class="focus-dot focus-load" aria-hidden="true"></span>
|
||||
</div>
|
||||
<div class="recipe-callout blue" aria-label="Load snapshot notes">
|
||||
<p><strong>Snapshot row</strong> restores that saved project kit. <strong>Recovery auto-saves</strong> are available below saved snapshots.</p>
|
||||
</div>
|
||||
<figcaption>Load a snapshot when you switch projects or return to a shot.</figcaption>
|
||||
</figure>
|
||||
<figure class="visual recipe-real module-recipe">
|
||||
<div class="recipe-shot">
|
||||
<img src="./img/screenshots/all-icons-new.png" alt="Sidebar toolbar screenshot with workflow save-selection highlighted">
|
||||
<span class="focus-dot focus-module" aria-hidden="true"></span>
|
||||
</div>
|
||||
<div class="recipe-callout amber" aria-label="Save selected nodes as module notes">
|
||||
<p><strong>Workflow save-selection</strong> is the bottom-right workflow action. Use it after selecting nodes on the canvas.</p>
|
||||
</div>
|
||||
<figcaption>Save selected nodes as a module, then insert that module into another canvas.</figcaption>
|
||||
</figure>
|
||||
<figure class="visual recipe-real">
|
||||
<div class="recipe-shot">
|
||||
<img src="./img/screenshots/search-C.png" alt="Search results showing matching favorite nodes">
|
||||
<span class="focus-dot focus-node-search" aria-hidden="true"></span>
|
||||
</div>
|
||||
<div class="recipe-callout green" aria-label="Node search notes">
|
||||
<p><strong>Node search</strong> narrows favorites so useful nodes are easier to scan and add.</p>
|
||||
</div>
|
||||
<figcaption>Search narrows the Nodes list so useful favorites are easier to scan and add.</figcaption>
|
||||
</figure>
|
||||
<figure class="visual recipe-real">
|
||||
<div class="recipe-shot">
|
||||
<img src="./img/screenshots/search-B.png" alt="Search results showing matching nodes and workflows">
|
||||
<span class="focus-dot focus-workflow-search" aria-hidden="true"></span>
|
||||
</div>
|
||||
<div class="recipe-callout purple" aria-label="Workflow search notes">
|
||||
<p><strong>One search field</strong> finds nodes and workflows, including saved workflows found through tags.</p>
|
||||
</div>
|
||||
<figcaption>Search finds both nodes and workflows from the same field, including saved workflows found through tags.</figcaption>
|
||||
</figure>
|
||||
<figure class="visual">
|
||||
<img src="./img/autosave-recovery.svg" alt="Annotated mockup showing autosave recovery">
|
||||
<figcaption>If something goes sideways, load an autosave from the Snapshot Load dialog.</figcaption>
|
||||
</figure>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||