+
    #j)                       R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RI	H
t
 ]P                  P                  ^ ]! ]! ]4      P                  4       P                   4      4       ^ RIHtHtHtHtHtHt ^t^t^t^t^tRtRtRtR	t R
t!Rt"Rt#RR/R R llt$R R lt%RR R llt&]'R8X  d   ]PP                  ! ]&! 4       4       R# R# )ud  
ws_monitor.py — Real-time ComfyUI WebSocket monitor.

Connects to /ws and pretty-prints execution events: node start/finish, sampling
progress, cached nodes, errors. Optionally writes preview frames to disk.

Useful for:
  - Watching a long-running job in real time without parsing JSON yourself
  - Saving in-progress preview frames for video / animation workflows
  - Debugging "why is this hanging?" — see exactly which node is stuck

Usage:
    # Local — watch all jobs from this client_id
    python3 ws_monitor.py

    # Cloud — watch a specific prompt_id
    python3 ws_monitor.py --host https://cloud.comfy.org         --prompt-id abc-123-def

    # Save preview frames to ./previews/
    python3 ws_monitor.py --previews ./previews

Requires: websocket-client (`pip install websocket-client`).
Falls back to a clear error message when not installed.
)annotationsN)Path)urlparse)DEFAULT_LOCAL_HOSTENV_API_KEYlognew_client_idresolve_api_keyis_cloud_hostz[0mz[2mz[1mz[32mz[33mz[31mz[36mcolor_onTc               (    V ^8  d   QhRRRRRRRR/# )   sstrcolorr   boolreturn )formats   "d/opt/hermes-venv/lib/python3.14/site-packages/../../../skills/creative/comfyui/scripts/ws_monitor.py__annotate__r   >   s(     3 3 3S 3t 3s 3    c               .    V'       d   V V  \          2# T # N)RESET)r   r   r   s   &&$r   	fmt_colorr   >   s    #+eWQCw22r   c                    V ^8  d   QhRRRR/# )r   databytesr   zdict | Noner   )r   s   "r   r   r   B   s     *J *JU *J{ *Jr   c           	        \        V 4      ^8  d   R# \        P                  ! RV R,          4      ^ ,          pV\        8X  dS   \        P                  ! RV R,          4      ^ ,          pV\        8X  d   RMV\
        8X  d   RMRpRR	R
VRVRV R,          /# V\        8X  d   \        V 4      ^8  d   R# \        P                  ! RV R,          4      ^ ,          p^V,           p\        V 4      V8  d   R#  \        P                  ! V ^V P                  R4      4      pRRRVRWR RR/# V\        8X  d   \        V 4      ^8  d   R# \        P                  ! RV R,          4      ^ ,          p^V,           p\        V 4      V8  d   R# RRRV ^V P                  RR4      RWR P                  RR4      /# RRRVR\        V 4      /#   \         d"    RT ^T R,          P                  RR4      /p Li ; i)   Nz>I:       N:r"   r    Njpgpngbinkindpreview
image_typeextimage_bytes:r    NNzutf-8rawN   Nreplacepreview_with_metadatametadatatextnode_idunknown	type_codesize)lenstructunpackBINARY_PREVIEW_IMAGEIMAGE_TYPE_JPEGIMAGE_TYPE_PNG"BINARY_PREVIEW_IMAGE_WITH_METADATAjsonloadsdecode	ExceptionBINARY_TEXT)	r   r4   r(   r)   meta_lenmeta_endmetanid_lennid_ends	   &        r   parse_binary_framerG   B   s   
4y1}dDI.q1I((]]4c3A6
!_4e:Q_C_%ejI*348	
 	
 66t9r>==tCy1!4x<t9x	N::d1X.55g>?D +4	?5	
 	
 Kt9q=--d3i03g+t9wFtAg--gyADN))'9=
 	

 I{Ivs4yII)  	N4(+D188)LMD	Ns   3(G )G.-G.c                    V ^8  d   QhRRRR/# )r   argvzlist[str] | Noner   intr   )r   s   "r   r   r   o   s     X X X3 Xr   c                   \         P                  ! R R7      pVP                  R\        RR7       VP                  RR\         R2R7       VP                  R	R
RR7       VP                  RR
RR7       VP                  RR
RR7       VP                  RRRR7       VP                  R\
        RRR7       VP                  V 4      p ^ R
Ip\        TP                  4      p\        TP                  4      pTP                   ;'       g    \#        4       p\%        RTP                  9   d   TP                  MRTP                   24      pTP&                  R8X  d   RMR pTP(                  p	TP*                  P-                  R!4      p
T RT	 T
 R"T 2pT'       d   T'       d   TR#T 2,          pTP.                  '       * ;'       d    \0        P2                  P5                  4       pTP6                  '       d$   \9        TP6                  4      P;                  4       MR
pT'       d"   TP=                  R$R$R%7       \?        R&T 24       \?        R'T R(T R)24       TP@                  '       d   \?        R*TP@                   24       TPC                  YPD                  R+7      pTPG                  TPD                  4       ^ p   TPI                  4       p\Q        T\R        4      '       d   \U        T4      pTf   K9  TR.,          Ro9   d   T'       d|   TPW                  R/R04      pT'       db   TPW                  R1R24      pTR3TR4 R5T 2,          pTPY                  T4       T^,          p\?        R6TPZ                   R7\]        T4       R824       K   \        P^                  ! T4      pTPW                  R9R:4      pTPW                  R;/ 4      ;'       g    / pTPW                  R<4      pTP@                  '       d   T'       d   TTP@                  8w  d   EKP  TR=8X  dT   TPW                  R=/ 4      PW                  R>/ 4      PW                  R?R@4      p\        \a        RAT 2\b        TRB7      4       EK  TRC8X  d"   \        \a        RDT 2\d        TRB7      4       EK  TRE8X  d\   TPW                  RF4      pT'       d"   \        \a        RGT 2\f        TRB7      4       EK  \        \a        RHT 2\b        TRB7      4       EK4  TRI8X  di   TPW                  RJ^ 4      TPW                  RK^ 4      ppT'       d   TT,          ^d,          M^ p\        RLT R!T R7TRM RNTPW                  RF4       24       EK  TRO8X  d   TPW                  RP4      ;'       g    / pTPi                  4        UUu. uF!  w  ppTPW                  RQ4      '       g   K  TNK#  	  pppT'       d"   \        \a        RRT 2\b        TRB7      4       EK+  EK.  TRS8X  d   TPW                  RF4      pTPW                  RT4      ;'       g    / p. p Rp FB  p!TPW                  T!4      '       g   K  T Pk                  T! RU\]        TT!,          4       24       KD  	  T '       d   RVPm                  T 4      MRWp"\        \a        RXT RYT" 2\n        TRB7      4       EK  TRZ8X  dR   TPW                  RP4      ;'       g    . p#T#'       d,   \        \a        R[\]        T#4       R\2\b        TRB7      4       EK?  EKB  TR]8X  dS   \        \a        R^T 2\n        \d        ,           TRB7      4       TP@                  '       d     TPM                  4        ^ # EK  TR_8X  d   TPW                  R`R@4      p$TPW                  RaR@4      p%\        \a        RbT$ RcT% 2\p        \d        ,           TRB7      4       TPW                  Rd4      p&T&'       d]   \Q        T&\r        4      '       d)   T& F!  p'\        \a        ReT' 2\p        TRB7      4       K#  	  M\        \a        ReT& 2\p        TRB7      4       TP@                  '       d     TPM                  4        ^# EK  TRf8X  dH   \        \a        RgT 2\t        TRB7      4       TP@                  '       d     TPM                  4        ^# EK  TRh8X  d4   TPW                  RJR:4      p\        \a        RiT 2\b        TRB7      4       EK  \        \a        RjT Rk\        P                  ! T\v        Rl7      Rm,           2\b        TRB7      4       EK]    \         d(    \        \        P                  ! RRRR/4      4        ^# i ; i  TPJ                   dA    \?        R,TPD                   R-24         TPM                  4        ^ #   \N         d     ^ # i ; ii ; i  \N         d     EK  i ; iu uppi   \N         d     ^ # i ; i  \N         d     ^# i ; i  \N         d     ^# i ; i  \x         d3    \?        Rn4         TPM                  4        ^#   \N         d     ^# i ; ii ; i   TPM                  4        i   \N         d     i i ; i; i)qz#Real-time ComfyUI WebSocket monitor)descriptionz--hostzComfyUI server URL)defaulthelpz	--api-keyzAPI key for cloud (or set $z	 env var))rN   z--client-idNz Client ID (default: random UUID)z--prompt-idz2Filter to a specific prompt_id (default: all jobs)z
--previewsz,Directory to save in-progress preview framesz
--no-color
store_truezDisable ANSI colour)actionrN   z	--timeoutg     @z+Hard cap on monitor duration (default 600s))typerM   rN   errorzwebsocket-client not installedinstallzpip install websocket-clientz://zhttp://httpswssws/z/ws?clientId=z&token=T)parentsexist_okzSaving previews to zConnecting to z (client_id=)z Filtering messages to prompt_id=)timeoutz	Idle for u   s — exitingr&   r*   r   r)   r$   preview_05d.z  [preview] saved z (z bytes)rQ    r   	prompt_idstatus	exec_infoqueue_remaining?z[status] queue_remaining=)r   execution_startz[start] prompt_id=	executingnodez  [executing] node=z(  [executing] (workflow done) prompt_id=progressvaluemaxz    [progress] z5.1fz%) node=progress_statenodesrunningz    [progress_state] running=executedoutput=z, z
(no files)z  [executed] node= execution_cachedz  [cached] z nodes skippedexecution_successz[success] prompt_id=execution_errorexception_typeexception_messagez[error] z: 	tracebackz  execution_interruptedz[interrupted] prompt_id=notificationz[notification] [z] )rM   r,   Interrupted>   r'   r/   )imagesvideovideosgifsaudiofiles)=argparseArgumentParseradd_argumentr   r   float
parse_args	websocketImportErrorprintr=   dumpsr	   api_keyr
   host	client_idr   r   schemenetlocpathrstripno_colorsysstdoutisattypreviewsr   
expandusermkdirr   r`   create_connectionr[   
settimeoutrecvWebSocketTimeoutExceptioncloser@   
isinstancer   rG   getwrite_bytesnamer6   r>   r   DIMBOLDCYANitemsappendjoinGREENREDlistYELLOWr   KeyboardInterrupt)(rI   pargsr   r   cloudr   parsedr   r   	base_pathws_urlr   preview_dirrV   preview_countermsg	img_bytesr)   outpayloadmtypemdatapidqrrg   vmpctrl   krm   summary_partskeysummarycachedexc_typeexc_msgtblines(   &                                       r   mainr   o   s   ,QRANN8%7>RNSNN;'B;-y%YNZNN=$5WNXNN=$L  NNN<F  HNN<;PNQNN;UEE  G<<D dll+G$))$E11-/I 5DII#5diiWTYYK;PQFmmw.UDF]]F""3'Ixs6(9+]9+FFGG9%%== 88SZZ%6%6%8H6:mmm$t}}%002K$6!+/0.YKq9:~~~.t~~.>?@		$	$V\\	$	BBMM$,,Oeggi #u%%+C0>&>%IIk &

=# >I $jj6)hs6K1SE,RR	2'1,0
"S^<LGTU**S/ KK+EKK+11rE))K(C~~~##*? YYx,00bAEEFWY\]i";B4 @#PXYZ++i"4SE :D8TU+%yy()&9$$@$QYZ[)&Nse$TVYdlmn*$yy!,eiiq.A1'(q1us{as!A3bT
(599VCTBUVW**		'*00b).KA!%%	:J11K)&CG9$Ms]efg *$yy(ii)//R "RCwws||%,,uAc#c(m_-EF S 7D$))M2i"4TF!G9 EuW_`a,,7+11r)k#f+n$Ms]efg --i"6se <edlU]^_>>>:	HHJ? "++ 99%5s;))$7=i(8*Bwi @#*W_`aYY{+!"d++$&D!)bKx"PQ %' i"RD	3JK>>> 	HHJ% "11i":3% @&S[\]>>>	HHJ ".(IIgr*i/! 5sXNO i!E7"TZZs-KD-Q,R SUXcklm  djj55
  	 N 66 i~];<x	HHJ 		A&  6 Ld  		y 		y 		  M	HHJ 			HHJ 		sp  d 8g- :e
 
<g- g- !A#g- f *g- %g- ,g- 4B5g- *Cg- :g- f11f17Ag- g- 91g- +Ag- 
g- A0g- >f7 C g- 3g	 :g- g Bg- .ee
*f4g- 6f fffg- f.)g- -f..	g- 7gg	ggg*)g*-h*h- h h&%h&)h**h- -i/i ?i iiii__main__r   ))__doc__
__future__r   r   r=   r7   r   pathlibr   urllib.parser   r   insertr   __file__resolveparent_commonr   r   r   r   r	   r
   r9   rA   r<   r:   r;   r   r   r   r   r   r   r   r   rG   r   __name__exitr   r   r   <module>r      s   4 #    
  ! 3tH~--/667 8   %& "  		3d 3*JZXv zHHTV r   