Last active
February 20, 2025 21:45
-
-
Save regiellis/7406d62ac47b6e9926b3231d34d0a553 to your computer and use it in GitHub Desktop.
ComfyUI hot-reload for custom nodes development
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
setlocal enabledelayedexpansion | |
rem Get the main directory | |
set "SCRIPT_DIR=%~dp0" | |
rem Set paths relative | |
set "WATCH_DIR=%SCRIPT_DIR%ComfyUI\custom_nodes" | |
set "RUN_COMFY_SCRIPT=%SCRIPT_DIR%comfyui_manager.bat" | |
set "PID_FILE=%SCRIPT_DIR%comfyui.pid" | |
set "LOG_FILE=%SCRIPT_DIR%comfyui.log" | |
set "DEBOUNCE_SECONDS=5" | |
rem Define colors | |
set "GREEN=[92m" | |
set "RED=[91m" | |
set "YELLOW=[93m" | |
set "NC=[0m" | |
:is_comfyui_running | |
if exist "%PID_FILE%" ( | |
for /f %%i in (%PID_FILE%) do ( | |
tasklist /FI "PID eq %%i" 2>NUL | find /I /N "%%i">NUL | |
if !errorlevel! equ 0 exit /b 0 | |
) | |
) | |
exit /b 1 | |
:start_comfyui | |
echo %GREEN%Starting ComfyUI...%NC% | |
call "%RUN_COMFY_SCRIPT%" background | |
timeout /t 2 >nul | |
exit /b | |
:stop_comfyui | |
call :is_comfyui_running | |
if !errorlevel! equ 0 ( | |
echo %YELLOW%Stopping ComfyUI...%NC% | |
call "%RUN_COMFY_SCRIPT%" stop | |
timeout /t 2 >nul | |
) | |
exit /b | |
:restart_comfyui | |
call :stop_comfyui | |
call :start_comfyui | |
exit /b | |
:watch_for_changes | |
set "last_restart=%time%" | |
:watch_loop | |
for /f "delims=" %%a in ('dir /s /b /a-d "%WATCH_DIR%\*.py" "%WATCH_DIR%\*.js" "%WATCH_DIR%\*.css"') do ( | |
set "file_time=%%~ta" | |
call :check_file_time "!file_time!" "!last_restart!" | |
if !errorlevel! equ 1 ( | |
echo %YELLOW%Changes detected. Restarting ComfyUI...%NC% | |
call :restart_comfyui | |
set "last_restart=%time%" | |
) | |
) | |
timeout /t 1 >nul | |
goto :watch_loop | |
:check_file_time | |
set "file_time=%~1" | |
set "last_restart=%~2" | |
powershell -Command "&{$ft=[datetime]::ParseExact('%file_time%','MM/dd/yyyy HH:mm:ss',$null);$lr=[datetime]::ParseExact('%last_restart%','HH:mm:ss.ff',$null);if(($ft - $lr).TotalSeconds -ge %DEBOUNCE_SECONDS%) {exit 1} else {exit 0}}" | |
exit /b | |
rem Start ComfyUI if it's not already running | |
call :is_comfyui_running | |
if !errorlevel! neq 0 call :start_comfyui | |
echo %GREEN%Watching %WATCH_DIR% for changes...%NC% | |
call :watch_for_changes |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Get the main directory | |
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path | |
# Set paths relative | |
$WatchDir = Join-Path $ScriptDir "ComfyUI\custom_nodes" | |
$RunComfyScript = Join-Path $ScriptDir "comfyui_manager.ps1" | |
$PidFile = Join-Path $ScriptDir "comfyui.pid" | |
$LogFile = Join-Path $ScriptDir "comfyui.log" | |
$DebounceSeconds = 5 | |
# Define colors | |
$Green = [System.ConsoleColor]::Green | |
$Red = [System.ConsoleColor]::Red | |
$Yellow = [System.ConsoleColor]::Yellow | |
function Is-ComfyUIRunning { | |
if (Test-Path $PidFile) { | |
$pid = Get-Content $PidFile | |
return Get-Process -Id $pid -ErrorAction SilentlyContinue | |
} | |
return $false | |
} | |
function Start-ComfyUI { | |
Write-Host "Starting ComfyUI..." -ForegroundColor $Green | |
& $RunComfyScript background | |
Start-Sleep -Seconds 2 | |
} | |
function Stop-ComfyUI { | |
if (Is-ComfyUIRunning) { | |
Write-Host "Stopping ComfyUI..." -ForegroundColor $Yellow | |
& $RunComfyScript stop | |
Start-Sleep -Seconds 2 | |
} | |
} | |
function Restart-ComfyUI { | |
Stop-ComfyUI | |
Start-ComfyUI | |
} | |
function Watch-ForChanges { | |
$lastRestart = Get-Date | |
while ($true) { | |
$changedFiles = Get-ChildItem -Path $WatchDir -Recurse -Include *.py,*.js,*.css | | |
Where-Object { $_.LastWriteTime -gt $lastRestart.AddSeconds(-$DebounceSeconds) } | |
if ($changedFiles) { | |
$currentTime = Get-Date | |
if (($currentTime - $lastRestart).TotalSeconds -ge $DebounceSeconds) { | |
Write-Host "Changes detected. Restarting ComfyUI..." -ForegroundColor $Yellow | |
Restart-ComfyUI | |
$lastRestart = $currentTime | |
} | |
} | |
Start-Sleep -Seconds 1 | |
} | |
} | |
# Start ComfyUI if it's not already running | |
if (-not (Is-ComfyUIRunning)) { | |
Start-ComfyUI | |
} | |
Write-Host "Watching $WatchDir for changes..." -ForegroundColor $Green | |
Watch-ForChanges |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Get the main directory | |
SCRIPT_DIR="$(dirname "$(realpath "$0")")" | |
# Set paths relative | |
WATCH_DIR="$SCRIPT_DIR/ComfyUI/custom_nodes/" | |
RUN_COMFY_SCRIPT="$SCRIPT_DIR/run_comfy.sh" # custom bootstrap or use comfyui cli | |
PID_FILE="$SCRIPT_DIR/comfyui.pid" | |
LOG_FILE="$SCRIPT_DIR/comfyui.log" | |
DEBOUNCE_SECONDS=5 | |
# Define colors | |
GREEN='\033[0;32m' # Green for success messages | |
RED='\033[0;31m' # Red for error messages | |
YELLOW='\033[0;33m' # Yellow for warnings | |
NC='\033[0m' # No Color | |
is_comfyui_running() { | |
[[ -f "$PID_FILE" ]] && kill -0 $(cat "$PID_FILE") 2>/dev/null | |
} | |
start_comfyui() { | |
echo -e "${GREEN}Starting ComfyUI...${NC}" | |
"$RUN_COMFY_SCRIPT" background | |
sleep 2 # Give it a moment to start | |
} | |
stop_comfyui() { | |
if is_comfyui_running; then | |
echo -e "${YELLOW}Stopping ComfyUI...${NC}" | |
"$RUN_COMFY_SCRIPT" stop | |
sleep 2 # Give it a moment to stop | |
fi | |
} | |
restart_comfyui() { | |
stop_comfyui | |
start_comfyui | |
} | |
watch_for_changes() { | |
local last_restart=$(date +%s) | |
while true; do | |
if find "$WATCH_DIR" -type f \( -name "*.py" -o -name "*.js" -o -name "*.css" \) -newermt "-${DEBOUNCE_SECONDS} seconds" | grep -q .; then | |
current_time=$(date +%s) | |
if ((current_time - last_restart >= DEBOUNCE_SECONDS)); then | |
echo -e "${YELLOW}Changes detected. Restarting ComfyUI...${NC}" | |
restart_comfyui | |
last_restart=$current_time | |
fi | |
fi | |
sleep 1 | |
done | |
} | |
# Start ComfyUI if it's not already running | |
if ! is_comfyui_running; then | |
start_comfyui | |
fi | |
echo -e "${GREEN}Watching $WATCH_DIR for changes...${NC}" | |
watch_for_changes |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
setlocal enabledelayedexpansion | |
set "SCRIPT_DIR=%~dp0" | |
set "COMFY_DIR=%SCRIPT_DIR%ComfyUI" | |
set "VENV_PATH=%COMFY_DIR%\.venv" | |
set "PID_FILE=%SCRIPT_DIR%comfyui.pid" | |
set "LOG_FILE=%SCRIPT_DIR%comfyui.log" | |
set "MAX_WAIT_TIME=60" | |
if "%1"=="" goto :usage | |
if "%1"=="start" goto :start_foreground | |
if "%1"=="background" goto :start_background | |
if "%1"=="stop" goto :stop | |
if "%1"=="restart" goto :restart | |
goto :usage | |
:start_background | |
echo Starting ComfyUI in the background... | |
call "%VENV_PATH%\Scripts\activate.bat" | |
start /B "" python -s "%COMFY_DIR%\main.py" --listen --preview-method auto > "%LOG_FILE%" 2>&1 | |
for /f "tokens=2" %%i in ('tasklist /fi "imagename eq python.exe" /fo list /v ^| find /i "PID:"') do ( | |
echo %%i > "%PID_FILE%" | |
echo ComfyUI started in background. PID: %%i | |
) | |
call :wait_for_comfyui_ready | |
goto :eof | |
:start_foreground | |
echo Starting ComfyUI in the foreground... | |
call "%VENV_PATH%\Scripts\activate.bat" | |
python -s "%COMFY_DIR%\main.py" --listen --preview-method auto | |
goto :eof | |
:stop | |
if exist "%PID_FILE%" ( | |
set /p PID=<"%PID_FILE%" | |
echo Stopping ComfyUI (PID: !PID!)... | |
taskkill /F /PID !PID! | |
call :wait_for_comfyui_stop | |
del "%PID_FILE%" | |
echo ComfyUI stopped. | |
) else ( | |
echo ComfyUI is not running in the background. | |
) | |
goto :eof | |
:wait_for_comfyui_ready | |
echo Waiting for ComfyUI to be fully operational... | |
set start_time=%time% | |
:wait_loop_ready | |
findstr /C:"Starting server" "%LOG_FILE%" >nul | |
if %errorlevel% equ 0 ( | |
echo ComfyUI is now fully operational. | |
goto :eof | |
) | |
call :check_timeout | |
if %errorlevel% equ 1 goto :eof | |
timeout /t 1 /nobreak >nul | |
goto wait_loop_ready | |
:wait_for_comfyui_stop | |
echo Waiting for ComfyUI to stop... | |
set start_time=%time% | |
:wait_loop_stop | |
tasklist /FI "PID eq %PID%" 2>NUL | find /I /N "%PID%">NUL | |
if %errorlevel% neq 0 goto :eof | |
call :check_timeout | |
if %errorlevel% equ 1 ( | |
echo Timeout: ComfyUI did not stop within %MAX_WAIT_TIME% seconds. Forcing stop. | |
taskkill /F /PID %PID% | |
goto :eof | |
) | |
timeout /t 1 /nobreak >nul | |
goto wait_loop_stop | |
:check_timeout | |
set end_time=%time% | |
set options="tokens=1-4 delims=:.," | |
for /f %options% %%a in ("%start_time%") do set start_s=%%a&set start_m=%%b&set start_c=%%c | |
for /f %options% %%a in ("%end_time%") do set end_s=%%a&set end_m=%%b&set end_c=%%c | |
set /a start=(((start_s*60)+start_m)*60)+start_c | |
set /a end=(((end_s*60)+end_m)*60)+end_c | |
set /a elapsed=end-start | |
if %elapsed% geq %MAX_WAIT_TIME% ( | |
echo Timeout: Operation did not complete within %MAX_WAIT_TIME% seconds. | |
exit /b 1 | |
) | |
exit /b 0 | |
:restart | |
call :stop | |
call :start_background | |
goto :eof | |
:usage | |
echo Usage: %~nx0 {start^|background^|stop^|restart} | |
exit /b 1 | |
:eof | |
endlocal |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path | |
$ComfyDir = Join-Path $ScriptDir "ComfyUI" | |
$VenvPath = Join-Path $ComfyDir ".venv" | |
$PidFile = Join-Path $ScriptDir "comfyui.pid" | |
$LogFile = Join-Path $ScriptDir "comfyui.log" | |
$MaxWaitTime = 60 # Maximum wait time in seconds | |
function Start-Background { | |
Write-Host "Starting ComfyUI in the background..." | |
$env:VIRTUAL_ENV = $VenvPath | |
$env:PATH = "$VenvPath\Scripts;$env:PATH" | |
$process = Start-Process -FilePath "python" -ArgumentList "-s", "$ComfyDir\main.py", "--listen", "--preview-method", "auto" -RedirectStandardOutput $LogFile -RedirectStandardError $LogFile -PassThru -NoNewWindow | |
$process.Id | Out-File -FilePath $PidFile | |
Write-Host "ComfyUI started in background. PID: $($process.Id)" | |
Wait-ForComfyUIReady | |
} | |
function Start-Foreground { | |
Write-Host "Starting ComfyUI in the foreground..." | |
$env:VIRTUAL_ENV = $VenvPath | |
$env:PATH = "$VenvPath\Scripts;$env:PATH" | |
& python -s "$ComfyDir\main.py" --listen --preview-method auto | |
} | |
function Stop-ComfyUI { | |
if (Test-Path $PidFile) { | |
$ComfyPID = Get-Content $PidFile | |
Write-Host "Stopping ComfyUI (PID: $ComfyPID)..." | |
Stop-Process -Id $ComfyPID -Force | |
Wait-ForComfyUIStop $ComfyPID | |
Remove-Item $PidFile | |
Write-Host "ComfyUI stopped." | |
} else { | |
Write-Host "ComfyUI is not running in the background." | |
} | |
} | |
function Wait-ForComfyUIReady { | |
Write-Host "Waiting for ComfyUI to be fully operational..." | |
$startTime = Get-Date | |
while ($true) { | |
if (Select-String -Path $LogFile -Pattern "Starting server" -Quiet) { | |
Write-Host "ComfyUI is now fully operational." | |
return | |
} | |
$elapsedTime = (Get-Date) - $startTime | |
if ($elapsedTime.TotalSeconds -ge $MaxWaitTime) { | |
Write-Host "Timeout: ComfyUI did not start within $MaxWaitTime seconds." | |
return | |
} | |
Start-Sleep -Seconds 1 | |
} | |
} | |
function Wait-ForComfyUIStop { | |
param($ComfyPID) | |
Write-Host "Waiting for ComfyUI to stop..." | |
$startTime = Get-Date | |
while (Get-Process -Id $ComfyPID -ErrorAction SilentlyContinue) { | |
$elapsedTime = (Get-Date) - $startTime | |
if ($elapsedTime.TotalSeconds -ge $MaxWaitTime) { | |
Write-Host "Timeout: ComfyUI did not stop within $MaxWaitTime seconds. Forcing stop." | |
Stop-Process -Id $ComfyPID -Force | |
break | |
} | |
Start-Sleep -Seconds 1 | |
} | |
} | |
switch ($args[0]) { | |
"start" { Start-Foreground } | |
"background" { Start-Background } | |
"stop" { Stop-ComfyUI } | |
"restart" { | |
Stop-ComfyUI | |
Start-Background | |
} | |
default { | |
Write-Host "Usage: $($MyInvocation.MyCommand.Name) {start|background|stop|restart}" | |
exit 1 | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env zsh | |
SCRIPT_DIR="${0:A:h}" | |
COMFY_DIR="$SCRIPT_DIR/ComfyUI" | |
VENV_PATH="$COMFY_DIR/.venv" | |
PID_FILE="$SCRIPT_DIR/comfyui.pid" | |
LOG_FILE="$SCRIPT_DIR/comfyui.log" | |
MAX_WAIT_TIME=60 # Maximum wait time in seconds | |
start_background() { | |
echo "Starting ComfyUI in the background..." | |
source "$VENV_PATH/bin/activate" | |
nohup python -s "$COMFY_DIR/main.py" --listen --preview-method auto > "$LOG_FILE" 2>&1 & | |
echo $! > "$PID_FILE" | |
echo "ComfyUI started in background. PID: $(cat "$PID_FILE")" | |
wait_for_comfyui_ready | |
} | |
start_foreground() { | |
echo "Starting ComfyUI in the foreground..." | |
source "$VENV_PATH/bin/activate" | |
python -s "$COMFY_DIR/main.py" --listen --preview-method auto | |
} | |
stop() { | |
if [[ -f "$PID_FILE" ]]; then | |
PID=$(cat "$PID_FILE") | |
echo "Stopping ComfyUI (PID: $PID)..." | |
kill "$PID" | |
wait_for_comfyui_stop | |
rm "$PID_FILE" | |
echo "ComfyUI stopped." | |
else | |
echo "ComfyUI is not running in the background." | |
fi | |
} | |
wait_for_comfyui_ready() { | |
echo "Waiting for ComfyUI to be fully operational..." | |
local start_time=$(date +%s) | |
while true; do | |
if grep -q "Starting server" "$LOG_FILE"; then | |
echo "ComfyUI is now fully operational." | |
return 0 | |
fi | |
local current_time=$(date +%s) | |
local elapsed_time=$((current_time - start_time)) | |
if [[ $elapsed_time -ge $MAX_WAIT_TIME ]]; then | |
echo "Timeout: ComfyUI did not start within $MAX_WAIT_TIME seconds." | |
return 1 | |
fi | |
sleep 1 | |
done | |
} | |
wait_for_comfyui_stop() { | |
echo "Waiting for ComfyUI to stop..." | |
local start_time=$(date +%s) | |
while kill -0 "$PID" 2>/dev/null; do | |
local current_time=$(date +%s) | |
local elapsed_time=$((current_time - start_time)) | |
if [[ $elapsed_time -ge $MAX_WAIT_TIME ]]; then | |
echo "Timeout: ComfyUI did not stop within $MAX_WAIT_TIME seconds. Forcing stop." | |
kill -9 "$PID" | |
break | |
fi | |
sleep 1 | |
done | |
} | |
case "$1" in | |
start) | |
start_foreground | |
;; | |
background) | |
start_background | |
;; | |
stop) | |
stop | |
;; | |
restart) | |
stop | |
start_background | |
;; | |
*) | |
echo "Usage: $0 {start|background|stop|restart}" | |
exit 1 | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment