Files
BehzadandClaude Opus 5 26b02e86f0 feat(picker): copy prompt, actionable errors, and a library lane worth reading
Release 1.1.0. Everything here came out of using the style picker and finding
the same shape of problem in several places: the connector showed the REST
API's own words to someone who cannot act on them, or showed nothing at all.

Errors, in one place. `friendly_error`/`short_error` (styleref_api.py) rewrite
an API failure as something a node graph can act on — the Login node's Sign in
button, the Search styles… dialog, generate-it-once for a 409 — and Load and
Apply re-raise through them. The raw 401 told users to send an
`Authorization: Bearer` header into ComfyUI's red error window, which has no
buttons at all. `short_error` is the same failure at widget width; the
"loaded style" line used to render the whole paragraph uncut, because the
length guard sat on the success branch only.

The picker:
- Sign in moved to the title row. It changes what the whole dialog can show,
  so it is not a property of one list.
- "My styles" hides itself when empty, and its rows now carry the thumbnail,
  category and tags a gallery row carries — with visibility (Private /
  Link-shared / Public) where a gallery row carries its author. A name on a
  blank square sat directly above real cards.
- The gallery lane drops styles you own, so a published style of yours appears
  once rather than in both lanes.
- No matches now offers /styles/create instead of a dead end.
- ↓/↑ walk the rows, Enter takes the top hit, Esc closes; query, category and
  sort survive between opens.

Load hides `search`/`category` when the dialog is available — they are the
headless fallback, and next to a working button they are the same duplication
the Login node's `action` dropdown was removed for. Picking also clears the
query, which otherwise made every later execution run a search it did not need.

Apply gains a Copy prompt button. Four of its six targets exist to be copied
out of ComfyUI, and the only way to read one in full was to wire up a Preview
Any node. The warning badge now matches any text encoder, not the exact class
`CLIPTextEncode` — SDXL, SD3 and Flux ship their own, so it did nothing on most
real graphs.

Reference Images no longer fails the queue when a style has no inspiration
images: it feeds IPAdapter or a preview, never the sampler, so it reports and
returns an empty batch. `max_images: 0` mutes it without rewiring.

Needs the matching StyleRef-Webapp deploy: the library lane's category, tags
and heroImage come from /api/v1/me/styles, and its search now scores the same
fields the gallery search scores.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 18:22:01 +02:00

74 lines
2.7 KiB
Python

"""
StyleRef nodes for ComfyUI — https://styleref.io
Define a creative style once on StyleRef, then load it as a node and reuse it
across your workflows.
MIT licensed. Issues: https://github.com/StyleRef/styleref-comfyui
"""
from __future__ import annotations
import os
import re
import sys
# The node modules import `styleref_api` etc. as top-level names. ComfyUI adds
# custom_nodes/<pack>/ to sys.path only in some layouts, so make it explicit
# rather than depending on how this pack was installed.
_PACK_DIR = os.path.dirname(os.path.abspath(__file__))
if _PACK_DIR not in sys.path:
sys.path.insert(0, _PACK_DIR)
from styleref_nodes.apply import StyleRefApply # noqa: E402
from styleref_nodes.facets import StyleRefFacets # noqa: E402
from styleref_nodes.load import StyleRefLoad # noqa: E402
from styleref_nodes.login import StyleRefLogin # noqa: E402
from styleref_nodes.reference_images import StyleRefReferenceImages # noqa: E402
NODE_CLASS_MAPPINGS = {
"StyleRefLoad": StyleRefLoad,
"StyleRefApply": StyleRefApply,
"StyleRefFacets": StyleRefFacets,
"StyleRefReferenceImages": StyleRefReferenceImages,
"StyleRefLogin": StyleRefLogin,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"StyleRefLoad": "StyleRef Load",
"StyleRefApply": "StyleRef Apply",
"StyleRefFacets": "StyleRef Facets",
"StyleRefReferenceImages": "StyleRef Reference Images",
"StyleRefLogin": "StyleRef Login",
}
# Served by ComfyUI at /extensions/styleref-comfyui/ — the search widget's
# progressive enhancement. Nothing here is required for the nodes to work.
WEB_DIRECTORY = "./web"
_FALLBACK_VERSION = "1.1.0"
def _pack_version() -> str:
"""Single-source the version from pyproject.toml, with a constant fallback."""
try:
with open(os.path.join(_PACK_DIR, "pyproject.toml"), encoding="utf-8") as fh:
match = re.search(r'^version\s*=\s*"([^"]+)"', fh.read(), re.MULTILINE)
return match.group(1) if match else _FALLBACK_VERSION
except OSError:
return _FALLBACK_VERSION
# The install docs tell users to look for a `[StyleRef]` line at startup, so a
# healthy import must print one — silence would read as a failed install.
print(f"[StyleRef] v{_pack_version()} — {len(NODE_CLASS_MAPPINGS)} nodes registered")
# Registering the search route is optional: without it the enhanced widget
# simply doesn't populate, and the vanilla `search` field still works.
try:
import server_routes # noqa: F401
except Exception as err: # noqa: BLE001 - never block node registration
print(f"[StyleRef] Search route unavailable ({err}); using the plain search field.")
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]