Comprehensive rebrand: ComfyUI → Hanzo Studio
- Replace all user-facing "ComfyUI" strings with "Hanzo Studio" - Update Help menu links: Discord → discord.gg/hanzoai, GitHub → hanzoai/studio - Replace comfy.org URLs with hanzo.ai equivalents - Update support email to support@hanzo.ai - Rewrite branding script to patch ALL JS bundles comprehensively - Update default filename prefixes from ComfyUI to HanzoStudio - Fix CI to trigger on main branch (not hanzo/main) - Update pyproject.toml metadata (name, URLs)
This commit is contained in:
@@ -2,7 +2,7 @@ name: Build and Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [hanzo/main]
|
||||
branches: [main]
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ except ImportError as e:
|
||||
------------------------------------------------------------------------
|
||||
Error importing dependencies: {e}
|
||||
{get_missing_requirements_message()}
|
||||
This error is happening because ComfyUI now uses a local sqlite database.
|
||||
This error is happening because Hanzo Studio now uses a local sqlite database.
|
||||
------------------------------------------------------------------------
|
||||
""".strip()
|
||||
)
|
||||
|
||||
@@ -27,7 +27,7 @@ def frontend_install_warning_message():
|
||||
return f"""
|
||||
{get_missing_requirements_message()}
|
||||
|
||||
This error is happening because the ComfyUI frontend is no longer shipped as part of the main repo but as a pip package instead.
|
||||
This error is happening because the Hanzo Studio frontend is no longer shipped as part of the main repo but as a pip package instead.
|
||||
""".strip()
|
||||
|
||||
def parse_version(version: str) -> tuple[int, int, int]:
|
||||
@@ -87,7 +87,7 @@ ________________________________________________________________________
|
||||
""".strip()
|
||||
)
|
||||
else:
|
||||
logging.info("ComfyUI frontend version: {}".format(frontend_version_str))
|
||||
logging.info("Hanzo Studio frontend version: {}".format(frontend_version_str))
|
||||
except Exception as e:
|
||||
logging.error(f"Failed to check frontend version: {e}")
|
||||
|
||||
|
||||
+115
-56
@@ -1,99 +1,158 @@
|
||||
#!/bin/bash
|
||||
# Apply Hanzo Studio branding to ComfyUI frontend
|
||||
# Apply Hanzo Studio branding to ComfyUI frontend package
|
||||
# This runs during Docker build after pip install to patch the pre-built frontend
|
||||
set -e
|
||||
|
||||
STATIC_DIR=$(python3 -c "import comfyui_frontend_package, importlib.resources; print(str(importlib.resources.files(comfyui_frontend_package) / 'static'))")
|
||||
BRANDING_DIR="$(dirname "$0")"
|
||||
|
||||
echo "Applying Hanzo Studio branding to: $STATIC_DIR"
|
||||
echo "=== Hanzo Studio Branding ==="
|
||||
echo "Target: $STATIC_DIR"
|
||||
|
||||
# 1. Replace logo SVGs
|
||||
cp "$BRANDING_DIR/hanzo-logo.svg" "$STATIC_DIR/assets/images/comfy-logo-single.svg"
|
||||
cp "$BRANDING_DIR/hanzo-logo.svg" "$STATIC_DIR/assets/images/comfy-logo-mono.svg"
|
||||
cp "$BRANDING_DIR/hanzo-logo.svg" "$STATIC_DIR/assets/images/comfy-cloud-logo.svg"
|
||||
# --- 1. Replace logo SVG files ---
|
||||
echo "[1/7] Replacing logos..."
|
||||
for logo_file in comfy-logo-single.svg comfy-logo-mono.svg comfy-cloud-logo.svg; do
|
||||
target="$STATIC_DIR/assets/images/$logo_file"
|
||||
if [ -f "$target" ]; then
|
||||
cp "$BRANDING_DIR/hanzo-logo.svg" "$target"
|
||||
echo " Replaced $logo_file"
|
||||
fi
|
||||
done
|
||||
|
||||
# 2. Replace favicon - convert SVG to ICO using Python
|
||||
# Also replace any other logo SVGs we find
|
||||
find "$STATIC_DIR" -name "*comfy*logo*" -o -name "*logo*comfy*" 2>/dev/null | while read f; do
|
||||
if [[ "$f" == *.svg ]]; then
|
||||
cp "$BRANDING_DIR/hanzo-logo.svg" "$f"
|
||||
echo " Replaced $(basename "$f")"
|
||||
fi
|
||||
done
|
||||
|
||||
# --- 2. Replace favicon ---
|
||||
echo "[2/7] Replacing favicon..."
|
||||
python3 -c "
|
||||
import struct, io, base64, xml.etree.ElementTree as ET
|
||||
import struct
|
||||
|
||||
# Read the favicon SVG
|
||||
with open('$BRANDING_DIR/favicon.svg', 'r') as f:
|
||||
svg_content = f.read()
|
||||
|
||||
# Create a minimal 16x16 ICO with the H mark
|
||||
# Use a simple 16x16 bitmap representation
|
||||
size = 16
|
||||
# Simple H pattern at 16x16
|
||||
pixels = bytearray(size * size * 4) # BGRA
|
||||
pixels = bytearray(size * size * 4)
|
||||
|
||||
# Draw the H mark (simplified geometric pattern)
|
||||
for y in range(size):
|
||||
for x in range(size):
|
||||
idx = (y * size + x) * 4
|
||||
# Background: transparent
|
||||
pixels[idx] = 0 # B
|
||||
pixels[idx+1] = 0 # G
|
||||
pixels[idx+2] = 0 # R
|
||||
pixels[idx+3] = 0 # A
|
||||
|
||||
# Left vertical bar (0-4, 0-15)
|
||||
pixels[idx] = 0; pixels[idx+1] = 0; pixels[idx+2] = 0; pixels[idx+3] = 0
|
||||
# Left vertical bar
|
||||
if 1 <= x <= 4 and 1 <= y <= 14:
|
||||
pixels[idx] = 255; pixels[idx+1] = 255; pixels[idx+2] = 255; pixels[idx+3] = 255
|
||||
# Right vertical bar (11-14, 0-15)
|
||||
# Right vertical bar
|
||||
if 11 <= x <= 14 and 1 <= y <= 14:
|
||||
pixels[idx] = 255; pixels[idx+1] = 255; pixels[idx+2] = 255; pixels[idx+3] = 255
|
||||
# Diagonal bar (connecting, roughly y=4 to y=11, x=1 to x=14)
|
||||
# Diagonal bar
|
||||
if 4 <= y <= 11:
|
||||
expected_x = 1 + (y - 4) * (13.0 / 7.0)
|
||||
if abs(x - expected_x) <= 2:
|
||||
pixels[idx] = 255; pixels[idx+1] = 255; pixels[idx+2] = 255; pixels[idx+3] = 255
|
||||
|
||||
# ICO format
|
||||
ico = bytearray()
|
||||
# ICONDIR
|
||||
ico += struct.pack('<HHH', 0, 1, 1) # reserved, type=1(icon), count=1
|
||||
# ICONDIRENTRY
|
||||
ico += struct.pack('<HHH', 0, 1, 1)
|
||||
ico += struct.pack('<BBBBHHII', size, size, 0, 0, 1, 32, len(pixels) + 40, 22)
|
||||
# BITMAPINFOHEADER
|
||||
ico += struct.pack('<IiiHHIIiiII', 40, size, size*2, 1, 32, 0, len(pixels), 0, 0, 0, 0)
|
||||
# Pixel data (bottom-up)
|
||||
for y in range(size-1, -1, -1):
|
||||
ico += pixels[y*size*4:(y+1)*size*4]
|
||||
|
||||
with open('$STATIC_DIR/assets/favicon.ico', 'wb') as f:
|
||||
f.write(ico)
|
||||
print('Generated favicon.ico')
|
||||
print(' Generated favicon.ico')
|
||||
"
|
||||
|
||||
# 3. Patch index.html
|
||||
sed -i 's/<title>ComfyUI<\/title>/<title>Hanzo Studio<\/title>/g' "$STATIC_DIR/index.html"
|
||||
sed -i 's/Loading ComfyUI\.\.\./Loading Hanzo Studio.../g' "$STATIC_DIR/index.html"
|
||||
# Also replace any other favicon files
|
||||
find "$STATIC_DIR" -name "favicon*" ! -name "favicon.ico" 2>/dev/null | while read f; do
|
||||
if [[ "$f" == *.svg ]]; then
|
||||
cp "$BRANDING_DIR/favicon.svg" "$f"
|
||||
echo " Replaced $(basename "$f")"
|
||||
fi
|
||||
done
|
||||
|
||||
# 4. Patch manifest JSON
|
||||
find "$STATIC_DIR/assets" -name "manifest-*.json" -exec sed -i 's/"ComfyUI"/"Hanzo Studio"/g' {} \;
|
||||
find "$STATIC_DIR/assets" -name "manifest-*.json" -exec sed -i 's/ComfyUI: AI image generation platform/Hanzo Studio: Visual AI Engine/g' {} \;
|
||||
# --- 3. Patch index.html ---
|
||||
echo "[3/7] Patching index.html..."
|
||||
if [ -f "$STATIC_DIR/index.html" ]; then
|
||||
sed -i 's/<title>ComfyUI<\/title>/<title>Hanzo Studio<\/title>/g' "$STATIC_DIR/index.html"
|
||||
sed -i 's/<title>Comfy<\/title>/<title>Hanzo Studio<\/title>/g' "$STATIC_DIR/index.html"
|
||||
sed -i 's/Loading ComfyUI/Loading Hanzo Studio/g' "$STATIC_DIR/index.html"
|
||||
sed -i 's/Loading Comfy/Loading Hanzo Studio/g' "$STATIC_DIR/index.html"
|
||||
sed -i 's/content="ComfyUI/content="Hanzo Studio/g' "$STATIC_DIR/index.html"
|
||||
sed -i 's/content="Comfy/content="Hanzo Studio/g' "$STATIC_DIR/index.html"
|
||||
echo " Patched index.html"
|
||||
fi
|
||||
|
||||
# 5. Patch visible "ComfyUI" strings in JS bundles (user-facing only)
|
||||
# Target the main bundle and commands for UI-visible strings
|
||||
for js in "$STATIC_DIR/assets"/main-*.js "$STATIC_DIR/assets"/commands-*.js "$STATIC_DIR/assets"/settings-*.js; do
|
||||
# --- 4. Patch manifest JSON files ---
|
||||
echo "[4/7] Patching manifests..."
|
||||
find "$STATIC_DIR" -name "manifest*.json" -exec sed -i 's/"ComfyUI"/"Hanzo Studio"/g' {} \;
|
||||
find "$STATIC_DIR" -name "manifest*.json" -exec sed -i 's/"Comfy"/"Hanzo Studio"/g' {} \;
|
||||
find "$STATIC_DIR" -name "manifest*.json" -exec sed -i 's/ComfyUI: AI image generation platform/Hanzo Studio: Visual AI Engine/g' {} \;
|
||||
find "$STATIC_DIR" -name "manifest*.json" -exec sed -i 's/comfy\.org/hanzo.ai/g' {} \;
|
||||
echo " Done"
|
||||
|
||||
# --- 5. Comprehensive JS bundle patching ---
|
||||
echo "[5/7] Patching ALL JS bundles..."
|
||||
JS_COUNT=0
|
||||
for js in "$STATIC_DIR"/assets/*.js "$STATIC_DIR"/*.js; do
|
||||
[ -f "$js" ] || continue
|
||||
# Replace user-visible ComfyUI references
|
||||
|
||||
# Brand names
|
||||
sed -i 's/ComfyUI/Hanzo Studio/g' "$js"
|
||||
done
|
||||
|
||||
# 6. Patch the AboutPanel
|
||||
for js in "$STATIC_DIR/assets"/AboutPanel-*.js; do
|
||||
[ -f "$js" ] || continue
|
||||
sed -i 's/ComfyUI/Hanzo Studio/g' "$js"
|
||||
sed -i 's/comfy\.org/hanzo.ai/g' "$js"
|
||||
# Organization names
|
||||
sed -i 's/ComfyOrg/Hanzo AI/g' "$js"
|
||||
done
|
||||
sed -i 's/Comfy-Org/Hanzo AI/g' "$js"
|
||||
sed -i 's/Comfy Org/Hanzo AI/g' "$js"
|
||||
|
||||
# 7. Patch ComfyOrgHeader
|
||||
for js in "$STATIC_DIR/assets"/ComfyOrgHeader-*.js; do
|
||||
[ -f "$js" ] || continue
|
||||
sed -i 's/ComfyOrg/Hanzo AI/g' "$js"
|
||||
# Domain replacements
|
||||
sed -i 's/comfy\.org/hanzo.ai/g' "$js"
|
||||
done
|
||||
sed -i 's/docs\.comfy\.org/docs.hanzo.ai/g' "$js"
|
||||
sed -i 's/forum\.comfy\.org/hanzo.ai\/community/g' "$js"
|
||||
sed -i 's/api\.comfy\.org/api.hanzo.ai/g' "$js"
|
||||
sed -i 's/platform\.comfy\.org/hanzo.ai/g' "$js"
|
||||
|
||||
echo "Hanzo Studio branding applied successfully"
|
||||
# GitHub URLs
|
||||
sed -i 's|github\.com/comfyanonymous/ComfyUI|github.com/hanzoai/studio|g' "$js"
|
||||
sed -i 's|github\.com/Comfy-Org/ComfyUI|github.com/hanzoai/studio|g' "$js"
|
||||
sed -i 's|github\.com/Comfy-Org|github.com/hanzoai|g' "$js"
|
||||
sed -i 's|github\.com/comfyanonymous|github.com/hanzoai|g' "$js"
|
||||
|
||||
# Discord - replace Comfy discord with Hanzo discord
|
||||
sed -i 's|discord\.gg/comfyorg|discord.gg/hanzoai|g' "$js"
|
||||
sed -i 's|discord\.com/invite/comfyorg|discord.com/invite/hanzoai|g' "$js"
|
||||
# Catch other Comfy discord patterns
|
||||
sed -i 's|discord\.gg/[a-zA-Z0-9]*comfy[a-zA-Z0-9]*|discord.gg/hanzoai|g' "$js"
|
||||
|
||||
# Support email
|
||||
sed -i 's/support@comfy\.org/support@hanzo.ai/g' "$js"
|
||||
|
||||
# Clean up any double-replacements (e.g., "Hanzo Studio Studio")
|
||||
sed -i 's/Hanzo Studio Studio/Hanzo Studio/g' "$js"
|
||||
sed -i 's/Hanzo Studio Manager/Hanzo Studio Manager/g' "$js"
|
||||
|
||||
JS_COUNT=$((JS_COUNT + 1))
|
||||
done
|
||||
echo " Patched $JS_COUNT JS files"
|
||||
|
||||
# --- 6. Patch CSS files ---
|
||||
echo "[6/7] Patching CSS..."
|
||||
for css in "$STATIC_DIR"/assets/*.css "$STATIC_DIR"/*.css; do
|
||||
[ -f "$css" ] || continue
|
||||
# Remove any ComfyUI-specific animation classes that reference the C logo
|
||||
# (The spinning C logo animation)
|
||||
sed -i 's/comfy\.org/hanzo.ai/g' "$css"
|
||||
done
|
||||
echo " Done"
|
||||
|
||||
# --- 7. Final verification ---
|
||||
echo "[7/7] Verification..."
|
||||
REMAINING=$(grep -rl "ComfyUI" "$STATIC_DIR" --include="*.html" --include="*.js" --include="*.json" 2>/dev/null | wc -l | tr -d ' ')
|
||||
echo " Files still containing 'ComfyUI': $REMAINING"
|
||||
if [ "$REMAINING" -gt 0 ]; then
|
||||
echo " Remaining references (for review):"
|
||||
grep -rl "ComfyUI" "$STATIC_DIR" --include="*.html" --include="*.js" --include="*.json" 2>/dev/null | head -5
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Hanzo Studio branding complete ==="
|
||||
|
||||
+1
-1
@@ -225,7 +225,7 @@ parser.add_argument(
|
||||
"--comfy-api-base",
|
||||
type=str,
|
||||
default="https://api.comfy.org",
|
||||
help="Set the base URL for the ComfyUI API. (default: https://api.comfy.org)",
|
||||
help="Set the base URL for the Hanzo Studio API. (default: https://api.comfy.org)",
|
||||
)
|
||||
|
||||
database_default_path = os.path.abspath(
|
||||
|
||||
@@ -514,7 +514,7 @@ def _friendly_http_message(status: int, body: Any) -> str:
|
||||
if status == 402:
|
||||
return "Payment Required: Please add credits to your account to use this node."
|
||||
if status == 409:
|
||||
return "There is a problem with your account. Please contact support@comfy.org."
|
||||
return "There is a problem with your account. Please contact support@hanzo.ai."
|
||||
if status == 429:
|
||||
return "Rate Limit Exceeded: The server returned 429 after all retry attempts. Please wait and try again."
|
||||
try:
|
||||
|
||||
@@ -223,7 +223,7 @@ def cuda_malloc_warning():
|
||||
if b in device_name:
|
||||
cuda_malloc_warning = True
|
||||
if cuda_malloc_warning:
|
||||
logging.warning("\nWARNING: this card most likely does not support cuda-malloc, if you get \"CUDA error\" please run ComfyUI with: --disable-cuda-malloc\n")
|
||||
logging.warning("\nWARNING: this card most likely does not support cuda-malloc, if you get \"CUDA error\" please run Hanzo Studio with: --disable-cuda-malloc\n")
|
||||
|
||||
|
||||
def prompt_worker(q, server_instance):
|
||||
@@ -363,7 +363,7 @@ def setup_database():
|
||||
|
||||
def start_comfyui(asyncio_loop=None):
|
||||
"""
|
||||
Starts the ComfyUI server using the provided asyncio event loop or creates a new one.
|
||||
Starts the Hanzo Studio server using the provided asyncio event loop or creates a new one.
|
||||
Returns the event loop, server instance, and a function to start the server asynchronously.
|
||||
"""
|
||||
if args.temp_directory:
|
||||
@@ -421,14 +421,14 @@ def start_comfyui(asyncio_loop=None):
|
||||
await prompt_server.setup()
|
||||
await run(prompt_server, address=args.listen, port=args.port, verbose=not args.dont_print_server, call_on_start=call_on_start)
|
||||
|
||||
# Returning these so that other code can integrate with the ComfyUI loop and server
|
||||
# Returning these so that other code can integrate with the Hanzo Studio loop and server
|
||||
return asyncio_loop, prompt_server, start_all
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Running directly, just start ComfyUI.
|
||||
# Running directly, just start Hanzo Studio.
|
||||
logging.info("Python version: {}".format(sys.version))
|
||||
logging.info("ComfyUI version: {}".format(comfyui_version.__version__))
|
||||
logging.info("Hanzo Studio version: {}".format(comfyui_version.__version__))
|
||||
|
||||
if sys.version_info.major == 3 and sys.version_info.minor < 10:
|
||||
logging.warning("WARNING: You are using a python version older than 3.10, please upgrade to a newer one. 3.12 and above is recommended.")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Cache control middleware for ComfyUI server"""
|
||||
"""Cache control middleware for Hanzo Studio server"""
|
||||
|
||||
from aiohttp import web
|
||||
from typing import Callable, Awaitable
|
||||
|
||||
@@ -484,7 +484,7 @@ class SaveLatent:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {"required": { "samples": ("LATENT", ),
|
||||
"filename_prefix": ("STRING", {"default": "latents/ComfyUI"})},
|
||||
"filename_prefix": ("STRING", {"default": "latents/HanzoStudio"})},
|
||||
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"},
|
||||
}
|
||||
RETURN_TYPES = ()
|
||||
@@ -494,7 +494,7 @@ class SaveLatent:
|
||||
|
||||
CATEGORY = "_for_testing"
|
||||
|
||||
def save(self, samples, filename_prefix="ComfyUI", prompt=None, extra_pnginfo=None):
|
||||
def save(self, samples, filename_prefix="HanzoStudio", prompt=None, extra_pnginfo=None):
|
||||
full_output_folder, filename, counter, subfolder, filename_prefix = folder_paths.get_save_image_path(filename_prefix, self.output_dir)
|
||||
|
||||
# support save metadata for latent sharing
|
||||
@@ -1638,7 +1638,7 @@ class SaveImage:
|
||||
return {
|
||||
"required": {
|
||||
"images": ("IMAGE", {"tooltip": "The images to save."}),
|
||||
"filename_prefix": ("STRING", {"default": "ComfyUI", "tooltip": "The prefix for the file to save. This may include formatting information such as %date:yyyy-MM-dd% or %Empty Latent Image.width% to include values from nodes."})
|
||||
"filename_prefix": ("STRING", {"default": "HanzoStudio", "tooltip": "The prefix for the file to save. This may include formatting information such as %date:yyyy-MM-dd% or %Empty Latent Image.width% to include values from nodes."})
|
||||
},
|
||||
"hidden": {
|
||||
"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"
|
||||
@@ -1652,10 +1652,10 @@ class SaveImage:
|
||||
|
||||
CATEGORY = "image"
|
||||
ESSENTIALS_CATEGORY = "Basics"
|
||||
DESCRIPTION = "Saves the input images to your ComfyUI output directory."
|
||||
DESCRIPTION = "Saves the input images to your Hanzo Studio output directory."
|
||||
SEARCH_ALIASES = ["save", "save image", "export image", "output image", "write image", "download"]
|
||||
|
||||
def save_images(self, images, filename_prefix="ComfyUI", prompt=None, extra_pnginfo=None):
|
||||
def save_images(self, images, filename_prefix="HanzoStudio", prompt=None, extra_pnginfo=None):
|
||||
filename_prefix += self.prefix_append
|
||||
full_output_folder, filename, counter, subfolder, filename_prefix = folder_paths.get_save_image_path(filename_prefix, self.output_dir, images[0].shape[1], images[0].shape[0])
|
||||
results = list()
|
||||
|
||||
+4
-4
@@ -1,14 +1,14 @@
|
||||
[project]
|
||||
name = "ComfyUI"
|
||||
name = "hanzo-studio"
|
||||
version = "0.14.1"
|
||||
readme = "README.md"
|
||||
license = { file = "LICENSE" }
|
||||
requires-python = ">=3.10"
|
||||
|
||||
[project.urls]
|
||||
homepage = "https://www.comfy.org/"
|
||||
repository = "https://github.com/comfyanonymous/ComfyUI"
|
||||
documentation = "https://docs.comfy.org/"
|
||||
homepage = "https://hanzo.ai"
|
||||
repository = "https://github.com/hanzoai/studio"
|
||||
documentation = "https://docs.hanzo.ai"
|
||||
|
||||
[tool.ruff]
|
||||
lint.select = [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import json
|
||||
from urllib import request
|
||||
|
||||
#This is the ComfyUI api prompt format.
|
||||
#This is the Hanzo Studio api prompt format.
|
||||
|
||||
#If you want it for a specific workflow you can "File -> Export (API)" in the interface.
|
||||
|
||||
@@ -85,7 +85,7 @@ prompt_text = """
|
||||
"9": {
|
||||
"class_type": "SaveImage",
|
||||
"inputs": {
|
||||
"filename_prefix": "ComfyUI",
|
||||
"filename_prefix": "HanzoStudio",
|
||||
"images": [
|
||||
"8",
|
||||
0
|
||||
|
||||
@@ -135,7 +135,7 @@ prompt_text = """
|
||||
"9": {
|
||||
"class_type": "SaveImage",
|
||||
"inputs": {
|
||||
"filename_prefix": "ComfyUI",
|
||||
"filename_prefix": "HanzoStudio",
|
||||
"images": [
|
||||
"8",
|
||||
0
|
||||
|
||||
Reference in New Issue
Block a user