The trigger words widget was created with node.addWidget(\"text\", ...) which
uses a simple single-line input even with multiline: true. In ComfyUI this
does not render multiple lines properly, making trigger words invisible.
Switch to ComfyWidgets[\"STRING\"](..., { multiline: true }) which creates a
proper <textarea> element that can display multi-line text.
Also fix preview area overlapping widget area by reserving ~250px for widgets
and capping preview height so it starts below the trigger words textarea.
The preview image area was fixed at 200px height regardless of node size.
When users dragged the node corner to enlarge it, the preview stayed the
same size while the space above it grew, leaving an awkward gap.
Change getPreviewArea() to compute a dynamic height:
- 35% of node height (scales with resize)
- clamped between 80px min and 400px max
Width already scaled with node.size[0]; now height does too.
Also update the minimum node height from a fixed PREVIEW_HEIGHT-based
value to a conservative estimate (260px) that fits widgets + min preview.
When the user switched from a LoRA with cached data to one without,
the button stayed as \"Refresh\" and stale trigger words / preview images
remained visible. This was because node-level civitai state was not
cleared on lora_name change.
Hook into the lora_name widget's callback to detect changes and reset:
- civitai_cache (null)
- civitai_image_index (0)
- civitai_nsfw_unblurred ({})
- trigger words text (empty)
Then update the button label back to \"Fetch Civitai Info\" and redraw.
- Cache manager with JSON read/write, TTL, corruption handling
- Civitai client with SHA256 hash (sync+async) and API fetch
- KaiCivitaiLoRALoader node with trigger words and JSON output
- Node registration, HTTP routes, and secure image serving
- Frontend extension with image preview, pagination, and NSFW blur
- 49 unit tests covering all modules