
    `gjH                        d Z ddlmZ ddlZddlZdddZddZddZddZddZ	dd	Z
dd
ZddZddZddZddZd dZd!dZd"dZd#dZd$dZd%dZddd&dZd'dZd(dZd)dZd*dZy)+u}  CLI subcommand: ``hermes pets <subcommand>``.

Thin shell around :mod:`agent.pet`.  Browses the public petdex gallery,
installs pets into the profile's ``pets/`` directory, selects the active
mascot (writes ``display.pet.*`` to config.yaml), and runs a doctor check.

No side effects at import time — ``main.py`` wires the argparse subparsers on
demand via :func:`register_cli`.
    )annotationsNc                    t        |        y N)printmsgs    B/root/.hermes/venv/lib/python3.12/site-packages/hermes_cli/pets.py_printr
      s	    	#J    c                :    t        | t        j                         y )N)file)r   sysstderrr   s    r	   _errr      s    	#CJJr   c                <   ddl m} t        | dd      rd|j                         }|st	        d       yt	        dt        |       d       |D ](  }t	        d|j                  d	d
|j                          * yddlm	}m
} 	  |       }t        | dd      xs dj                         j                         }|rG|D 	cg c]<  }	||	j                  j                         v s||	j                  j                         v r|	> }}	t        | dd      xs d}
|
dkD  r|d|
 n|}|j                         D ch c]  }|j                   }}t	        dt        |       d|rdt        |      z   nd d       |D ]K  }|j                  |v rdnd
}t	        d| d
|j                  dd
|j                   d|j                   d	       M |
r)t        |      |
kD  rt	        dt        |      |
z
   d       t	        d       y# |$ r}t        d|        Y d}~yd}~ww xY wc c}	w c c}w )z@List gallery pets (or only installed ones with ``--installed``).r   store	installedFz0No pets installed. Try: hermes pets install bobazInstalled pets (z):  <24 ManifestErrorfetch_manifest   ✗ N   query limitu   petdex gallery — z pet(s)z
 matching :u   ✓z<28z  ()u     … z* more (use --limit 0 or --query to filter)z-
Install one with: hermes pets install <slug>)	agent.petr   getattrinstalled_petsr
   lenslugdisplay_nameagent.pet.manifestr   r   r   striplowerreprkind)argsr   petspetr   r   entriesexcr   er   shownpr   entrymarks                   r	   	_cmd_listr7      s(   t[%(##%EF!#d)B/0 	;CR~Qs'7'7&89:	;@ "
 T7B'-2446<<>E 
&%1>>3G3G3I*I 
 
 D'1%*E$qyGFUOgE!&!5!5!78A8I8
 WgTYlT%[6P_a5bbcde R

i/uSD65::c*!E,>,>+?s5::,aPQR W%Gu,--WXY
;</  tC5\
 9s%   G4 ;AH-H4H9HHc                   ddl m} ddlm} | j                  j                         }	 |j                  |t        | dd            }t        d	|j                   d
|j                          t        | dd      s
t               s(t        |       t        d|j                   d| d       yt        d|        y# |j                  |f$ r}t        d|        Y d }~yd }~ww xY w)Nr   r   )r   forceF)r9   u   ✗ install failed: r   u   ✓ installed u    → selectu   ✓ z) is now the active pet (display.pet.slug=
, enabled)z*  Make it active with: hermes pets select )r"   r   r(   r   r&   r)   install_petr#   PetStoreErrorr   r
   r'   	directory_has_active_pet_set_active)r-   r   r   r&   r/   r1   s         r	   _cmd_installrA   E   s    099??DGD'5,IJ
 ^C,,-U3==/BCtXu%_->Dc&&''PQUPVV`ab  	;D6BC / #C5)*s   B9 9C"
CC"c                    ddl m} | j                  j                         }|j	                  |      rt        d|        yt        d| d       y)Nr   r   u   ✓ removed    ✗ 'z' is not installedr   )r"   r   r&   r)   
remove_petr
   r   )r-   r   r&   s      r	   _cmd_removerE   Z   sJ    99??DdV$%5(	)*r   c                Z   ddl m} t        | dd      xs dj                         }|s,|j	                         }|st        d       yt        |      }|sy|j                  |      }||j                  st        d| d|        yt        |       t        d	|j                   d
| d       y)Nr   r   r&   r   u7   ✗ no pets installed — run: hermes pets install bobar   rC   u0   ' is not installed — run: hermes pets install u   ✓ active pet set to z (display.pet.slug=r;   )r"   r   r#   r)   r$   r   _interactive_pickload_petexistsr@   r
   r'   )r-   r   r&   r.   r/   s        r	   _cmd_selectrJ   e   s    D&"%+224D##%JK &
..
C
{#**uTFJ4&QR
#C$4$4#55HjYZr   c                0    t        d       t        d       y)NFu,   ✓ pet disabled (display.pet.enabled=false)r   )_set_enabledr
   )r-   s    r	   _cmd_offrM   |   s    
9:r   c                v    t        | j                        \  }}|rt        d|        yt        d|dd       y)uA   Persist ``display.pet.scale`` — one knob resizes every surface.r   r   u   ✓ pet scale set to gz (display.pet.scale)r   )set_pet_scalefactorr   r
   )r-   scaleerrs      r	   
_cmd_scalerT      s@    t{{+JE3
tC5\
"5)+?@Ar   c                	  ! ddl }ddlm} ddlm}m}m}m}m} ddl	m
} t               }	t        | dd      xs dj                         xs t        |	j                  dd      xs d      }
|j!                  |
      }|t#        d       y	t        | d
d      xs t        |	j                  dd      xs d      }t%        t        | dd      xs |	j                  d|      xs |      } |||	j                  dd            } ||j&                  |||      }|j(                  st#        d|j*                   d       y	t        | dd      xs dj                         j-                         }|r|g}nSt        | dd      r/|D cg c]!  }||D ch c]  }|j.                   c}v s |# }}}n|j0                  j.                  g}|j*                  dk(  }t3        d|dz  t3        d	|j5                  |d         xs d	      z        }ddl}|j9                  d      j:                  }d!d}|rdt3        d||z
  d	z
        z  !nDt3        d	t=        |j>                  |j@                  z        dz        }dt3        d||z
  d	z
        z  }tB        jD                  }|jG                  d       |jI                          d}	 tK        |jL                   d|j*                   d       d}	 |D ]?  }|j5                  |      xs d	}tO        |      D ]  }|jQ                  ||      } |ry!r)djS                  !fd| jU                  d      D              } |r|jG                  d | d!       |jG                  |        |jG                  d"       | jW                  d      d	z   }ng|jG                  d#       |jG                  |jL                   d$| d%       |r|jG                  |       |jG                  |        |jG                  d       |jI                          |jY                  |        B |d	z  }t        | d&d      r|t[        |      k\  rnh	 |jG                  d'       |jG                  d"       |jI                          yc c}w c c}}w # t\        $ r Y Iw xY w# |jG                  d'       |jG                  d"       |jI                          w xY w)(u	  Animate the active (or named) pet in the terminal.

    Uses the shared :class:`~agent.pet.render.PetRenderer` — full graphics
    protocol (kitty/iTerm2/sixel) when the terminal supports it, else a
    truecolor Unicode half-block fallback.  Ctrl+C to stop.
    r   Nr   )DEFAULT_SCALELOOP_MS
STATE_ROWSPetStateresolve_cols)build_rendererr&   r   u4   ✗ no pet to show — run: hermes pets install bobar   moderender_modeautorR   unicode_cols)configured_moderR   r_   uE   ✗ cannot render here (no TTY / graphics disabled). Effective mode: .statecycleFunicodeg?g     @@)P      r      z[?25lu
    — mode=z  (Ctrl+C to stop)
c              3  (   K   | ]	  }|z     y wr    ).0lnindents     r	   	<genexpr>z_cmd_show.<locals>.<genexpr>   s     /Z/Zs   z[Fz[0m
z[2J[3J[Hz [z]
oncez[?25h)/timer"   r   agent.pet.constantsrV   rW   rX   rY   rZ   agent.pet.renderr[   _pet_configr#   r)   strgetresolve_active_petr   floatspritesheet	availabler\   r*   valueIDLEmaxframe_countshutilget_terminal_sizecolumnsintframe_wrR   r   stdoutwriteflushr
   r'   rangeframejoinsplitcountsleepr%   KeyboardInterrupt)"r-   rq   r   rV   rW   rX   rY   rZ   r[   cfgr&   r/   mode_cfgrR   colsrenderer	requestedstatessr2   
is_unicodeframe_delayr   	term_colsg_indent	cell_colsout
prev_linesloopsrb   r   iencodedrm   s"                                    @r	   	_cmd_showr      s`    ^^/
-CD&"%+224VCGGFB<O<USU8VD

"
"4
(C
{CDtVT*[c#''-2P2ZTZ.[H'$+_swww/N_R_`Esww~q9:D 	H '}}oQ0	
  w+1r88:@@BI	w	&'L1(0KQ0K+K!LL--%%&)+JdWv-Q8L8LVTUY8W8\[\1]]^K
 ((2::IFHs1i$.2333x//(..@AQFG	Q	I 5 9::
**CIIkIIKJ##""#:hmm_<NOP , ,,U38qu ,A&nnUA6G!!&*ii/ZgmmTXFY/Z&ZG%IIj\&;<		'*		+. &-]]4%81%<
		"89		S%5%5$6bs"CD#IIh/		'*		$IIKJJ{+),,. QJEtVU+V0D5 4  			+		+		{ 1LLn   			+		+		sI   ?
Q=	Q8Q=!Q=4FR R 8Q=	RR RR 4Sc           	        ddl m} ddlm}m} t               }t        |j                  d            }t        |j                  dd      xs d      }t        |j                  dd      xs d      }|j                         }|j                  |      }	t        d	       t        d
|j                                 t        dt        |       ddj                  d |D              xs d d       t        d|        t        d|xs d        t        d|	r|	j                  nd        t        d|        t        d |               t        d ||              d}
|st        d       d}
n*|	t        d       d}
n|st        d|	j                  z          	 ddl}t        |
r	|rd        yd!       y# t"        $ r t        d       d}
Y /w xY w)"zBReport install state, active pet, config, and terminal capability.r   r   )detect_terminal_graphicsresolve_modeenabledr&   r   r]   r^   zpetdex doctorz  pets dir:        z  installed:       z (z, c              3  4   K   | ]  }|j                     y wr   )r&   )rk   r4   s     r	   rn   z_cmd_doctor.<locals>.<genexpr>  s     7M17Ms   noner!   z  display.pet.enabled:     z  display.pet.slug:        z(unset)z  active (resolved):       z(none)z  display.pet.render_mode: z  detected graphics:       z  effective mode (TTY):    Tu6     → no pets installed. Run: hermes pets install bobaFNu;     → active pet unresolved. Run: hermes pets select <slug>u7     → pet display is disabled. Run: hermes pets select uC     ✗ Pillow not importable — sprite decoding will be unavailableu     ✓ readyz-  (run the suggestions above to finish setup))r"   r   rs   r   r   rt   boolrv   ru   r$   rw   r
   pets_dirr%   r   r&   PILImportError)r-   r   r   r   r   r   configured_slugr   r.   activeokr   s               r	   _cmd_doctorr      s   G
-C3779%&G#''&"-34O377=&1;V<H!D%%o6F
?
 !1 234
 T2dii7M7M.M.WQW-XXYZ[
(	23
()EI(FGH
(H(MNO
(
34
()A)C(DEF
(h)?(@AB	BGH	LMH6;;VW
 B7=` 1``  TUs   F7 7GGc                     ddl m}   |        }t        |j                  d      t              r|j                  di       ni }|j                  di       }t        |t              r|S i S )Nr   )load_configdisplayr/   )hermes_cli.configr   
isinstancerv   dict)r   r   r   r/   s       r	   rt   rt   %  sU    -
-C(237793Et(Lcggi$RTG
++eR
 CS$'3/R/r   c                     t        t               j                  d            xr" t        t               j                  d            S )Nr   r&   )r   rt   rv   rj   r   r	   r?   r?   .  s1    !!),-Q${}7H7H7P2QQr   c                    ddl m}m}  |       }|j                  di       }|j                  di       }| |d<   d|d<    ||       y )Nr   r   save_configr   r/   r&   Tr   r   r   r   
setdefault)r&   r   r   r   r   r/   s         r	   r@   r@   2  sH    :
-CnnY+G


UB
'CCKC	Nr   c                    ddl m}m}  |       }|j                  di       }|j                  di       }| |d<    ||       y )Nr   r   r   r/   r   r   )r   r   r   r   r   r/   s         r	   rL   rL   =  s?    :
-CnnY+G


UB
'CC	Nr   c                    ddl m}m}  |       }|j                  di       }|j                  di       }| |d<    ||       y )Nr   r   r   r/   rR   r   )rR   r   r   r   r   r/   s         r	   
_set_scaler   G  s?    :
-CnnY+G


UB
'CCLr   c                    ddl m} 	  |t        |             }t        |       |dfS # t        t        f$ r dd| dfcY S w xY w)a3  Set ``display.pet.scale`` (clamped to bounds). Returns ``(applied, error)``.

    The single write path behind ``/pet scale`` and the desktop slider, so every
    surface that resolves scale from config picks it up identically. *error* is
    set (and nothing written) only when *value* isn't a number.
    r   )clamp_scaleg        znot a number: u    — try a value like 0.5N)rr   r   rx   	TypeError
ValueErrorr   )r{   r   rR   s      r	   rP   rP   Q  s\     0HE%L) u$;	 z" HnUI-FGGGHs   ( AAc                    ddl m}  t               }t        |j	                  dd      xs d      }| j                  |      }t        |j	                  d            r t        d       d|r|j                  dfS ddfS |.| j                         }|sy|d   }t        |j                         nt        d	       d	|j                  dfS )
zToggle ``display.pet.enabled``.

    Returns ``(enabled, display_name, error_message)``. *error_message* is set
    when turning on but nothing is installed to show.
    r   r   r&   r   r   FN)FNuB   no pets installed — /pet list to browse, or /pet <slug> to adoptT)r"   r   rt   ru   rv   rw   r   rL   r'   r$   r@   r&   )r   r   r&   r/   r   s        r	   toggle_pet_displayr   c  s      
-Cswwvr"(b)D

"
"4
(CCGGIU#c&&==4==
{((*	dlCHHT!!4''r      )r   c           	        ddl m} ddlm}m} 	  |       }|j                         D ch c]  }|j                   }}| dkD  r|d|  n|}t        dt        |       dt        |       d       |D ]=  }	|	j                  |v rd	nd
}
t        d|
 d|	j                  dd|	j                          ? t        d       y# |$ r}t        d|        Y d}~yd}~ww xY wc c}w )zCPrint a slice of the public petdex gallery (CLI/TUI text fallback).r   r   r   z)(._.) Couldn't reach the petdex gallery: Nu    (^o^)/ petdex gallery — first z of r    u   ●u   ○r   r   r   u(     /pet <slug> to adopt · /pet to toggle)
r"   r   r(   r   r   r   r$   r&   r%   r'   )r   r   r   r   r0   r1   r4   r   r3   r5   r6   s              r	   print_pet_galleryr   ~  s    @ "
 "'!5!5!78A8I8$qyGFUOgE	,SZLS\N!
LM A

i/uU4&%**S)5+=+=*>?@A 

45  9#?@ 9s   B< C<CCCc                    ddl m}m}  |       }|j                  di       j                  di       }t	        |t
              r"t        |j                  dd      xs d      | k7  ryd|d<   d|d<    ||       y	)
zDisable + unset the active pet iff it's ``slug`` (e.g. after removal).

    Returns whether anything changed, so callers don't write config needlessly.
    r   r   r   r/   r&   r   Fr   Tr   r   r   r   r   r   ru   rv   )r&   r   r   r   r/   s        r	   _clear_active_ifr     sq    
 ;
-C
..B
'
2
25"
=Cc4 C(;(Ar$Bd$JCKC	Nr   c                    |r| |k(  ryddl m}m}  |       }|j                  di       j                  di       }t	        |t
              r"t        |j                  dd      xs d      | k7  ry||d<    ||       y)	a1  Repoint the active pet from ``old_slug`` to ``new_slug`` iff it's active.

    Used when a rename realigns a pet's slug/dir: if the renamed pet was the
    active one, the config must follow or surfaces point at a now-missing dir.
    Preserves the ``enabled`` flag. Returns whether anything changed.
    Fr   r   r   r/   r&   r   Tr   )old_slugnew_slugr   r   r   r/   s         r	   _rename_active_ifr     su     x8+:
-C
..B
'
2
25"
=Cc4 C(;(Ar$Bh$NCKr   c           	        t        d       t        | d      D ].  \  }}t        d| d|j                  dd|j                          0 	 t	        d      j                         xs d}t        |      dz
  }d|cxk  rt        |       k  rn n| |   j                  S t        d       y
# t        t        t        f$ r t        d	       Y y
w xY w)z<Minimal numbered picker (avoids curses dep for a tiny list).zInstalled pets:r   r   z. r   r   zSelect a pet [1]: 1u   ✗ cancelledr   r   u   ✗ invalid selection)r
   	enumerater&   r'   inputr)   r   EOFErrorr   r   r   r%   )r.   r   r/   choiceidxs        r	   rG   rG     s    
D!$ <3A3b#a(8(8'9:;<+,224;&kAo 	C#d)Cy~~	 ! '4 _s   
+B' 'C	C	c                H     j                   fd        j                  d      }|j                  dd      }|j                  dd	d
d       |j                  ddd       |j                  dt        dd       |j                  t
               |j                  dd      }|j                  dd       |j                  ddd       |j                  ddd       |j                  t               |j                  dd      }|j                  dd	d
d       |j                  t               |j                  d d!      }|j                  dd	d
d"       |j                  d#d
d$%       |j                  d&dd'       |j                  d(dd)       |j                  d*d+d,%       |j                  d-t        d.d/       |j                  t               |j                  d0d1      j                  t               |j                  d2d3      }|j                  d4d5       |j                  t               |j                  d6d7      }|j                  dd8       |j                  t               |j                  d9d:      j                  t               y+);z<Attach ``pets`` subcommands to *parent* (called by main.py).c                .    j                         dfd   S )Nr   r   )
print_help)aparents    r	   <lambda>zregister_cli.<locals>.<lambda>  s    (9(9(;Q'?'B r   )funcpets_command)destlistzBrowse the petdex gallery)helpr   ?r   zFilter by slug/name substring)nargsdefaultr   z--installed
store_truezOnly show installed pets)actionr   z--limit(   zMax rows (0 = all))typer   r   installzInstall a pet from the galleryr&   zPet slug (e.g. boba)z--forcezRe-download even if presentz--selectzMake it the active petr:   z)Set the active pet (writes display.pet.*)zPet slug (omit for picker)showz&Animate the active pet in the terminalzPet slug (default: active)z--statez.Single state: idle/run/review/failed/wave/jump)r   r   z--cyclezCycle through all statesz--oncezPlay once instead of loopingz--modeNz5Override render mode (kitty/iterm/sixel/unicode/auto)z--scaler   zOverride scale (0 = config)offzDisable the pet displayrR   z-Resize the pet everywhere (display.pet.scale)rQ   u*   Scale factor, e.g. 0.5 (clamped 0.1–3.0)removezDelete an installed petzPet slugdoctorz+Check pet setup + terminal graphics support)set_defaultsadd_subparsers
add_parseradd_argumentr   r7   rA   rJ   rx   r   rM   rT   rE   r   )r   subsp_list	p_installp_selectp_showp_scalep_removes   `       r	   register_clir     s   
BC  n 5D__V*E_FF
sB=\]
lA[\
	R>RS
Y'	0PQI6(>?9\@]^:lAYZ-x.YZH&R>Z[{+__V*R_SF
c2<XY
	24de
	,=WX
<Z[
$5lm
	q?\]
Y'OOE 9O:GGXGVoog,[o\G(TUj)x.GHH&z2{+OOH#POQ^^ _ r   )r   )r   ru   returnNone)r   r   )r   r   )r   r   )r&   ru   r   r   )r   r   r   r   )rR   rx   r   r   )r{   zfloat | strr   ztuple[float, str | None])r   z#tuple[bool, str | None, str | None])r   r   r   r   )r&   ru   r   r   )r   ru   r   ru   r   r   )r   ru   )r   zargparse.ArgumentParserr   r   )__doc__
__future__r   argparser   r
   r   r7   rA   rE   rJ   rM   rT   r   r   rt   r?   r@   rL   r   rP   r   r   r   r   rG   r   rj   r   r	   <module>r      s    #  
 )X*.gT(^0R$(6 ') 6("(**r   