+
    iM                       a  R% t:0 t R t^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H
t
 ^ RIHt ^ RIHtHtHt ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ R	IHt ]P:                  ! ]4      tR
t Rt!Rt"Rt#R R lt$R R lt%R R lt&^ RI'H(t)H*t+ Rt,Rt-Rt.R R lt/R&t0R R lt1Rs2] ^ k ]Pf                  ! 4       t4R t5R'R R llt6R R  lt7R! R" lt8R(R# R$ llt9R# ))zWelcome banner, ASCII art, skills summary, and update check for the CLI.

Pure display functions with no HermesCLI state dependency.
N)Path)get_hermes_home)DictListOptional)Console)Panel)Table)print_formatted_text)ANSIz[1;38;2;255;215;0mz[1mz[2mz[0mc                $    V ^8  d   QhR\         /# )   textstr)formats   "./home/ubuntu/hermes-agent/hermes_cli/banner.py__annotate__r   %   s           c                .    \        \        V 4      4       R# )z:Print ANSI-colored text through prompt_toolkit's renderer.N)	_pt_print_PT_ANSI)r   s   &r   cprintr   %   s    htnr   c                <    V ^8  d   QhR\         R\         R\         /# r   keyfallbackreturnr   )r   s   "r   r   r   .   s!      S C C r   c                b     ^ RI Hp V! 4       P                  W4      #   \         d    Tu # i ; i)z5Get a color from the active skin, or return fallback.get_active_skin)hermes_cli.skin_enginer    	get_color	Exceptionr   r   r    s   && r   _skin_colorr%   .   s2    : **399     ..c                <    V ^8  d   QhR\         R\         R\         /# r   r   )r   s   "r   r   r   7   s!       s s r   c                b     ^ RI Hp V! 4       P                  W4      #   \         d    Tu # i ; i)z?Get a branding string from the active skin, or return fallback.r   )r!   r    get_brandingr#   r$   s   && r   _skin_brandingr*   7   s2    : --c<< r&   )__version____release_date__u  [bold #FFD700]██╗  ██╗███████╗██████╗ ███╗   ███╗███████╗███████╗       █████╗  ██████╗ ███████╗███╗   ██╗████████╗[/]
[bold #FFD700]██║  ██║██╔════╝██╔══██╗████╗ ████║██╔════╝██╔════╝      ██╔══██╗██╔════╝ ██╔════╝████╗  ██║╚══██╔══╝[/]
[#FFBF00]███████║█████╗  ██████╔╝██╔████╔██║█████╗  ███████╗█████╗███████║██║  ███╗█████╗  ██╔██╗ ██║   ██║[/]
[#FFBF00]██╔══██║██╔══╝  ██╔══██╗██║╚██╔╝██║██╔══╝  ╚════██║╚════╝██╔══██║██║   ██║██╔══╝  ██║╚██╗██║   ██║[/]
[#CD7F32]██║  ██║███████╗██║  ██║██║ ╚═╝ ██║███████╗███████║      ██║  ██║╚██████╔╝███████╗██║ ╚████║   ██║[/]
[#CD7F32]╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝╚═╝     ╚═╝╚══════╝╚══════╝      ╚═╝  ╚═╝ ╚═════╝ ╚══════╝╚═╝  ╚═══╝   ╚═╝[/]u  [#CD7F32]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⡀⠀⣀⣀⠀⢀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#CD7F32]⠀⠀⠀⠀⠀⠀⢀⣠⣴⣾⣿⣿⣇⠸⣿⣿⠇⣸⣿⣿⣷⣦⣄⡀⠀⠀⠀⠀⠀⠀[/]
[#FFBF00]⠀⢀⣠⣴⣶⠿⠋⣩⡿⣿⡿⠻⣿⡇⢠⡄⢸⣿⠟⢿⣿⢿⣍⠙⠿⣶⣦⣄⡀⠀[/]
[#FFBF00]⠀⠀⠉⠉⠁⠶⠟⠋⠀⠉⠀⢀⣈⣁⡈⢁⣈⣁⡀⠀⠉⠀⠙⠻⠶⠈⠉⠉⠀⠀[/]
[#FFD700]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⡿⠛⢁⡈⠛⢿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#FFD700]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠿⣿⣦⣤⣈⠁⢠⣴⣿⠿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#FFBF00]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠻⢿⣿⣦⡉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#FFBF00]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢷⣦⣈⠛⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#CD7F32]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣴⠦⠈⠙⠿⣦⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#CD7F32]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣤⡈⠁⢤⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#B8860B]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠷⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#B8860B]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠑⢶⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#B8860B]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠁⢰⡆⠈⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#B8860B]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠳⠈⣡⠞⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#B8860B]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]u  
[bold #FFD700]╔══════════════════════════════════════════════════════════════╗[/]
[bold #FFD700]║[/]  [#FFBF00]⚕ NOUS HERMES[/] [dim #B8860B]- AI Agent Framework[/]              [bold #FFD700]║[/]
[bold #FFD700]║[/]  [#CD7F32]Messenger of the Digital Gods[/]    [dim #B8860B]Nous Research[/]   [bold #FFD700]║[/]
[bold #FFD700]╚══════════════════════════════════════════════════════════════╝[/]
c                \    V ^8  d   QhR\         \        \        \        ,          3,          /# r   r   )r   r   r   )r   s   "r   r   r   i   s       d3S	>2 r   c                      ^ RI Hp  V ! 4       p/ pT FF  pTP                  R4      ;'       g    RpTP	                  T. 4      P                  TR,          4       KH  	  T#   \         d    / u # i ; i)a  Return skills grouped by category, filtered by platform and disabled state.

Delegates to ``_find_all_skills()`` from ``tools/skills_tool`` which already
handles platform gating (``platforms:`` frontmatter) and respects the
user's ``skills.disabled`` config list.
)_find_all_skillscategorygeneralname)tools.skills_toolr0   r#   get
setdefaultappend)r0   
all_skillsskills_by_categoryskillr1   s        r   get_available_skillsr;   i   sw    6%'
 0299Z(55I%%h3::5=I    	s   A A/.A/c                :    V ^8  d   QhR\         \        ,          /# r.   )r   int)r   s   "r   r   r      s     9 98C= 9r   c            	        \        4       p V R,          pV R,          pVR,          P                  4       '       g2   \        \        4      P                  P                  P                  4       pVR,          P                  4       '       g   R# \        P                  ! 4       p VP                  4       '       dW   \        P                  ! VP                  4       4      pW4P                  R^ 4      ,
          \        8  d   VP                  R4      #  \        P                  ! . R
OR^
\        T4      R7        \        P                  ! . RORR^\        T4      R	7      pTP                   ^ 8X  d%   \#        TP$                  P'                  4       4      pMRp  TP)                  \        P*                  ! RTRT/4      4       T#   \         d     Li ; i  \         d     Li ; i  \         d    Rp L]i ; i  \         d     T# i ; i)zCheck how many commits behind origin/main the local repo is.

Does a ``git fetch`` at most once every 6 hours (cached to
``~/.hermes/.update_check``).  Returns the number of commits behind,
or ``None`` if the check fails or isn't applicable.
zhermes-agentz.update_checkz.gitNtsbehindT)capture_outputtimeoutcwd)rA   r   rB   rC   )gitfetchoriginz--quiet)rD   zrev-listz--countzHEAD..origin/main)r   existsr   __file__parentresolvetimejsonloads	read_textr5   _UPDATE_CHECK_CACHE_SECONDSr#   
subprocessrunr   
returncoder=   stdoutstrip
write_textdumps)hermes_homerepo_dir
cache_filenowcachedresultr@   s          r   check_for_updatesr]      s    "#K^+H.J v%%''>((//779v%%'' ))+CZZ
 4 4 67FZZa((+FFzz(++
1H	
?dAH

 !,,./FF
djj$Xv)FGH MC        MsV    F= 6AF= %G 3AG G )G2 =G
GGGG/.G/2H Hc                 \    R p \         P                  ! V RR7      pVP                  4        R# )z4Kick off update check in a background daemon thread.c                  B    \        4       s\        P                  4        R # N)r]   _update_result_update_check_doneset r   r   _run#prefetch_update_check.<locals>._run   s    *, r   T)targetdaemonN)	threadingThreadstart)re   ts     r   prefetch_update_checkrm      s$    ! 	T2AGGIr   c                F    V ^8  d   QhR\         R\        \        ,          /# )r   rB   r   )floatr   r=   )r   s   "r   r   r      s      u x} r   c                :    \         P                  V R7       \        # )z:Get result of prefetched check. Returns None if not ready.rB   )rb   waitra   rq   s   &r   get_update_resultrs      s    G,r   c                0    V ^8  d   QhR\         R\        /# )r   tokensr   )r=   r   )r   s   "r   r   r      s      3 3 r   c                p    V R8  d   V R,          pVR R2# V R8  d   V R,          pVR R2# \        V 4      # )uL   Format a token count for display (e.g. 128000 → '128K', 1048576 → '1M').i@B gMi  Kr   )ru   vals   & r   _format_context_lengthr{      sJ    y a{	5una{v;r   c                0    V ^8  d   QhR\         R\         /# )r   toolset_namer   r   )r   s   "r   r   r      s        r   c                R    V '       g   R# V P                  R4      '       d   V RR # T # )zANormalize internal/legacy toolset identifiers for banner display.unknown_toolsNi)endswith)r}   s   &r   _display_toolset_namer      s6       ** 	Sb r   c                    V ^8  d   QhR\         R\        R\        R\        \        ,          R\        \        ,          R\        R\        /# )r   consolemodelrC   toolsenabled_toolsets
session_idcontext_length)r   r   r   dictr=   )r   s   "r   r   r      sV     \ \' \# \C \ $T
\+/9\ &)\
 *-\r   c                   ^ RI HpHp	 Vf   ^ RI Hp T;'       g    . pT;'       g    . pV! RR7      w  r\	        4       p\	        4       pV Ft  pVP                  RR4      pV	P                  V/ 4      pVP                  R. 4      pVP                  R	4      '       d   VP                  V4       Kc  VP                  V4       Kv  	  \        P                  ! RdR
7      pVP                  RRR7       VP                  RRR7       \        RR4      p\        RR4      p\        RR4      p\        RR4      p ^ RIHp V! 4       p\        VR4      '       d   VP                  '       d   VP                  M\        pRVR.pRV9   d   VP#                  R4      Re,          MTpVP%                  R4      '       d   VRRf p\'        V4      ^8  d   VR,          R,           pV'       d   RV RV R\)        V4       R 2MRpVP+                  R!V RV R"V RV RV R#24       VP+                  R$V RV R"24       V'       d   VP+                  R$V R%V R"24       R&P-                  V4      pR'V R(2.p/ pV FO  p V R),          R,          p!\/        V! V!4      ;'       g    R*4      p"VP1                  V". 4      P+                  V!4       KQ  	  V F}  pVP                  R+VP                  RR,4      4      p#\/        V#4      p$V$V9  d   . VV$&   VP                  R. 4       F+  p!V!VV$,          9  g   K  VV$,          P+                  V!4       K-  	  K  	  \3        VP5                  4       4      p%V%R-,          p&\'        V%4      ^,
          p'V& EF  p"VV",          p(. p)\3        V(4       FW  p*V*V9   d   V)P+                  R.V* R"24       K!  V*V9   d   V)P+                  R/V* R"24       K?  V)P+                  R!V RV* R"24       KY  	  R0P-                  V)4      p+\'        R0P-                  \3        V(4      4      4      ^-8  d   . p,^ p-\3        V(4       F^  p*V-\'        V*4      ,           ^,           ^*8  d   V,P+                  R4        M.V,P+                  V*4       V-\'        V*4      ^,           ,          p-K`  	  . p)V, Fq  p*V*R8X  d   V)P+                  R14       K  V*V9   d   V)P+                  R.V* R"24       K;  V*V9   d   V)P+                  R/V* R"24       KY  V)P+                  R!V RV* R"24       Ks  	  R0P-                  V)4      p+VP+                  R$V RV" R2V+ 24       EK  	  V'^ 8  d   VP+                  R$V R3V' R424        ^ R5IHp. V.! 4       p/V/'       d   VP+                  R4       VP+                  R'V R624       V/ Fv  p0V0R7,          '       d?   VP+                  R$V RV0R,           R8V R9V0R:,           R;V R<V RV0R,           R=24       KP  VP+                  R.V0R,           R>V0R:,           R?24       Kx  	  VP+                  R4       VP+                  R'V R@24       \;        4       p1\=        RA V1P?                  4        4       4      p2V1'       d   \3        V1P5                  4       4       F  p3\3        V1V3,          4      p4\'        V44      ^8  d7   V4R-,          p5R0P-                  V54      RB\'        V44      ^,
           RC2,           p6MR0P-                  V44      p6\'        V64      ^28  d   V6RD,          R,           p6VP+                  R$V RV3 REV RV6 R"2	4       K  	  MVP+                  R$V RF24       VP+                  R4       V/'       d   \=        RG V/ 4       4      M^ p7\'        V4       RH2V2 RI2.p8V7'       d   V8P+                  V7 RJ24       T8P+                  RK4        ^ RLI H!p9 V9! 4       p:V:'       d#   V:RM8w  d   VP+                  R'V RNV RV: R"24       TP+                  R$T RROP-                  T84       R"24        \E        RPRQ7      p;T;'       d9   T;^ 8  d2   ^ RRI#H$p< T;^8X  d   RSMRTp=TP+                  RUT; RVT= RWT<! 4        RX24       R&P-                  T4      p>TPK                  TT>4       \M        RYRZ4      p?\        R[R\4      p@\        R]R^4      pA\O        TR'T@ RT? R_\P         R`\R         Ra2	TARdRb7      pBT PU                  4        \V        PX                  ! 4       PZ                  pCTC^_8  d`   T'       d1   \        TRc4      '       d   TP\                  '       d   TP\                  M\^        pDT PU                  TD4       T PU                  4        T PU                  XB4       R#   \          d    Rp\        p ELi ; i  \          d    . p/ EL5i ; i  \          d     ELi ; i  \          d     ELai ; i)ga  Build and print a welcome banner with caduceus on left and info on right.

Args:
    console: Rich Console instance.
    model: Current model name.
    cwd: Current working directory.
    tools: List of tool definitions.
    enabled_toolsets: List of enabled toolset names.
    session_id: Session identifier.
    get_toolset_for_tool: Callable to map tool name -> toolset name.
    context_length: Model's context window size in tokens.
)check_tool_availabilityTOOLSET_REQUIREMENTSN)get_toolset_for_toolT)quietr3    r   check_fn)paddingleftcenter)justifyrightbanner_accentz#FFBF00
banner_dimz#B8860Bbanner_textz#FFF8DCsession_borderz#8B8682r   banner_hero/z.gguf:N   Nz...z [dim u   ]·[/] [dim ]z context[/][z[/]z]Nous Research[/]z[dim z
]Session: 
z[bold z]Available Tools[/]functionotheridr   :N   Nz[red]z[yellow]z, z[dim]...[/]z:[/] z](and z more toolsets...)[/])get_mcp_statusz]MCP Servers[/]	connectedz[/] [z](	transportz
)[/] [dim u	   ]—[/] [z tool(s)[/]z
[/] [dim](u   )[/] [red]— failed[/]z]Available Skills[/]c              3   8   "   T F  p\        V4      x  K  	  R # 5ir`   )len.0ss   & r   	<genexpr>'build_welcome_banner.<locals>.<genexpr>  s     C'B!s1vv'Bs   z +z more:N/   Nz:[/] [z]No skills installed[/]c              3   F   "   T F  qR ,          '       g   K  ^x  K  	  R# 5i)r   Nrd   r   s   & r   r   r     s     @:a;:s   !
!z toolsz skillsz MCP serversz/help for commands)get_active_profile_namedefaultz]Profile:[/] [u    ·       ?rq   )recommended_update_commandcommitcommitsu   [bold yellow]⚠  u%    behind[/][dim yellow] — run [bold]z[/bold] to update[/]
agent_namezHermes Agentbanner_titlez#FFD700banner_borderz#CD7F32z vz (z)[/])titleborder_styler   banner_logo)    r   )0model_toolsr   r   r   rc   r5   updater	   grid
add_columnr%   r!   r    hasattrr   HERMES_CADUCEUSr#   splitr   r   r{   r7   joinr   r6   sortedkeystools.mcp_toolr   r;   sumvalueshermes_cli.profilesr   rs   hermes_cli.configr   add_rowr*   r   VERSIONRELEASE_DATEprintshutilget_terminal_sizecolumnsr   HERMES_AGENT_LOGO)Er   r   rC   r   r   r   r   r   r   r   _unavailable_toolsetsdisabled_tools
lazy_toolsitemr}   ts_reqtools_in_tslayout_tableaccentdimr   session_colorr    _bskin_hero
left_linesmodel_shortctx_strleft_contentright_linestoolsets_dicttool	tool_nametoolset
toolset_iddisplay_namesorted_toolsetsdisplay_toolsetsremaining_toolsets
tool_namescolored_namesr3   	tools_strshort_nameslengthr   
mcp_statussrvr9   total_skillsr1   skill_namesdisplay_names
skills_strmcp_connectedsummary_partsr   _profile_namer@   r   commits_wordright_contentr   title_colorborder_colorouter_panel
term_width_logosE   &&&&&&&&                                                             r   build_welcome_bannerr     s	   $ J#4KKRE'--25DAAUN J$xx+%)),;hhw+::j!!k*!!+. % ::f-LFH5GV4 )4F
lI
.C}i0D 0)<M : "&-fm&D&DI[I[I[""ap eRJ*-,%++c"2&EKG$$!#2&
;"!#&.esse<uA.D^.T-UU`ay{G&;-s7)6#lSVRWWhijcU!C5,-E-
:,cJK99Z(LF8#678K%'M$V,	'(<Y(G(R(R7S  "-44Y? 
 %XXdDHHVY$?@
,Z8},*,M,''2.Il ;;l+229= / % ]//12O&r*_-1#"7+
:&D~%$$uTF#%67#$$xvS%9:$$qavS%9: ' IIm,	tyy
+,-2KFz*CI%)B.&&u-""4(#d)a-' + M#5=!((7^+!((5c):;Z'!((8D6)=>!((1TF!D6)=> $ 		-0IU3%q	ykBCC $F AU3%v.@-AAVWX1#%
 2VF8?;<C;""C5#f+eD6C<L;M N5	$qWkK
 ""CK=
3{3C2D E) *  rx';<=-/C'9'@'@'BCCL16689H !3H!=>K;!# +B!YY}5"S=MPQ=Q<RRW8XX
!YY{3
:#'_u4
se1XJfTF!J<sST : 	U3%'>?@rDNC@:@@TUME
|6*|nG,DEMl;<-.?/1]i7x~dV1]OSVWX se1V[[%?$@DE
"3/fqjD'-{8	L#F81\N ;..H.J-KK_a IIk*M}5n=Jni8K	:L{m1ZL7)2l^4P!	K MMO))+33JR&,1O1OTZTfTfTf""l}eMM+K    ^  
b    sU   20e7 #e7 f 9f% "f% Af7 7fff"!f"%f43f47ggc                V    V ^8  d   Qh/ ^ \         9   d   \        \        ,          ;R&   # )r   ra   )__conditional_annotations__r   r=   )r   s   "r   r   r      s$      H % $ $Ir   i`T  )r   )NNNNN);r
  __doc__rL   loggingosr   rP   ri   rK   pathlibr   hermes_constantsr   typingr   r   r   rich.consoler   
rich.panelr   
rich.tabler	   prompt_toolkitr
   r   prompt_toolkit.formatted_textr   r   	getLogger__name__logger_GOLD_BOLD_DIM_RSTr   r%   r*   
hermes_clir+   r   r,   r   r   r   COMPACT_BANNERr;   rO   r]   ra   Eventrb   rm   rs   r{   r   r  r   )r
  s   @r   <module>r      s   
   	      , ' '     < :			8	$ 	! PF j 2 ' 9@ !% $__& \ \r   