
    iu                    f   U d Z ddlZddlZddlZddlZddlZddlZddlmZ ddl	m
Z
 ddZdeddfdZ ee          j        j                                        Zej                            d ee                     dd	Z e             dd
lmZ ddlmZ  eedz             	 dej        vrddlZ e            dz  Ze                                r eed          5 Z ej         e          pi !                    di           Z"ddd           n# 1 swxY w Y    e#e"e$          r<e"!                    d          Z%e%% ee%          &                                ej        d<   ["[n# e'$ r Y nw xY w	 ddl(m)Z*  e*d           n# e'$ r Y nw xY w	 ddlm+Z, ddl-m.Z/  e,            Z0e0!                    di           Z1 e#e1e$          r!e1!                    d          r e/d           [0[1n# e'$ r Y nw xY wddl2Z2ddl3Z4ddl5m5Z5 ddl6m7Z7m8Z8 ddl-m9Z9m:Z:  e2j;        e<          Z=defd Z>de?fd!Z@d"eAde
e         fd#ZBdd$ede
e         fd%ZCdd'eAd(ed)e?fd*ZDd+e$d,eAfd-ZEd.ede
e         fd/ZFd0e
e         de
e         fd1ZGdd2e
e         d3e
e         ddfd4ZH eId5h          ZJd6ede?fd7ZKd8ede
e         fd9ZLd8ede?fd:ZMd8ede?fd;ZNdd<ZOd8ed=e?dePeAe         ef         fd>ZQd?eRdeAe         fd@ZS	 	 	 	 	 ddAe
e         d=e?dBe
e         dCe
e         d?eRf
dDZTdE ZUdF ZVdG ZWdH ZXdI ZYddJZZdK Z[g dLZ\eAePeeef                  e]dM<   dNe$defdOZ^dPdPdPdQdRedCedBedSedTeddfdUZ_de`fdVZaddWZbdReddfdXZc	 ddRedYedZeAd[eddf
d\ZddRedNe$ddfd]Zedd^d_Zfdd`ZgddaZhddbZiddcZjdddegZkddfZlddgZmddhZndi ZodSedefdjZpddkZq	 ddlZrddmZsdn Ztdo ZuddplvmwZw defdqZxdreddfdsZyddtZzdduZ{ddvZ|ddwZ}dSedefdxZ~dyedefdzZdd{Zdd|Zdd}Zdd~Zd ZddZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd6ede`fdZddedededefdZdede?fdZddddededePedf         de?dej        f
dZd&ddede?de?fdZdeAe`         fdZddZ	 ddeddfdZeZd ZdeAe         dede
e         fdZdeAe         dedede
e         fdZ	 ddede
e         ddfdZ	 	 ddeAe         dedede?de?f
dZh dZdZdZdeAe         dede
e         fdZde
e         de?fdZdeAe         dede?fdZdeAe         dede?fdZdeAe         dededede`f
dZde?fdZd ZdeAe         dede?fdZdeAe         deddfdZd ZdeAe         fdÄZddĜdeAe         de$eef         dz  ddfdǄZddȄZ G dɄ dʦ          Zdde?fd̄Zd̈́ Zd΄ ZddτZddЄZdф Zde?fd҄ZdeAdeAfdԄZdՄ Zde`fdքZdׄ Zdd؄Zdل Zdڄ Ze<dk    r eŦ             dS dS )u	  
Hermes CLI - Main entry point.

Usage:
    hermes                     # Interactive chat (default)
    hermes chat                # Interactive chat
    hermes gateway             # Run gateway in foreground
    hermes gateway start       # Start gateway as service
    hermes gateway stop        # Stop gateway service
    hermes gateway status      # Show gateway status
    hermes gateway install     # Install gateway service
    hermes gateway uninstall   # Uninstall gateway service
    hermes setup               # Interactive setup wizard
    hermes logout              # Clear stored authentication
    hermes status              # Show status of all components
    hermes cron                # Manage cron jobs
    hermes cron list           # List cron jobs
    hermes cron status         # Check if cron scheduler is running
    hermes doctor              # Check configuration and dependencies
    hermes honcho setup                    # Configure Honcho AI memory integration
    hermes honcho status                   # Show Honcho config and connection status
    hermes honcho sessions                 # List directory → session name mappings
    hermes honcho map <name>               # Map current directory to a session name
    hermes honcho peer                     # Show peer names and dialectic settings
    hermes honcho peer --user NAME         # Set user peer name
    hermes honcho peer --ai NAME           # Set AI peer name
    hermes honcho peer --reasoning LEVEL   # Set dialectic reasoning level
    hermes honcho mode                     # Show current memory mode
    hermes honcho mode [hybrid|honcho|local]  # Set memory mode
    hermes honcho tokens                   # Show token budget settings
    hermes honcho tokens --context N       # Set session.context() token cap
    hermes honcho tokens --dialectic N     # Set dialectic result char cap
    hermes honcho identity                 # Show AI peer identity representation
    hermes honcho identity <file>          # Seed AI peer identity from a file (SOUL.md etc.)
    hermes honcho migrate                  # Step-by-step migration guide: OpenClaw native → Hermes + Honcho
    hermes version             Show version
    hermes update              Update to latest version
    hermes uninstall           Uninstall Hermes Agent
    hermes acp                 Run as an ACP server for editor integration
    hermes sessions browse     Interactive session picker with search

    hermes claw migrate --dry-run  # Preview migration without changes
    N)Path)Optionalreturnc                 L    |                      ddt          j        d           dS )zzAttach the ``--accept-hooks`` flag.  Shared across every agent
    subparser so the flag works regardless of CLI position.z--accept-hooks
store_truezuAuto-approve unseen shell hooks without a TTY prompt (equivalent to HERMES_ACCEPT_HOOKS=1 / hooks_auto_accept: true).actiondefaulthelpN)add_argumentargparseSUPPRESS)parsers    4/home/ubuntu/.hermes/hermes-agent/hermes_cli/main.py_add_accept_hooks_flagr   7   s=     !O          command_namec                     t           j                                        s5t          d|  dt           j                   t          j        d           dS dS )a  Exit with a clear error if stdin is not a terminal.

    Interactive TUI commands (hermes tools, hermes setup, hermes model) use
    curses or input() prompts that spin at 100% CPU when stdin is a pipe.
    This guard prevents accidental non-interactive invocation.
    zError: 'hermes z' requires an interactive terminal.
It cannot be run through a pipe or non-interactive subprocess.
Run it directly in your terminal instead.file   N)sysstdinisattyprintstderrexit)r   s    r   _require_ttyr   E   sk     9 9l 9 9 9 		
 	
 	
 	
 	 r   c                      t           j        dd         } d}d}t          |           D ]c\  }}|dv r%|dz   t          |           k     r| |dz            }d} n6|                    d          r |                    dd          d         }d} nd|!t          j                            d          rdS |r	 dd	l	m
}  |            d
z  }|                                r2|                                                                }|r
|dk    r|}d}n# t          t          f$ r Y nw xY w|T	 ddlm}  ||          }	n# t$          t&          f$ r<}
t)          d|
 t           j                   t          j        d           Y d}
~
n:d}
~
wt.          $ r*}
t)          d|
 dt           j                   Y d}
~
dS d}
~
ww xY w|	t          j        d<   |dk    rt          |           D ]\  }}|dv r>|dz   }t           j        d|         t           j        ||z   d         z   t           _         dS |                    d          r>|dz   }t           j        d|         t           j        |dz   d         z   t           _         dS dS dS dS )zAPre-parse --profile/-p and set HERMES_HOME before module imports.r   Nr   )z	--profilez-p   z
--profile==HERMES_HOMEget_default_hermes_rootactive_profiler
   )resolve_profile_envError: r   z"Warning: profile override failed (z), using default)r   argv	enumeratelen
startswithsplitosenvirongethermes_constantsr$   exists	read_textstripUnicodeDecodeErrorOSErrorhermes_cli.profilesr&   
ValueErrorFileNotFoundErrorr   r   r   	Exception)r(   profile_nameconsumeiargr$   active_pathnamer&   hermes_homeexcstarts               r   _apply_profile_overriderC   d   s!   8ABB<DLG D//  3%%%!a%#d))*;*;A;LGE^^L)) 	99S!,,Q/LGE	 
} = = 
	@@@@@@11336FFK!!##  ",,..4466  DI--#'LG"G, 	 	 	D	 	??????--l;;KK-. 	 	 	/C//
3333HQKKKKKKKK 	 	 	JSJJJZ    FFFFF	 %0
=!Q;;#D//  3---EE"x/#(57?;L;L2MMCHEE^^L11 EE"x/#(519;;2GGCHEE/  " ; s7   2AD D D 'D9 9F8
2FF8F33F8get_hermes_home)load_hermes_dotenv.env)project_envHERMES_REDACT_SECRETSzconfig.yamlutf-8encodingsecurityredact_secrets)setup_loggingcli)modeload_config)apply_ipv4_preferencenetwork
force_ipv4T)force)datetime)__version____release_date__)AI_GATEWAY_BASE_URLOPENROUTER_BASE_URLc                 F   | sdS t          j                    | z
  }|dk     rdS |dk     rt          |dz             dS |dk     rt          |dz             dS |dk     rd	S |d
k     rt          |dz             dS t          j        |                               d          S )zBFormat a timestamp as relative time (e.g., '2h ago', 'yesterday').?<   zjust nowi  zm agoiQ zh agoi  	yesterdayi:	 zd agoz%Y-%m-%d)_timetimeintrX   fromtimestampstrftime)tsdeltas     r   _relative_timerh      s     sJLL2Erzzzt||ebj//((((u}}edl##****v~~{v~~eem$$++++!"%%..z:::r   c                     ddl m} m}m} ddlm} ddl m} |                    dd          } |            }|                    d          }t          |t                    r*|                    d          pd
                                }n,t          |t                    r|
                                }nd}|o||k    }	ddlm}
 h d	}|
                                D ]'}|j        d
k    r|                    |j                   (t#          d |D                       rdS  |             }|                                r	 |                    d                                          D ]}|
                                }|                    d          sd|vr0|                    d          \  }}}|
                                
                    d          }|
                                |v r|r dS n# t.          $ r Y nw xY w	 |
                                D ]4\  }}|j        d
k    r ||          }|                    d          r dS 5n# t.          $ r Y nw xY w |            dz  }|                                rq	 ddl} |j        |                                          }|                    d          }|r" ||          }|                    d          rdS n# t.          $ r Y nw xY wt          |t                    r|                    d          pd
                                }|                    d          pd
                                }|                    d
          pd
                                }|s|s|rdS |	rH	 ddlm}m}  |            }|r" ||          s|                    d          rdS n# t.          $ r Y nw xY wdS )z3Check if at least one inference provider is usable.r   )get_env_pathrE   rS   )get_auth_status)DEFAULT_CONFIGmodel r
   )PROVIDER_REGISTRY>   OPENAI_API_KEYANTHROPIC_TOKENOPENAI_BASE_URLANTHROPIC_API_KEYOPENROUTER_API_KEYapi_keyc              3   >   K   | ]}t          j        |          V  d S N)r-   getenv).0vs     r   	<genexpr>z/_has_any_provider_configured.<locals>.<genexpr>  s*      
3
3A29Q<<
3
3
3
3
3
3r   TrJ   rK   #r!   z'"	logged_inz	auth.jsonNactive_providerproviderbase_url)read_claude_code_credentialsis_claude_code_token_validrefreshTokenF)hermes_cli.configrj   rE   rS   hermes_cli.authrk   rl   r/   
isinstancedictr3   strro   values	auth_typeupdateapi_key_env_varsanyr1   r2   
splitlinesr+   	partitionr9   itemsjsonloadsagent.anthropic_adapterr   r   )rj   rE   rS   rk   rl   _DEFAULT_MODELcfg	model_cfg_model_name_has_hermes_configro   provider_env_varspconfigenv_filelinekey_valprovider_idstatus	auth_filer   authactivecfg_providercfg_base_urlcfg_api_keyr   r   credss                                 r   _has_any_provider_configuredr      s   LLLLLLLLLL////// 100000#''44N
+--C  I)T""  }}Y//52<<>>	Is	#	# oo''$F)F
 211111   %++-- ? ?	))$$W%=>>>

3
3!2
3
3
333 t |~~H 
	 **G*<<GGII    zz||??3'' 3d??"nnS11Qiikk''..99;;"333344   	 	 	D	$5$;$;$=$= 	 	 K I--$_[11Fzz+&& tt		      !!K/I 
	KKK4:i113344DXX/00F  (00::k**  4 	 	 	D	 )T"" !j117R>>@@!j117R>>@@ }}Y//52<<>> 	< 	; 	4
  	       
 1022E **5115:YY~5N5N t 	 	 	D	 5sW   ?B1G4 2G4 4
H HAI I 
IIAK! !
K.-K.4O 
OOsessionsc                      st          d           dS 	 ddldgd d  fd}                    |           d         S # t          $ r Y nw xY wt          d           t	                     D ]\  }}|                    d          pd	                                }|                    d
          pd	                                }|p	|p|d         }t          |          dk    r|dd         dz   }t          |                    d                    }|                    dd	          dd         }t          d|dz   dd|dd|dd|            	 	 t          dt                      d                                          }	|	r|	
                                dv rdS t          |	          dz
  }
d|
cxk    rt                     k     rn n |
         d         S t          dt                      d           n@# t          $ r t          d           Y n%t          t          f$ r t                       Y dS w xY w)a  Interactive curses-based session browser with live search filtering.

    Returns the selected session ID, or None if cancelled.
    Uses curses (not simple_term_menu) to avoid the ghost-duplication rendering
    bug in tmux/iTerm when arrow keys are used.
    No sessions found.Nr   c                    |                      d          pd                                }|                      d          pd                                }|                      dd          dd         }t          |                      d                    }| d         dd	         }d
}t          d||z
            }|r|d|         }	n|r|d|         }	n|}	|	d| d|dd|dd| S )z!Format a session row for display.titlern   previewsourceN   last_activeid   -      <  <10<5 )r/   r3   rh   max)
smax_xr   r   r   r   sid
fixed_cols
name_widthr?   s
             r   _format_rowz+_session_browse_picker.<locals>._format_rowz  s   UU7^^)r0022EuuY''-24466GUU8R((!,F(})=)=>>KD'#2#,C -JR!344J [j[) {
{+PZPPPPKPPPvPPP3PPPr   c                    |                                 }||                     d          pd                                 v p||                     d          pd                                 v pT||                     dd                                           v p*||                     d          pd                                 v S )z?Check if a session matches the search query (case-insensitive).r   rn   r   r   r   )lowerr/   )r   queryqs      r   _matchz&_session_browse_picker.<locals>._match  s    AaeeGnn*11333 8y))/R668888dB--///8 x.B55777	r   c           
                              d                                           r                                                                                      dj        d                               dj        d                               dj        d                               ddd           d}d}dt                    }	 | 	                                 | 
                                \  }}|d
k     s|dk     rS	 |                     ddd           n# j        $ r Y nw xY w|                                  |                                  d S r:d d}j        }                                r|                    d          z  }n5d}j        }                                r|                    d          z  }	 |                     dd||dz
  |           n# j        $ r Y nw xY wd}t%          d||z
            }	ddd|	 dddddddd }
	                                 r                    d          nj        }|                     dd|
|dz
  |           n# j        $ r Y nw xY w|dz
  }|dk     rd}|s7	 d}|                     dd||dz
  j                   n:# j        $ r Y n-w xY w|t)          |          k    rt)          |          dz
  }|dk     rd}||k     r|}n|||z   k    r||z
  dz   }t+          t-          |t/          t)          |          ||z                                 D ]\  }}|dz   }||dz
  k    r n||         }||k    rdnd}| ||dz
            z   }j        }||k    r3j        }                                r|                    d          z  }	 |                     |d||dz
  |           # j        $ r Y w xY w|dz
  }|rPd|dz    dt)          |           d}t)          |          t)                    k     r|d t)                     d!z  }nd"t)                     d}	 |                     |d||dz
                                  r                    d          nj                   n# j        $ r Y nw xY w|                                  |                                 }|j        fv r|r|dz
  t)          |          z  }n|j        fv r|r|dz   t)          |          z  }n|j        d#d$fv r|r||         d%         d<   d S |d&k    rrdt                    }d}d}nd S |j        d'dfv r2r/d d         rfd(D             }nt                    }d}d}nL|t;          d)          k    rsd S d*|cxk    rd+k    r(n n%t=          |          z  fd,D             }d}d})-Nr   r   r             rn   T   (   zTerminal too smallu     Browse sessions — filter: u   █uM     Browse sessions — ↑↓ navigate  Enter select  Type to filter  Esc quitr   r   z   zTitle / Previewr   r   Activer   Srcr   r   IDz  No sessions match the filter.    → /	 sessionsz (filtered from )z  0/
      r         c                 ,    g | ]} |          |S  r   ry   r   r   search_texts     r   
<listcomp>zB_session_browse_picker.<locals>._curses_browse.<locals>.<listcomp>,  s*    'V'V'Vavva?U?U'V'V'V'Vr   r       ~   c                 ,    g | ]} |          |S r   r   r   s     r   r   zB_session_browse_picker.<locals>._curses_browse.<locals>.<listcomp>6  s*    NNNavva7M7MNNNNr   )curs_set
has_colorsstart_coloruse_default_colors	init_pairCOLOR_GREENCOLOR_YELLOW
COLOR_CYANlistcleargetmaxyxaddstrerrorrefreshgetchA_BOLD
color_pairaddnstrr   A_DIMr*   r)   rangeminA_NORMALKEY_UPKEY_DOWN	KEY_ENTERKEY_BACKSPACEordchr)stdscrcursorscroll_offsetfilteredmax_yr   headerheader_attrr   r   
col_headerdim_attrvisible_rowsmsgdraw_ir<   yr   arrowrowattrfooter_yfooterr   r   r   r   cursesresult_holderr   s                           @r   _curses_browsez._session_browse_picker.<locals>._curses_browse  s   OOA  "" +""$$$))+++  F$6;;;  F$7<<<  F$5r:::  Ar***FMKH~~HO&%00u199

a,@AAAA!<   NN$$$LLNNNF  	<NkNNNF"(-K((** <#v'8'8';';;lF"(-K((** <#v'8'8';';;NN1aKHHHH|   D 1
 UZ%788
g#4gzgggghgggV[gggaegg
060A0A0C0CU))!,,,  NN1aUQYIIII|   D  %qy!###$L   $!?q!S%!)V\JJJJ!<    X..!$X!2zz!"--(.=<#???(.(=(A%.)H}|/KLL & & ! !	 #QJ	>>!E$QK+,;;E#kk!UQY&?&??%;;#)=D%0022 = $(9(9!(<(< <!"NN1aeaiFFFF%| ! ! ! D! !19 =G&1*GGs8}}GGGF8}}s8}}44"ES]]"E"E"EE<CMM<<<F	NN 	060A0A0C0CU))!,,,    |   D    llnn6=*** >"(1*H!=V_... >"(1*H!=V-r2666 B+3F+;D+Aa(FBYY" &(#'>>!"() V13:::" *&1#2#&6& 6'V'V'V'V'V8'V'V'VHH'+H~~H!"()CHH__[_F3%%%%#%%%%%3s88+KNNNNN8NNNHF$%M_O&sn   D% %
D21D2G. .
G;:G;(AI5 5
JJ#J: :
KKO$$
O10O1A
R* *
R76R7z:
  Browse sessions  (enter number to resume, q to cancel)
r   rn   r   r   2   /   ...r   r   r   r   r   z>3. <50r   Tz
  Select [1-]: )r   quitr   z  Invalid selection. Enter 1-z or q to cancel.z/  Invalid input. Enter a number or q to cancel.)r   r  wrapperr9   r)   r/   r3   r*   rh   inputr   rc   r7   KeyboardInterruptEOFError)r   r  r<   r   r   r   labelr   srcr   idxr   r   r  r  s   `          @@@@r   _session_browse_pickerr!  i  s     "###tI	Q 	Q 	Q,	 	 	^	& ^	& ^	& ^	& ^	& ^	& ^	& ^	& ^	&@ 	~&&&Q    

HIII(## F F1w%2,,..55##)r0022++AdGu::??#2#J&E$QUU=%9%9::eeHb!!"1"%D1q5DDDuDDDKDDDsDDEEEE	;X;;;<<BBDDC #))++)>>>tc((Q,CC''''#h--'''''}T**Q#h--QQQRRRR 	E 	E 	ECDDDDD!8, 	 	 	GGG44	s6   2A 
AA"A
H .<H + H I	'I	I	r   c                    d}	 ddl m}  |            }|                    | d          }|r|d         d         nd	 |&	 |                                 S # t          $ r Y S w xY wS # t          $ r Y nw xY w	 |&	 |                                 n># t          $ r Y n2w xY wn-# |&	 |                                 w # t          $ r Y w w xY ww xY wdS )z7Look up the most recently-used session ID for a source.Nr   	SessionDBr   )r   limitr   )hermes_stater$  search_sessionscloser9   )r   dbr$  r   s       r   _resolve_last_sessionr*  \  sE   	B******Y[[%%V1%==$,6x{4  $6 >



        >



    2>



    
 4sk   8A&  A
A"!A"&
A30B  2A33B  :B 
BB C
$B98C
9
CC
CC
Fcmdbackendvia_sudoc                     	 t          j        | ddd          S # t           j        $ rC |rd| n|}t          d| d| dt          j                   t	          j        d	           Y d
S w xY w)zRun a container inspect probe, returning the CompletedProcess.

    Catches TimeoutExpired specifically for a human-readable message;
    all other exceptions propagate naturally.
    T   capture_outputtexttimeoutzsudo zError: timed out waiting for z to respond.
The z+ daemon may be unresponsive or starting up.r   r   N)
subprocessrunTimeoutExpiredr   r   r   r   )r+  r,  r-  r  s       r   _probe_containerr7  p  s    	~c$T2NNNN$   %-:!!!!7HE H HH H H	
 	
 	
 	

 	s    AA,+A,container_infocli_argsc                 L   | d         }| d         }| d         }| d         }t          j        |          }|s3t          d| dt          j                   t          j        d           d	}t          |d
dd|g|          }|j        dk    rt          j        d          }|rt          |d|d
dd|g|d          }	|	j        dk    rjt          d| d| d| d| dt          j	        dd           d| dd
                    |           t          j                   t          j        d           nKt          d| d| dd
                    |           t          j                   t          j        d           t          j                                        }
|
rdgndg}g }dD ]?}t          j                            |          }|r|                    d | d!| g           @|r|d|gn|g}|d"gz   |z   d#|gz   |z   ||gz   |z   }t          j        |d         |           d	S )$a  Replace the current process with a command inside the managed container.

    Probes whether sudo is needed (rootful containers), then os.execvp
    into the container. On success the Python process is replaced entirely
    and the container's exit code becomes the process exit code (OS semantics).
    On failure, OSError propagates naturally.

    Args:
        container_info: dict with backend, container_name, exec_user, hermes_bin
        cli_args: the original CLI arguments (everything after 'hermes')
    r,  container_name	exec_user
hermes_binr'   z. not found on PATH. Cannot route to container.r   r   Ninspectz--formatokr   sudo-nT)r-  zError: container 'z' not found via zL.

The container is likely running as root. Your user cannot see it
because z7 uses per-user namespaces. Grant passwordless
sudo for u    — the -n (non-interactive) flag is required
because a password prompt would hang or break piped commands.

On NixOS:

  security.sudo.extraRules = [{
    users = [ "USERz	your-userz"" ];
    commands = [{ command = "z<"; options = [ "NOPASSWD" ]; }];
  }];

Or run: sudo hermes r   z<.
The container may be running under root. Try: sudo hermes z-it-i)TERM	COLORTERMLANGLC_ALL-er!   execz-u)shutilwhichr   r   r   r   r7  
returncoder-   rx   joinr   r   r.   r/   extendexecvp)r8  r9  r,  r;  r<  r=  runtime	sudo_pathprobeprobe2is_tty	tty_flags	env_flagsvarr   
cmd_prefixexec_cmds                    r   _exec_in_containerrZ    s'    Y'G#$45N{+I-Jl7##G MgMMM	
 	
 	
 	
 	
 I	)Z~> E 1L((	  	%D'9j$W  F
  A%%@ @ @ @ @  '@ @ !(	@ @ ')i&D&D@ @ 6=@ @ ,/88H+=+=@ @ !   $ b^ b bW b bMPXXV^M_M_b bZ   
 HQKKKYF!-vII6 5 5jnnS!! 	5dsNNSNN3444/8G)T7++wiJ(	
	 
	 		
 :
&	' 	  Ihqk8$$$$$r   
name_or_idc                 8   	 ddl m}  |            }|                    |           }d}|r	|d         }n|                    |           }|r)	 |                    |          p|}n# t
          $ r Y nw xY w|                                 |S # t
          $ r Y nw xY wdS )aX  Resolve a session name (title) or ID to a session ID.

    - If it looks like a session ID (contains underscore + hex), try direct lookup first.
    - Otherwise, treat it as a title and use resolve_session_by_title (auto-latest).
    - Falls back to the other method if the first doesn't match.
    - If the resolved session is a compression root, follow the chain forward
      to the latest continuation. Users who remember the old root ID (e.g.
      from an exit summary printed before the bug fix, or from notes) get
      resumed at the live tip instead of a stale parent with no messages.
    r   r#  Nr   )r&  r$  get_sessionresolve_session_by_titleget_compression_tipr9   r(  )r[  r$  r)  sessionresolved_ids        r   _resolve_session_by_name_or_idrb    s    ******Y[[ ..,,%) 	B!$-KK 55jAAK 	 44[AAP[    	


   4s6   A	B
 A$ #B
 $
A1.B
 0A11B
 

BBpathc                    | sd S 	 t          j        t          |                               d                    }t	          |                    d          pd                                          }|pd S # t          $ r Y d S w xY w)NrJ   rK   
session_idrn   )r   r   r   r2   r   r/   r3   r9   )rc  datar   s      r   _read_tui_active_session_filerg    s     tz$t**...@@AA$((<((.B//5577{d   tts   A.A5 5
BBre  active_session_filec                 &   t          |          p| pt          d          }|sdS d}	 ddlm}  |            }|                    |          }|s	 ||                                 dS dS |                    |          }t          |                    d          pd          }|dk    r	 ||                                 dS dS t          |                    d          pd          }t          |                    d          pd          }	t          |                    d	          pd          }
t          |                    d
          pd          }t          |                    d          pd          }||	z   |
z   |z   |z   }n)# t          $ r Y ||                                 dS dS w xY w	 ||                                 n# ||                                 w w xY wt                       t          d           t          d|            |rt          d| d           t                       t          d|            |rt          d|            t          d|            t          d| d| d|	 d|
|z    d| d           dS )z/Print a shell-visible epilogue after TUI exits.tuir   Nr   r#  message_countinput_tokensoutput_tokenscache_read_tokenscache_write_tokensreasoning_tokenszResume this session with:z  hermes --tui --resume z  hermes --tui -c ""zSession:        zTitle:          zMessages:       zTokens:         z (in z, out z, cache z, reasoning r   )rg  r*  r&  r$  r]  r(  get_session_titlerc   r/   r9   r   )re  rh  targetr)  r$  r`  r   rl  rm  rn  ro  rp  rq  total_tokenss                 r   _print_tui_exit_summaryrv    sZ   *+>??t:tQfnsQtQtQtF 	B******Y[[..(( 	* >HHJJJJJ >' $$V,,GKK88=A>>A  >HHJJJJJ > 7;;~66;!<<GKK88=A>>,? @ @ EAFF -A!B!B!GaHHw{{+=>>C!DD  !! 	 	    >HHJJJJJ > 	 >HHJJJ >HHJJJJ  
GGG	
%&&&	
-V
-
-... .,E,,,---	GGG	
%V
%
%&&& *((()))	
,]
,
,---		Y	Y 	Y*	Y 	Y2?	Y 	Y"%77	Y 	YEU	Y 	Y 	Y    s6   'F +?F CF G	 
F.G	 -F..G	 	G"ideallyInertrootc                    | dz  dz  dz  dz  }|                                 sdS | dz  }|                                 sdS | dz  dz  }|                                 sdS 	 t          j        |                    d	
                                        d          pi }t          j        |                    d	
                                        d          pi }nV# t
          t          t          j        f$ r7 |                                j	        |                                j	        k    cY S w xY wdt          dt          fd}|                                D ]\  }}|st          |t                    s||vr.|                    d          s|                    d          rM dS t          ||         t                    r! ||           |||                   k    r dS dS )u  True when @hermes/ink is missing or node_modules is behind package-lock.json.

    Compares ``package-lock.json`` against ``node_modules/.package-lock.json``
    (npm's hidden lockfile) by **content**, not mtime: git checkouts and npm
    rewrites can bump the root lockfile's timestamp even when installed deps
    already match, which used to trigger a spurious "Installing TUI
    dependencies" on every launch.

    For each entry in the root lock's ``packages`` map:
      - missing from hidden lock → reinstall (unless the entry is marked
        ``optional`` or ``peer``, which npm may intentionally skip per platform)
      - present but with differing fields (excluding npm-written runtime
        annotations like ``ideallyInert``) → reinstall

    Extra entries that exist only in the hidden lock are ignored — stale
    transitives left over from a removed dependency don't break runtime and
    we'd rather not force a reinstall for them. Falls back to mtime
    comparison if either lockfile is unparseable.
    node_modulesz@hermesinkpackage.jsonTpackage-lock.jsonFz.package-lock.jsonrJ   rK   packagespkgr   c                 >    d |                                  D             S )Nc                 ,    i | ]\  }}|t           v||S r   )_NPM_LOCK_RUNTIME_KEYSry   krz   s      r   
<dictcomp>z=_tui_need_npm_install.<locals>.comparable.<locals>.<dictcomp>s  s)    PPPA9O0O0O10O0O0Or   )r   )r  s    r   
comparablez)_tui_need_npm_install.<locals>.comparabler  s    PPPPPPr   optionalpeer)is_filer   r   r2   r/   r5   r4   JSONDecodeErrorstatst_mtimer   r   r   )	rx  r{  lockmarkerwanted	installedr  r?   r  s	            r   _tui_need_npm_installr  K  s   ( 
)
+e
3n
DC;;== t%%D<<>> uN"%99F>> t
=DNNGN<<==AA*MMSQSJv///AABBFFzRRXVX		')=> = = =yy{{#fkkmm&<<<<<=Q Q Q Q Q Q \\^^  	c 	#t$$ 	y  wwz"" cggfoo 44iot,, 	CJJyY]D_D_1_1_445s   A:C AD-,D-tui_dirc                    t           j                            d          }|r:t          |          }|dz  dz                                  rt          |          s|S | dz  dz                                  rt          |           s| S dS )zTDirectory whose dist/entry.js we should run: HERMES_TUI_DIR first, else repo ui-tui.HERMES_TUI_DIRdistentry.jsN)r-   r.   r/   r   r1   r  )r  envps      r   _find_bundled_tuir    s    
*..)
*
*C
 IIJ#++-- 	6KA6N6N 	H&:%--// 8Mg8V8V 4r   c                 T  	 t          |           rdS | dz  dz  }|                                sdS |                                j        }t	          ddh          	t          j        | d          D ]x\  }}}	fd|D             |d d <   |D ]\}|                    d          rEt
          j        	                    t
          j        
                    ||                    |k    r  dS ]ydD ];}| |z  }|                                r |                                j        |k    r dS <d	S )
NTr  r  rz  topdownc                     g | ]}|v|	S r   r   ry   dskips     r   r   z%_tui_build_needed.<locals>.<listcomp>      <<<Qatmmqmmmr   .ts.tsx)r|  r}  ztsconfig.jsonztsconfig.build.jsonF)_hermes_ink_bundle_staler1   r  r  	frozensetr-   walkendswithrc  getmtimerM  )
r  entrydist_mdirpathdirnames	filenamesfnmetampr  s
            @r   _tui_build_neededr    sO   (( tfz)E<<>> tZZ\\"Fnf-..D(*(F(F(F    $9<<<<(<<< 	  	 B{{?++  7##BGLL"$=$=>>GG444	    t^99;; 	27799-66445r   c                 6  	 | dz  dz  }|dz  dz  }|                                 sdS |                                j        }t          ddh          	t	          j        |d          D ]x\  }}}	fd|D             |d d <   |D ]\}|                    d	          rEt          j                            t          j        	                    ||                    |k    r  dS ]y|d
z  }|                                 r|                                j        |k    rdS dS )Nr~  z
hermes-inkr  zink-bundle.jsTrz  r  c                     g | ]}|v|	S r   r   r  s     r   r   z,_hermes_ink_bundle_stale.<locals>.<listcomp>  r  r   r  r|  F)
r1   r  r  r  r-   r  r  rc  r  rM  )
r  ink_rootbundlebmr  r  r  r  r  r  s
            @r   r  r    s6   #l2H0F==?? t		Bnf-..D(*$(G(G(G    $9<<<<(<<< 	  	 B{{?++  7##BGLL"$=$=>>CC444	  
N	"B	yy{{ rwwyy)B..t5r   c                     t          j        d          rt          j        d          rdS t          j                            d          rdS t
          dz  dz  dz  } |                                 sdS t          j                            d          p"t          t          j	                    d	z            }	 t          j        d
dd|  dgi t          j        d|iddd          }n# t          t          j        f$ r Y dS w xY wt          j                            dd                              t          j                  }g }|j        pd                                }|r9|                    t          |                                          j                   |                    t          |          dz  dz  t          j	                    dz  dz  g           |D ]?}t          |          }|                                r||vr|                    d|           @t          j                            |          t          j        d<   dS )uz  Make sure `node` + `npm` are on PATH for the TUI.

    If either is missing and scripts/lib/node-bootstrap.sh is available, source
    it and call `ensure_node` (fnm/nvm/proto/brew/bundled cascade). After
    install, capture the resolved node binary path from the bash subprocess
    and prepend its directory to os.environ["PATH"] so shutil.which finds the
    new binaries in this Python process — regardless of which version manager
    was used (nvm, fnm, proto, brew, or the bundled fallback).

    Idempotent no-op when node+npm are already discoverable. Set
    ``HERMES_SKIP_NODE_BOOTSTRAP=1`` to disable auto-install.
    nodenpmNHERMES_SKIP_NODE_BOOTSTRAPscriptslibznode-bootstrap.shr"   z.hermesbash-czsource "z+" >&2 && ensure_node >&2 && command -v nodeTF)r  r1  r2  checkPATHrn   binz.localr   )rJ  rK  r-   r.   r/   PROJECT_ROOTr  r   r   homer4  r5  r5   SubprocessErrorr,   pathsepstdoutr3   appendresolveparentrN  is_dirinsertrM  )helperr@   resultpartsextrasresolvedextrar   s           r   _ensure_tui_noder    s6    |F U 3 3 	z~~233 I%-0CCF>> *..//O3ty{{Y7N3O3OK N6NNN
 ;2::}k::

 

 

 Z/0    JNN62&&,,RZ88EF#**,,H 7d8nn,,..5666
MM4$$v-5ty{{X7MPU7UVWWW  JJ<<>> 	aunnLLA//BJvs   50C& &D ?D tui_devc           
         t                       dt          dt          fd}|s}t          j                            d          }|r\t          |          }|dz  dz                                  r3t          |          s$ |d          }|t          |dz  dz            g|fS  |d          }t          |           rt          j                            d	          st          d
           t          j
        |dddddgt          |           t          j        t          j        di t          j        ddi          }|j        dk    r~|j        pd                                }d                    |                                dd                   }	t          d           |	rt          |	           t%          j        d           |rt)          |           rt          j
        |ddddgt          |           dd          }|j        dk    r|j        pd |j        pd                                 }
d                    |
                                dd                   }	t          d            |	rt          |	           t%          j        d           | d!z  d"z  d#z  }|                                rt          |          d$g| fS |d%g| fS t-          |           rt          j
        |ddgt          |           dd          }|j        dk    r|j        pd |j        pd                                 }
d                    |
                                dd                   }	t          d&           |	rt          |	           t%          j        d           t/          |           }|s#t          d'           t%          j        d            |d          }|t          |dz  dz            g|fS )(uT   TUI: --dev → tsx src; else node dist (HERMES_TUI_DIR or ui-tui, build when stale).r  r   c                 L   | dk    rat           j                            d          }|r@t           j                            |          r!t          j        |t           j                  r|S t          j        |           }|s&t          |  d           t          j        d           |S )Nr  HERMES_NODEu.    not found — install Node.js to use the TUI.r   )r-   r.   r/   rc  isfileaccessX_OKrJ  rK  r   r   r   )r  env_noderc  s      r   	_node_binz!_make_tui_argv.<locals>._node_bin  s    &==z~~m44H  BGNN844  8RW9U9U  |C   	SHHHIIIHQKKKr   r  r  r  r  r  HERMES_QUIETu   Installing TUI dependencies…install--silent	--no-fund
--no-audit--progress=falseTCI1)cwdr  r   r2  r  r   rn   
Nznpm install failed.r   r5  buildz--prefixzpackages/hermes-inkr  r1  r2  z@hermes/ink build failed.rz  z.bintsxzsrc/entry.tsxrB   zTUI build failed.z'TUI build did not produce dist/entry.js)r  r   r-   r.   r/   r   r1   r  r   r4  r5  DEVNULLPIPErL  r   r3   rM  r   r   r   r  r  r  r  )r  r  r  ext_dirr  r  r  r  errr   combinedr  rx  s                r   _make_tui_argvr    s#   	s 	s 	 	 	 	  ?*..!122 	?WAF
Z'//11 ?:OPQ:R:R ? y((c!f*z"9::;Q>>
)E

CW%% z~~n-- 	42333)ZlDVWG%?)2:)tS))
 
 
 !!=&B--//Cii 0 0 677G'((( gHQKKK '#G,, 	^eWj2GHLL#	  F  A%%$m1rH6=3FBHHNNPP))H$7$7$9$9#$$$?@@1222 #'NNN&/%7::<< 	8HHo.77W~w&&!! %!G	
 
 
 !! --2Dv}/BDDJJLLHii 3 3 5 5cdd ;<<G%&&& gHQKKKW%%D 78889VD#dVmj0112D88r   toolsetsc                    	 ddl m}  ||           pg S # t          t          f$ r | sg cY S t	          | t
                    r| gn| }t	          |t          t          f          s|g}g }|D ]~}t	          |t
                    r3|                    d |	                    d          D                        J|
                    t          |                                                     d |D             cY S w xY w)zCNormalize argparse/Fire-style toolset input for the TUI subprocess.r   )_normalize_toolsetsc              3   >   K   | ]}|                                 V  d S rw   )r3   )ry   parts     r   r{   z*_normalize_tui_toolsets.<locals>.<genexpr>b  s*      !K!K4$**,,!K!K!K!K!K!Kr   ,c                     g | ]}||S r   r   ry   items     r   r   z+_normalize_tui_toolsets.<locals>.<listcomp>f  s    444t4444r   )hermes_cli.oneshotr  AttributeErrorImportErrorr   r   r   tuplerN  r,   r  r3   )r  r  	raw_items
normalizedr  s        r   _normalize_tui_toolsetsr   Q  s.   5::::::""8,,22K( 5 5 5 	III",Xs";";IXJJ	)dE]33 	$"I "
 	5 	5D$$$ 5!!!K!K4::c??!K!K!KKKKK!!#d))//"3"34444444444445s    C7CC76C7resume_session_idrm   r   c                    t           dz  }ddl}t          j                                        }|                    dd          \  }}	t          j        |           |	|d<   t          j                            dt          t                               |d<   |	                    d	t          j                   |	                    d
t          j                               |	                    d|rdnd           |r
||d<   ||d<   |r
||d<   ||d<   t          |          }
|
rd                    |
          |d<   |                    dd                                          }t!          d |D                       s|                    d           d|vr|                    d           d                    |          |d<   | r| |d<   t%          ||          \  }}d}	 	 t'          j        |t          |          |          }n# t*          $ r d}Y nw xY w|dv rt-          | |	           	 t          j        |	           n:# t0          $ r Y n.w xY w# 	 t          j        |	           w # t0          $ r Y w w xY wxY wt          j        |           dS )z%Replace current process with the TUI.ui-tuir   Nzhermes-tui-active-session-z.json)prefixsuffixHERMES_TUI_ACTIVE_SESSION_FILEHERMES_PYTHON_SRC_ROOTHERMES_PYTHON
HERMES_CWDNODE_ENVdevelopment
productionHERMES_MODELHERMES_INFERENCE_MODELHERMES_TUI_PROVIDERHERMES_INFERENCE_PROVIDERr  HERMES_TUI_TOOLSETSNODE_OPTIONSrn   c              3   @   K   | ]}|                     d           V  dS )z--max-old-space-size=Nr+   )ry   ts     r   r{   z_launch_tui.<locals>.<genexpr>  s/      FFq||344FFFFFFr   z--max-old-space-size=8192z--expose-gcr   HERMES_TUI_RESUME)r  r     )r   r  )r  tempfiler-   r.   copymkstempr(  r/   r   
setdefaultr   
executablegetcwdr   rM  r,   r   r  r  r4  callr  rv  unlinkr5   r   )r  r  rm   r   r  r  r  r  active_session_fdrh  tui_toolsets_tokensr(   r  codes                  r   _launch_tuir$  i  s    X%GOOO
*//

C-5-=-=+G .> . .** H,?C()$&JNN #l"3"3% %C ! NN?CN333NN<---NN:I}}\JJJ .#N(-$% 4%-!"+3'(*844L <%(XXl%;%;!" ggnb))//11GFFgFFFFF 42333G##}%%%((7++C 5#4 w00ID#D	?4SXX3???DD  	 	 	DDD	 8#$57JKKK	I)**** 	 	 	D		I)**** 	 	 	D	 HTNNNNNs`   $H  I HI HI (H= =
I
	I
I4I$#I4$
I1.I40I11I4c                 	   t          | dd          p"t          j                            d          dk    }t          | dd          }|rt          | dd          st	          |t
                    rPt          |          }|r|| _        nt          d| d	           t          d
           t          j
        d           ne|rdnd}t          |          }|s|dk    rt          d          }|r|| _        n-|rdnd}t          d| d           t          j
        d           t          | dd          }|rt          |          }|r|| _        t                      st                       t          d           t                       t          d           t                       ddlm}m}	  |            s |	d           t          j
        d           	 t!          d                                                                          }
n# t&          t(          f$ r d}
Y nw xY w|
dv rt+          |            dS t                       t          d           t          j
        d           	 ddlm}  |             n# t0          $ r Y nw xY w	 ddlm}  |d           n# t0          $ r Y nw xY wt          | dd          rdt          j        d <   t          | d!d          rdt          j        d"<   t          | d#d          rdt          j        d$<   t          | d%d          r| j        t          j        d&<   |r_t9          t          | dd          t          | d'd          t          | d(d          t          | d)d          t          | d*d          +           dd,lm} | j        t          | d)d          | j         t          | d-d          | j!        t          | d.d          | j"        t          | d/d          t          | dd          t          | d0d          t          | d1d          t          | d2d          t          | d3d          t          | d#d          t          | d!d          d4}d5 |#                                D             }	  |d7i | dS # tH          $ r1}t          d6|            t          j
        d           Y d}~dS d}~ww xY w)8zRun interactive chat CLI.rj  F
HERMES_TUIr  continue_lastNresumezNo session found matching ''.z5Use 'hermes sessions list' to see available sessions.r   rP   rk  TUICLIzNo previous z session found to continue.zLIt looks like Hermes isn't configured yet -- no API keys or providers found.z  Run:  hermes setupr   )is_interactive_stdin#print_noninteractive_setup_guidancez;No interactive TTY detected for the first-run setup prompt.zRun setup now? [Y/n] nrn   r
  yesz4You can run 'hermes setup' at any time to configure.)prefetch_update_checksync_skillsTquietyoloHERMES_YOLO_MODEignore_user_configHERMES_IGNORE_USER_CONFIGignore_rulesHERMES_IGNORE_RULESr   HERMES_SESSION_SOURCEr  rm   r   r  )r  rm   r   r  mainskillsr5  imageworktreecheckpointspass_session_id	max_turns)rm   r   r  r?  verboser5  r   r@  r(  rA  rB  rC  rD  r:  r8  c                     i | ]
\  }}|||S rw   r   r  s      r   r  zcmd_chat.<locals>.<dictcomp>6  s    ???tq!ar   r'   r   )%getattrr-   r.   r/   r   r   rb  r(  r   r   r   r*  r   hermes_cli.setupr,  r-  r  r3   r   r  r  	cmd_setuphermes_cli.bannerr1  r9   tools.skills_syncr3  r   r$  rP   r>  rm   r  rE  r   r   r7   )argsuse_tuicontinue_valr  r   last_idkind
resume_valr,  r-  replyr1  r3  cli_mainkwargses                   r   cmd_chatrV    s   dE5))PRZ^^L-I-IS-PG 4$77L GD(D99 lC(( 	5lCCH &DLDDDEEEMNNN &0UU5F+6:::G >v/u=== % '2uuUFTFFFGGG x..J #1*== 	#"DK
 ()) Z	
 	
 	
 	$%%%	
 	
 	
 	
 	
 	
 	
 	

 $#%% 	//M   HQKKK	12288::@@BBEE+, 	 	 	EEE	$$$dOOOFDEEE;;;;;;   111111$    tVU## -),
%& t)511 625
./
 t^U++ 0,/
() tXt$$ :.2k
*+ 
D(D))D)U33$..T:t44T:t44	
 	
 	
 	
 %$$$$$ D*d33M$$//<w..w--$$//D*e44t]E::"4):EBBT;55ne<<%d,@%HH F$ @?v||~~???F6   mmmsN   3H H! H!+I< <
J	J	J   
J-,J-R 
S&SSc                 (    ddl m}  ||            dS )zGateway management commands.r   )gateway_commandN)hermes_cli.gatewayrX  )rL  rX  s     r   cmd_gatewayrZ  ?  *    222222ODr   c           	      B   t          d           ddlm}m} t	                       t	          d           t	          d            |d          pd}|st	                       t	          d           t	                       t	          d	           t	          d
           t	          d           t	                       t	          d           t	          d           t	          d           t	                       	 t          d                                          }n'# t          t          f$ r t	          d           Y dS w xY w|dk    r |dd           d}t	          d           t	                       t	          d           t	          d           t	          d           t	          d           t	          d           t	          d           t	          d           t	          d           t	          d           t	          d           t	          d           t	          d           n< |dd            d }t	          d!           n|}|dk    rd"nd#}t	          d$|            t	                        |d%          }|r(|	                                d&k    rt	          d'           n |d%d&           t	          d(            |d)          pd}|rt	          d*|            	 t          d+                                          }	n# t          t          f$ r d,}	Y nw xY w|		                                d-v r}|dk    r"t          d.                                          }
n!t          d/                                          }
|
r2 |d)|

                    d0d                     t	          d1|
            nt	                       |dk    r1t	          d2           t          d3                                          }
n!t          d/                                          }
|
r3 |d)|

                    d0d                     t	          d4|
            nt	          d5           t          t                                                    j        d6         }|d7z  d8z  }|d9z  }|                                st	          d:|            dS |d;z                                  s t	          d<           t!          j        d=          }|st	          d>           dS 	 t%          j        |d?d@dAdBgt)          |          t$          j        t$          j        dCD          }n # t          $ r t	          dE           Y dS w xY w|j        dk    rn|j        pd                                }|r/dF                    |                                dGd                   ndH}t	          dI           t	          |           dS t	          dJ           nt	          dK           t7                      dz  dLz  }|                    dCdCM           |dNz                                  rt	          dO           	 t          dP                                          }	n# t          t          f$ r d,}	Y nw xY w|		                                d-v r=t!          j        |dCQ           |                    dCdCM           t	          dR           n t	          dS           t	          dT           dS t	                       t	          dU           |dk    rt	          dV           t	          dW           nt	          dX           t	                       t	          dY           t	          dU           t	                       	 t%          j        dZt)          |          d[d\t)          |          gt)          |          ]           n# t          $ r Y nw xY wt	                       |dNz                                  rt	          d^           t	                       |dk    rZt	          d_           t	          d`           t	          da           t	          db           t	                       t	          dc           nht	          d_           t	          d`           t	          dd           t	          de           t	                       t	          dc           t	          df           t	                       t	          dg           dS t	          dh           dS )izESet up WhatsApp: choose mode, configure, install bridge, pair via QR.whatsappr   get_env_valuesave_env_valueu   ⚕ WhatsApp Setup2==================================================WHATSAPP_MODErn   z&How will you use WhatsApp with Hermes?z&  1. Separate bot number (recommended)uF        People message the bot's number directly — cleanest experience.zH     Requires a second phone number with WhatsApp installed on a device.z   2. Personal number (self-chat)z/     You message yourself to talk to the agent.z3     Quick to set up, but the UX is less intuitive.z  Choose [1/2]: z
Setup cancelled.Nr  botu     ✓ Mode: separate bot numberu     ┌─────────────────────────────────────────────────┐u9     │  Getting a second number for the bot:           │u9     │                                                 │u9     │  Easiest: Install WhatsApp Business (free app)  │u9     │  on your phone with a second number:            │u;     │    • Dual-SIM: use your 2nd SIM slot            │u<     │    • Google Voice: free US number (voice.google) │u;     │    • Prepaid SIM: $3-10, verify once            │u9     │  WhatsApp Business runs alongside your personal │u;     │  WhatsApp — no second phone needed.             │u     └─────────────────────────────────────────────────┘z	self-chatu'     ✓ Mode: personal number (self-chat)zseparate bot numberzpersonal number (self-chat)u   
✓ Mode: WHATSAPP_ENABLEDtrueu   ✓ WhatsApp is already enabledu   ✓ WhatsApp enabledWHATSAPP_ALLOWED_USERSu   ✓ Allowed users: z
  Update allowed users? [y/N] r.  r
  r0  z<  Phone numbers that can message the bot (comma-separated): z(  Your phone number (e.g. 15551234567): r   u     ✓ Updated to: z+  Who should be allowed to message the bot?z4  Phone numbers (comma-separated, or * for anyone): u     ✓ Allowed users set: uF     ⚠ No allowlist — the agent will respond to ALL incoming messagesr   r  zwhatsapp-bridgez	bridge.jsu    
✗ Bridge script not found at rz  uM   
→ Installing WhatsApp bridge dependencies (this can take a few minutes)...r  u5     ✗ npm not found on PATH — install Node.js firstr  r  r  r  T)r  r  r   r2  u   
  ✗ Install cancelledr  r  z(no output)u     ✗ npm install failed:u     ✓ Dependencies installedu)   ✓ Bridge dependencies already installedr`  parentsexist_okz
creds.jsonu#   ✓ Existing WhatsApp session foundz8
  Re-pair? This will clear the existing session. [y/N] ignore_errorsu     ✓ Session clearedu'   
✓ WhatsApp is configured and paired!z(  Start the gateway with: hermes gatewayu   ──────────────────────────────────────────────────u0   📱 Open WhatsApp (or WhatsApp Business) on thez*   phone with the BOT's number, then scan:u,   📱 Open WhatsApp on your phone, then scan:u0      Settings → Linked Devices → Link a Devicer  z--pair-only	--session)r  u!   ✓ WhatsApp paired successfully!z  Next steps:z)    1. Start the gateway:  hermes gatewayz2    2. Send a message to the bot's WhatsApp numberz)    3. The agent will reply automaticallyu;     Tip: Agent responses are prefixed with '⚕ Hermes Agent'u)       2. Open WhatsApp → Message Yourselfu.       3. Type a message — the agent will replyz4  so you can tell them apart from your own messages.z1  Or install as a service: hermes gateway installuG   ⚠ Pairing may not have completed. Run 'hermes whatsapp' to try again.)r   r   r_  r`  r   r  r3   r  r  r   replacer   __file__r  ri  r1   rJ  rK  r4  r5  r   r  r  rL  r   rM  r   rE   mkdirrmtree)rL  r_  r`  current_modechoicewa_mode
mode_labelcurrentcurrent_usersresponsephoneproject_root
bridge_dirbridge_scriptr  r  r  r   session_dirs                      r   cmd_whatsappr~  F  s	
   ????????	GGG	
	(OOO !=117RL .+67776777VWWWV	
 	
 	
 	0111?@@@CDDD	-..4466FF+, 	 	 	&'''FF	 S==N?E222G3444GGG  p  q  q  qMNNNMNNNMNNNMNNNOPPPPQQQOPPPMNNNMNNNOPPP  p  q  q  q  qN?K888!G;<<<<%,%5%5!!;X 	 	)Z))*** 
GGGm.//G &7==??f,,/0000)6222$%%% "M":;;ArM \3M33444	?@@FFHHHH+, 	 	 	HHH	>>|++%R %''  HIIOOQQ 47sB9O9OPPP2522333e?@@@F egg E DEEKKMME 	\N3U]]35K5KLLL5e556666Z[[[ >>))++3A6L	),==J,M!! A-AABBB'//11 ;^___l5!! 	IJJJF
	^il<NO
OO!)!  FF ! 	 	 	-...FF	 !!=&B--//C;>Qdii 0 0 6777MG-...'NNNF,----9::: "##j09<KdT222l"**,, 3444	K egg H +, 	 	 	HHH	>>|++M+T::::dT:::)****<===<===F 
GGG	*%@AAA:;;;;<===	GGG	
<===	*	GGGS''SEUEUVJ	
 	
 	
 	
 	
     
GGGl"**,, Y1222e/"""=>>>FGGG=>>>GGGOPPPP/"""=>>>=>>>BCCCGGGOPPPHIIIABBBBBWXXXXXs[   6!D  D<;D<!!L LL?U U,+U,!Y; ;ZZA_ 
_#"_#c                 (    ddl m}  ||            dS )zInteractive setup wizard.r   )run_setup_wizardN)rH  r  )rL  r  s     r   rI  rI    s+    111111Tr   c                 D    t          d           t          |            dS )uK   Select default model — starts with provider selection, then model picker.rm   rL  N)r   select_provider_and_modelr  s    r   	cmd_modelr    s'    4((((((r   c           	        #$% ddl m%m#m} ddlm$m}m} ddlm	}  |            }|
                    d          }t          |t                    r|
                    dd          }|pd}d	}|
                    d          }t          |t                    r|
                    d
          }|pt          j        d          pd}	 $|          }
d	}|	dk    rC ||	|
                    d          |
          }||j        }nd|	 d}t!          d| d           |E	  %d          }n8# #$ r0}|	dk    r ||          }t!          d| d           d	}Y d	}~nd	}~ww xY w|dk    r |d          rd}ddlm}m} t          |          }|r|
                    ||          nd}t!                       t!          d|            t!          d|            t!                       d |D             }dt          t(          t          t(          t(          f         f         f#$%fd} ||          }|                                D ]\  }}|d         }|d         }|                    dd                              dd                              d           }|
                    dd          }|rd!| nd}|                    || d"| d#| f           g }d}|D ]Q\  }}|r3||k    r-|                    || d$f           t3          |          d%z
  }:|                    ||f           R|                    d&           t          |
                    d'          t4                    o!t7          |
                    d'                    } | r|                    d(           |                    d)           |                    d*           t9          d+ |D             |,          }!|!||!         d         d-k    rt!          d.           d	S ||!         d         }"|"d/k    rt;                       d	S |"dk    rt=          ||           n|"d0k    rt?          ||           n|"d1k    rtA          ||| 2           n|"d3k    rtC          ||           n|"d4k    rtE          ||           nz|"d5k    rtG          ||| 2           n`|"d6k    rtI          ||           nH|"d7k    rtK          ||           n0|"d8k    rtM          ||           n|"dk    rtO          |           n|"(                    d9          s|"|v rJ | |                      
                    |"          }|t!          d:           d	S tS          ||           n|"d;k    rtU          |           n|"d<k    rtW          ||           nq|"d=k    rtY          ||           nZ|"d>k    rt[          ||           nC|"d?k    rt]          ||           n,|"d@k    rt_          ||           n|"dAv rta          ||"|           |"dBvr%|"(                    d9          stc                       d	S d	S d	S )Ca  Core provider selection + model picking logic.

    Shared by ``cmd_model`` (``hermes model``) and the setup wizard
    (``setup_model_provider`` in setup.py).  Handles the full flow:
    provider picker, credential prompting, model selection, and config
    persistence.
    r   )resolve_provider	AuthErrorformat_auth_error)get_compatible_custom_providersrS   r_  )resolve_provider_fullrm   r
   rn   z	(not set)Nr   r  auto	providerszUnknown provider 'zb'. Check 'hermes model' for available providers, or run 'hermes doctor' to diagnose config issues.z	Warning: z) Falling back to auto provider detection.
openrouterrr   custom)CANONICAL_PROVIDERS_PROVIDER_LABELSnonez  Current model:    z  Active provider:  c                 *    g | ]}|j         |j        fS r   )slugtui_desc)ry   r  s     r   r   z-select_provider_and_model.<locals>.<listcomp>m  s!    GGGaafaj)GGGr   r   c                 T   ddl m} i  |            }dt          dt          dt          dt          dd f
fd}|                    d	          }t	          |t
                    r{|D ]x}t	          |t                    s ||                    dd
          d
|                    dd
          p|                    dd
          |                    dd
                     y|                    d          }t	          |t                    r|                                D ]}\  }}t	          |t                    s ||                    dd
          p|||                    dd
          p|                    dd
          |                    dd
                     ~dt          dt          dt          dt          ffd}i }	 |           D ]]}
t	          |
t                    s|
                    d          pd
                                }|
                    d          pd
                                }|r|spd|	                                
                    dd          z   }|
                    d          pd
                                }|r	  |           n# $ r |}Y nw xY w|||
                    dd
          |
                    dd
          |
                    dd
          |
                    dd
          | ||||
                    dd
                    d|	|<   _|	S )Nr   )read_raw_configr?   provider_keyrm   ru   r   c                    t          |pd                                          }d|vrd S t          | pd                                          } t          |pd                                          }t          |pd                                          }| rS                    |                                 f|                               |                                 |f|           |rU                    |                                f|                               |                                |f|           d S d S )Nrn   ${)r   r3   r  r   )r?   r  rm   ru   templateraw_api_key_refss        r   _record_rawzRselect_provider_and_model.<locals>._named_custom_provider_map.<locals>._record_raw}  sE    7=b))//11H8##tzr??((**D|1r2288::L$$**,,E
  M ++TZZ\\OXFFF ++TZZ\\5,A8LLL  ++\-?-?-A-A,CXNNN ++!''))518     r   custom_providersrn   default_modelr  c                 l   t          | pd                                                                          }t          |pd                                                                          }t          |pd                                          }||f|f||f|ffD ]}|d         r|v r
|         c S dS )Nrn   r   r   r3   r   )r?   r  rm   name_lcpkey_lcidentityr  s         r   _lookup_refzRselect_provider_and_model.<locals>._named_custom_provider_map.<locals>._lookup_ref  s    $*"oo++--3355G,,"--3355;;==G$$**,,E% 
% 
	 6 6 A; 68/?#?#?+H55552r   r   custom:r   -key_envapi_mode)r?   r   ru   r  rm   r  r  api_key_ref)r   r  r   r/   r   r   r   r   r3   r   rn  )r   r  raw_cfgr  raw_list	raw_entryraw_providersraw_keyr  custom_provider_mapr  r?   r   r   r  r  r  r  r  s                  @r   _named_custom_provider_mapz=select_provider_and_model.<locals>._named_custom_provider_mapo  s   555555 .0!/##			 	 		
 	 	 	 	 	 	2 ;;122h%% 
	% 	 		!)T22 MM&"--MM'2.. : }}_b99MM)R00     K00mT** 
	&3&9&9&;&; 	 	"!)T22 MM&"--8MM'2.. : }}_b99MM)R00   	c 	 	S 	S 	 	 	 	 	 	 !44S99 	 	EeT** IIf%%+2244D		*--3::<<H x djjll223<<<C!IIn55;BBDDL ''$$\2222  ' ' '&CCC' $ 99Y33 99Y337B//!IIj"55 ,*{,		'2(>(>   ( ($$ #"s   JJ&%J&r?   r   https://http://r       —  (r        ← currently activer   )r  z$Custom endpoint (enter URL manually)r  )remove-customzRemove a saved custom provider)
aux-configzConfigure auxiliary models...)cancelzLeave unchangedc                     g | ]\  }}|S r   r   ry   r   r  s      r   r   z-select_provider_and_model.<locals>.<listcomp>  s    '''81e'''r   r
   r  
No change.r  
ai-gatewaynousr  openai-codex
qwen-oauthminimax-oauthgoogle-gemini-clicopilot-acpcopilotr  zyWarning: the selected saved custom provider is no longer available. It may have been removed from config.yaml. No change.r  	anthropickimi-codingstepfunbedrockazure-foundry)geminideepseekxaizaizkimi-coding-cnminimaxz
minimax-cnkilocodeopencode-zenopencode-goalibabahuggingfacexiaomiarceegminvidiaollama-cloudztencent-tokenhublmstudio)r  r  r  )2r   r  r  r  r   r  rS   r_  hermes_cli.providersr  r/   r   r   r-   rx   r   r   hermes_cli.modelsr  r  r   r   rn  rstripr  r*   r   bool_prompt_provider_choice_aux_config_menu_model_flow_openrouter_model_flow_ai_gateway_model_flow_nous_model_flow_openai_codex_model_flow_qwen_oauth_model_flow_minimax_oauth_model_flow_google_gemini_cli_model_flow_copilot_acp_model_flow_copilot_model_flow_customr+   _model_flow_named_custom_remove_custom_provider_model_flow_anthropic_model_flow_kimi_model_flow_stepfun_model_flow_bedrock_model_flow_azure_foundry_model_flow_api_key_provider_clear_stale_openai_base_url)&rL  r  rS   r_  r  configcurrent_modelconfig_providerr   effective_providercompatible_custom_providersr   
active_defwarningrA   r  r  provider_labelsactive_labelall_providersr  _custom_provider_mapr   provider_infor?   r   	short_urlsaved_model
model_hintordereddefault_idxr  _has_saved_custom_listprovider_idxselected_providerr  r  r  s&                                      @@@r   r  r     s            
         
 ;:::::[]]FJJw''M-&& 9%)))R88!0[M O

7##I)T"" 4#--
33 	K29%@AAKV  #B"A&"I"IFV##**JJ{##'
 


 !]FF%7    
 PgPPPQQQ~	%%f--FF 	 	 	!V++++C00T'TTTUUUFFFFFF		 --0A"B"BGGGGGGGG+,,O:@L?&&vv666fL	GGG	
0
0
0111	
/
/
/000	GGG HG3FGGGMi#4T#s(^0C+D i# i# i# i# i# i# i# i#X 65  388:: I I]V$ ,$$Z44<<YKKRRSVWW	#''44.9A*[***r
cd#F#Fi#F#F*#F#FGHHHH GK# ) )
U 	)cVmmNNCE!A!A!ABCCCg,,*KKNNC<((((NNEFFF'

3E(F(FMM RV

%&&S S  LJKKKNNBCCCNN0111*''w'''  L w|4Q78CCl-a0L(( L((v}5555	l	*	*v}5555	f	$	$T:::::	n	,	, 7777	l	*	*v}5555	o	-	-!&-dCCCCC	1	1	1%fm<<<<	m	+	+6666	i	'	'FM2222	h	&	&6""""$$Y//-O 44422;;==AAEEFWXX H   F 7777	o	-	-''''	k	)	)fm4444	m	+	+////	i	'	'FM2222	i	'	'FM2222	o	-	-!&-8888	  
 
* 	%V->NNN  !    **955	
 	%&&&&&   s   D* *E/&EEc                     ddl m} m}m}  |            }|                    di           }t          |t                    r<|                    d          pd                                                                }nd}|dk    s|sdS  | d          }|rB |dd           t          t          |          d	k    rd
|dd	          dnd
| d           dS dS )aQ  Remove OPENAI_BASE_URL from ~/.hermes/.env if the active provider is not 'custom'.

    After a provider switch, a leftover OPENAI_BASE_URL causes auxiliary
    clients (compression, vision, delegation) with provider:auto to route
    requests to the old custom endpoint instead of the newly selected
    provider.  See issue #5161.
    r   )r_  r`  rS   rm   r   rn   r  Nrr   r   z.Cleared stale OPENAI_BASE_URL from .env (was: z...)r   )r   r_  r`  rS   r/   r   r   r3   r   r   r*   )r_  r`  rS   r   r   r   	stale_urls          r   r  r  W  s)    MLLLLLLLLL
+--C$$I)T"" MM*--3::<<BBDD88/00I 
("---9~~"" RYss^QQQQN)NNN	
 	
 	
 	
 	

 
r   )	)visionVisionzimage/screenshot analysis)compressionCompressionzcontext summarization)web_extractzWeb extractzweb page summarization)session_searchzSession searchzpast-conversation recall)approvalApprovalzsmart command approval)mcpMCPzMCP tool reasoning)title_generationzTitle generationzsession titles)
skills_hubz
Skills hubzskills search/install)curatorCuratorzskill-usage review pass
_AUX_TASKStask_cfgc                 P   t          | t                    sdS t          |                     d          pd                                          }t          |                     d          pd                                          pd}t          |                     d          pd                                          }|rM|                    dd                              dd                              d          }d	| d
|rd| ndz   S |dk    rd|rd| ndz   S |r| d| S |S )z;Render the current aux config for display in the task menu.r  r   rn   r   rm   r  r  r   zcustom (r       · )r   r   r   r/   r3   rn  r  )r  r   r   rm   shorts        r   _format_aux_currentr    sC   h%% v8<<
++1r2288::H8<<
++5v66<<>>H&HW%%+,,2244E G  R0088BGGNNsSS"%"""&EnUnnn2FF658b99 ('''''Or   rn   rm   r   ru   taskr   ru   c                <   ddl m}m}  |            }|                    di           }t	          |t
                    si }||d<   |                    | i           }	t	          |	t
                    si }	|	|| <   ||	d<   |pd|	d<   |pd|	d<   |pd|	d<    ||           d	S )
u  Persist an auxiliary task's provider/model to config.yaml.

    Only writes the four routing fields — timeout, download_timeout, and any
    other task-specific settings are preserved untouched. The main model
    config (``model.default``/``model.provider``) is never modified.
    r   rS   save_config	auxiliaryr   rn   rm   r   ru   N)r   rS   r!  r  r   r   )
r  r   rm   r   ru   rS   r!  r   auxr  s
             r   _save_aux_choicer$    s     ;:::::::
+--C
..b
)
)Cc4   KNN4$$EeT"" D	 E*[bE'N BE*}"E)Kr   c                     ddl m} m}  |             }|                    di           }t	          |t
                    si }||d<   d}t          D ]\  }}}|                    |i           }t	          |t
                    si }|||<   d}	|                    d          dvrd|d<   d}	d	D ]}
|                    |
          rd
||
<   d}	|	r|dz  } ||           |S )zDReset every known aux task back to auto/empty. Returns number reset.r   r   r"  Fr   )Nrn   r  r  Tr  rn   r   )r   rS   r!  r  r   r   r  r/   )rS   r!  r   r#  countr  _name_descr  changedfields              r   _reset_aux_to_autor+    s,   ::::::::
+--C
..b
)
)Cc4   KE(  eUtR((%&& 	ECI99Z  (::: &E*G5 	 	Eyy !e 	QJEKLr   c                     ddl m}  	  |             }t          |                    d          t                    r|                    di           ni }t                       t          d           t                       t          d           t          d           t          d           t          d	           t          d
           t                       t          d t          D                       dz   }t          d t          D                       dz   }g }t          D ]\  }}}t          |                    |          t                    r|                    |i           ni }	t          |	          }
|	                    |           d|z   dz   	                    |           |
 }|
                    ||f           |
                    d           |
                    d           t          d |D             d          }|dS ||         d         }|dk    rdS |dk    rCt                      }|rt          d| d           nt          d           t                       ct          |           s)u   Top-level auxiliary-model picker — choose a task to configure.

    Loops until the user picks "Back" so multiple tasks can be configured
    without returning to the main provider menu.
    r   rR   Tr"  u(     Auxiliary models — side-task routingz@  Side tasks (vision, compression, web extraction, etc.) defaultu@     to your main chat model.  "auto" means "use my main model" —z>  Hermes only falls back to a lightweight backend (OpenRouter,z<  Nous Portal) if the main model is unavailable.  Override az@  task below if you want it pinned to a specific provider/model.c              3   <   K   | ]\  }}}t          |          V  d S rw   r*   )ry   r   r?   s      r   r{   z#_aux_config_menu.<locals>.<genexpr>  s.      >>ZQas4yy>>>>>>r   r    c              3   <   K   | ]\  }}}t          |          V  d S rw   r.  )ry   r   descs      r   r{   z#_aux_config_menu.<locals>.<genexpr>  s.      >>ZQ4s4yy>>>>>>r   r   (r   )	__reset__zReset all to auto)__back__Backc                     g | ]\  }}|S r   r   r  s      r   r   z$_aux_config_menu.<locals>.<listcomp>  s    +++xq%U+++r   r  Nr3  r2  zReset z auxiliary task(s) to auto.z-All auxiliary tasks were already set to auto.)r   rS   r   r/   r   r   r   r  r  ljustr  r  r+  _aux_select_for_task)rS   r   r#  name_coldesc_colentriestask_keyr?   r0  r  rv  r  r   r   r.  s                  r   r  r    s    .-----+"kmm*4SWW[5I5I4*P*PXcggk2&&&VX8999PQQQTUUUNOOOLMMMPQQQ >>:>>>>>B>>:>>>>>B)+$. 	. 	. HdD0:3778;L;Ld0S0S[swwx,,,Y[H)(33Gzz(++ZcDj3.>-E-Eh-O-OZQXZZENNHe,----9:::,---%++7+++Q
 
 
 ;Fcl1o*F+"$$A G=q===>>>>EFFFGGGS!!!W+"r   c                     ddl m} ddlm}  |            }t	          |                    d          t                    r|                    di           ni }t	          |                               t                    r|                     i           ni }t          |                    d          pd                                          pd}t          |                    d          pd                                          }t          |                    d	          pd                                          }t           fd
t          D                        }		  ||||          }
n+# t          $ r}t          d|            g }
Y d}~nd}~ww xY wg }|dk    r|sdnd}|                    dd| g f           |
D ]}|                    dd          }|                    d          p|}|                    dd          }|                    d          pg }|rd| dnd}||k    r|sdnd}|                    || | | t          |          f           |rdnd}|                    dd| g f           |                    ddg f           t                       t          d|	 dt          |                      t                       t!          d |D             d          }|dS ||         \  }}}|dk    rdS |dk    r(t#           dddd           t          |	 d            dS |dk    rt%           |           dS t'           |||           dS )!ui  Pick a provider + model for a single auxiliary task and persist it.

    Uses ``list_authenticated_providers()`` to only show providers the user
    has already configured. This avoids re-running OAuth/credential flows
    inside the aux picker — users set up new providers through the normal
    ``hermes model`` flow, then route aux tasks to them here.
    r   rR   )list_authenticated_providersr"  r   r  rm   rn   r   c              3   0   K   | ]\  }}}|k    |V  d S rw   r   ry   r   r?   r   r  s       r   r{   z'_aux_select_for_task.<locals>.<genexpr>'  -      LL,#tQtLLr   )current_providerr  current_base_urlz*Could not detect authenticated providers: Nu     ← current__auto__zauto (recommended)r  r?   total_modelsmodelsr  z models
__custom__zCustom endpoint (direct URL)r3  r4  z  Configure u    — current: c                     g | ]\  }}}|	S r   r   r  s      r   r   z(_aux_select_for_task.<locals>.<listcomp>K  s    "D"D"D[Qq5"D"D"Dr   r  r   rm   r   ru   z: reset to auto.)r   rS   hermes_cli.model_switchr=  r   r/   r   r   r3   nextr  r9   r   r  r   r  r  r$  _aux_flow_custom_endpoint_aux_flow_provider_model)r  rS   r=  r   r#  r  rA  r  rB  display_namer  rA   r:  auto_markerr  r  r?   totalrE  r  r  custom_markerr   _labels   `                       r   r7  r7    s    .-----DDDDDD
+--C&01E1Et&L&L
T#''+r
"
"
"RTC$.swwt}}d$C$CKswwtR   H8<<
33=v>>DDFFP&W--344::<<M8<<
339r::@@BBLLLL*LLLdSSL00-'-
 
 
		
    @3@@AAA						 13G%5%?%?HX%?//^`KNNJ B[ B BBGHHH L LuuVR  uuV}}$na((x&B/4<+U++++"
$(,<$<$<EU$<[];z;6;;T&\\JKKKK (8?OORMNNL"P"P"PRTUVVVNNJ+,,,	GGG	
T
T
T5H5R5R
T
TUUU	GGG
!"D"DG"D"D"Da
P
P
PC
{"3<D&&zzb2rRRRR///000|!$111 T4?????s   E- -
F7FFprovider_slugcurated_modelsr  c                 x    ddl m} ddlm} t	           fdt
          D                        }i }	  ||          pi }n# t          $ r i }Y nw xY wt          |          }|spt          d| d           t          d           	 t          d          
                                }	n&# t          t          f$ r t                       Y d	S w xY w|	pd
}
n! ||||          }
|
t          d           d	S t           ||
pd
d
d
           |
rt          | d| d|
            d	S t          | d| d           d	S )zHPrompt for a model under an already-authenticated provider, save to aux.r   )_prompt_model_selection)get_pricing_for_providerc              3   0   K   | ]\  }}}|k    |V  d S rw   r   r?  s       r   r{   z+_aux_flow_provider_model.<locals>.<genexpr>j  r@  r   zNo curated model list for .z;Enter a model slug manually (blank = use provider default):zModel: Nrn   r  pricingr  rH  : r  z (provider default model))r   rU  r  rV  rJ  r  r9   r   r   r  r3   r  r  r$  )r  rR  rS  r  rU  rV  rM  rZ  
model_listr   selecteds   `          r   rL  rL  `  s    877777::::::LLLL*LLLdSSL G**=99?R    n%%J
  ;=;;;<<<KLLL		""((**CC!8, 	 	 	GGGFF	 9"**mW
 
 
 ,FTMR ". . . . K>>>>H>>?????IIIIIJJJJJs#   A   AA!B( (C
Cc                     ddl }t           fdt          D                        }t          |                    d          pd                                          }t          |                    d          pd                                          }t                       t          d|            t          d           t                       	 |rd	| d
nd}t          |                                          }n&# t          t          f$ r t                       Y dS w xY w|p|}|st          d           dS 	 |rd| d
nd}t          |                                          }	n&# t          t          f$ r t                       Y dS w xY w|	p|}		 |                     d                                          }
n&# t          t          f$ r t                       Y dS w xY wt           d|	||
           |                    dd                              dd                              d          }t          | d| d|	rd|	 ndz              dS )zHPrompt for a direct OpenAI-compatible base_url + optional api_key/model.r   Nc              3   0   K   | ]\  }}}|k    |V  d S rw   r   r?  s       r   r{   z,_aux_flow_custom_endpoint.<locals>.<genexpr>  r@  r   r   rn   rm   z  Custom endpoint for zH  Provide an OpenAI-compatible base URL (e.g. http://localhost:11434/v1)
Base URL [r  z
Base URL: zNo URL provided. No change.zModel slug (optional) [zModel slug (optional): z0API key (optional, blank = use OPENAI_API_KEY): r  rH  r  r  r   z
: custom (r   r  )getpassrJ  r  r   r/   r3   r   r  r  r  r$  rn  r  )r  r  ra  rM  rB  r  
url_prompturlmodel_promptrm   ru   r  s   `           r   rK  rK    s   NNNLLLL*LLLdSSL8<<
339r::@@BBW--344::<<M	GGG	
1<
1
1222	
TUUU	GGG;K]7"27777Q]
J%%''x(    
!!C +,,,GTsCCCCCZsl##))++x(    "]E//"TUU[[]]x(    xusG    J++33IrBBII#NNI	\
1
1Y
1
1
1u5T^E^^^RT
UVVVVVs6   +C= =D D ;+E' 'F
	F
'F: :GGr  c          	         	 ddl m}  |d| |          }|dk    rt                       |S n# t          $ r Y nw xY wt          d           t	          | d          D ]*\  }}|dz
  |k    rdnd}t          d| d| d|            +t                       	 	 t          d
t          |            d|dz    d                                          }|s|S t          |          dz
  }d|cxk    rt          |           k     rn n|S t          dt          |                       n@# t          $ r t          d           Y n%t          t          f$ r t                       Y dS w xY w)zShow provider selection menu with curses arrow-key navigation.

    Falls back to a numbered list when curses is unavailable (e.g. piped
    stdin, non-TTY environments).  Returns the selected index, or None
    if the user cancels.
    r   )_curses_prompt_choicezSelect provider:r   u   →r   r   r  T
Choice [1-z] (): Please enter 1-Please enter a numberN)rH  rf  r   r9   r)   r  r*   r3   rc   r7   r  r  )choicesr
   rf  r   r<   cr  r   s           r   r  r    s   ::::::##$6II!88GGGJ      

'1%% & &1a%7**$6$$A$$$$%%%%	GGG	FS\\FFgkFFFGGMMOOC c((Q,CC&&&&#g,,&&&&&
2CLL223333 	+ 	+ 	+)*****!8, 	 	 	GGG44	s0   (, 
99;D# 0D# D# #E >E E c                 ^   ddl m}m}m} ddlm}m}  |d          }|st          d           t          d           t                       	 ddl}|                    d          	                                }	n&# t          t          f$ r t                       Y dS w xY w|	st          d	           dS  |d|	           t          d
           t                       ddlm}
m}  |
d          } |dd          } ||||          }|r ||           ddlm}m}  |            }|                    d          }t%          |t&                    s|rd|ini }||d<   d|d<   t(          |d<   d|d<    ||            |             t          d| d           dS t          d           dS )z5OpenRouter provider: ensure API key, then pick model.r   rU  _save_model_choicedeactivate_providerr^  rt   z!No OpenRouter API key configured.z&Get one at: https://openrouter.ai/keysNz)OpenRouter API key (or Enter to cancel): 
Cancelled.API key saved.)	model_idsrV  Tforce_refreshr  rY  r   rm   r
   r   r   chat_completionsr  Default model set to: z (via OpenRouter)r  )r   rU  ro  rp  r   r_  r`  r   ra  r3   r  r  r  rs  rV  rS   r!  r/   r   r   r\   )r  r  rU  ro  rp  r_  r`  ru   ra  r   rs  rV  openrouter_modelsrZ  r]  rS   r!  r   rm   s                      r   r  r    s            
 @???????m011G 12226777	NNN//"MNNTTVVCC!8, 	 	 	GGGFF	  	,F+S111EEEEEEEE!	555 '&|4HHHG&&  H  8$$$ 	?>>>>>>>kmm  %&& 	!*/7Y&&RE CL(j/j.jCBxBBBCCCCCls   +A9 9BBc                 |   ddl m}m}m} ddlm}m}  |d          }|st          d           t          d           t          d           t                       	 ddl}|                    d	          	                                }	n&# t          t          f$ r t                       Y dS w xY w|	st          d
           dS  |d|	           t          d           t                       ddlm}
m}  |
d          } |dd          } ||||          }|r ||           ddlm}m}  |            }|                    d          }t%          |t&                    s|rd|ini }||d<   d|d<   t(          |d<   d|d<    ||            |             t          d| d           dS t          d           dS )zIVercel AI Gateway provider: ensure API key, then pick model with pricing.r   rn  r^  AI_GATEWAY_API_KEYz(No Vercel AI Gateway API key configured.z^Create API key here: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai-gateway&title=AI+Gatewayz/Add a payment method to get $5 in free credits.Nz)AI Gateway API key (or Enter to cancel): rq  rr  )ai_gateway_model_idsrV  Trt  r  rY  r   rm   r
   r   r   rv  r  rw  z (via Vercel AI Gateway)r  )r   rU  ro  rp  r   r_  r`  r   ra  r3   r  r  r  r{  rV  rS   r!  r/   r   r   r[   )r  r  rU  ro  rp  r_  r`  ru   ra  r   r{  rV  models_listrZ  r]  rS   r!  r   rm   s                      r   r  r  	  s            
 @???????m011G 8999nooo?@@@	NNN//"MNNTTVVCC!8, 	 	 	GGGFF	  	,F+S111PPPPPPPP&&T:::K&&|4HHHG&&='  H  8$$$>>>>>>>>kmm  %&& 	!*/7Y&&RE CL(j/j.jCIxIIIJJJJJls   +B B+*B+c                 
   ddl m}m}m}m}m}m}m}	m}
m	} ddl
m}m}m}m} ddlm}  |d          }|r|                    d          sQt%          d           t%                       	 t'          j        t+          |dd	          t+          |d
d	          t+          |dd	          t+          |dd	          t-          t+          |dd                    t+          |dd	          pdt+          |dd	          t-          t+          |dd                              } |
||d                    	  |            pi } ||           n# t.          $ r Y nw xY wnE# t0          $ r t%          d           Y d	S t.          $ r}t%          d|            Y d	}~d	S d	}~ww xY wd	S ddlm}m}m}m}  |            }|st%          d           d	S 	  |d          }n# t.          $ r}t=          ||          o|j        }t=          ||          r |	|          ntA          |          }|rt%          d|            t%          d           	 t'          j        d	d	d	d	ddd	d          } |
||d                    n)# t.          $ r}t%          d|            Y d	}~nd	}~ww xY wY d	}~d	S t%          d|            Y d	}~d	S d	}~ww xY w |d          } |            }g } |r |||d          \  }} |s| st%          d            d	S d!}!	  |d          }"|"r|"                    d"d!          }!n# t.          $ r Y nw xY w|rE|sCt%          d#           | r0dd$l m!}# |!p|#"                    d%          }$t%          d&|$ d'           d	S t%          d(tG          |           d)            ||||| |!*          }%|%rK ||%           |                    d+d!          }& |d|&           |                     d,          }'t=          |'tH                    rtI          |'          }(nBt=          |'t@                    r+|'%                                rd-|'%                                i}(ni }(d|(d.<   |%|(d-<   |&r-|&%                                r|&"                    d%          |(d+<   n|(&                    d+d	           |(| d,<    |d/          r |d/d!            |d0d!            ||            t%          d1|% d2            ||            d	S t%          d3           d	S )4z8Nous Portal provider: ensure logged in, then pick model.r   )	get_provider_auth_staterU  ro  _update_config_for_provider resolve_nous_runtime_credentialsr  r  _login_nousro   )r_  rS   r!  r`  )prompt_enable_tool_gatewayr  access_tokenz.Not logged into Nous Portal. Starting login...
portal_urlNinference_url	client_idscope
no_browserFr3        .@	ca_bundleinsecure)r  r  r  r  r  r3  r  r  Login cancelled or failed.Login failed: )get_curated_nous_model_idsrV  check_nous_free_tierpartition_nous_models_by_tierz,No curated models available for Nous Portal.i,  )min_key_ttl_secondszSession expired: z&Re-authenticating with Nous Portal...
zRe-login failed: zCould not verify credentials: T)	free_tierz4No models available for Nous Portal after filtering.rn   portal_base_urlz#No free models currently available.)DEFAULT_NOUS_PORTAL_URLr   zUpgrade at z to access paid models.zShowing =    curated models — use "Enter custom model name" for others.)r  rZ  unavailable_modelsr  r   rm   r
   r   rr   rp   rw  z (via Nous Portal)r  )'r   r~  rU  ro  r  r  r  r  r  ro   r   r_  rS   r!  r`  hermes_cli.nous_subscriptionr  r/   r   r   	NamespacerG  r  r9   
SystemExitr  r  rV  r  r  r   relogin_requiredr   r  r  r*   r   r3   pop))r  r  rL  r~  rU  ro  r  r  r  r  r  ro   r_  rS   r!  r`  r  state	mock_args
_refreshedrA   r  rV  r  r  rs  r   reloginr  	login_excrZ  r  r  _nous_portal_url_nous_stater  _urlr]  r  current_model_cfgr   s)                                            r   r  r  V	  s   
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
            HGGGGG##F++E 		.11 >???	 *"4t<<%dOTBB!$T::dGT22lE B BCCi66>$!$T::gdJ>>??	 	 	I K	#4V#<===([]]0b
**:6666    	 	 	.///FF 	 	 	(3(()))FFFFF	 	
            +*,,I <===00VLLL   S),,E1E(23	(B(BP$$$C 	+c++,,,;<<<7$.#"&"$ ""	 	 		 I'8'@AAAA 7 7 75)55666666667FFFFF4s44555-2 '&v..G %$&&I %' 
(E(Ew$)
 )
 )
%	%  / DEEE --f55 	F*/@"EE      3444 	???????$?(?GGLLD====>>>	`3y>>```   '&#-#  H  8$$$		*b11##FM:::"JJw//'.. 	.//II)3// 	4E4K4K4M4M 	"$5$;$;$=$=>III &	*'	) 	,]0022 	,$1$8$8$=$=Ij!!MM*d+++#w=*++ 	1N,b111N+R000FCxCCCDDD""6*****ls   *CE -E E 
EE EE F2	F;FFG 
J>A$J9.I21J92
J<JJ9JJ9!J99J>#L' '
L43L4c                    ddl m}m}m}m}m}m}m} ddlm	}	  |            }
|

                    d          r_t          d           t                       t          d           t          d           t          d           t                       	 t          d	                                          }n# t          t          f$ r d
}Y nw xY w|dk    rt          d           t                       	 t!          j                    } |||d         d           nE# t$          $ r t          d           Y dS t&          $ r}t          d|            Y d}~dS d}~ww xY w |            }
|

                    d          st          d           dS n|dk    rdS nt          d           t                       	 t!          j                    } |||d                    nE# t$          $ r t          d           Y dS t&          $ r}t          d|            Y d}~dS d}~ww xY wd}	  |            }|
                    d          r|
                    d          }n# t&          $ r Y nw xY w|s7	 ddl m}  |            }|
                    d          }n# t&          $ r Y nw xY w |	|          } |||          }|r, ||            |d|           t          d| d           dS t          d           dS )z9OpenAI Codex provider: ensure logged in, then pick model.r   )get_codex_auth_statusrU  ro  r  _login_openai_codexro   DEFAULT_CODEX_BASE_URL)get_codex_model_idsr}   u     OpenAI Codex credentials: ✓    1. Use existing credentials'    2. Reauthenticate (new OAuth login)    3. Cancel  Choice [1/2/3]: r  2z&Starting a fresh OpenAI Codex login...r  T)force_new_loginr  Nr  zLogin failed.3z/Not logged into OpenAI Codex. Starting login...ru   )!resolve_codex_runtime_credentials)r  r  rw  z (via OpenAI Codex)r  )r   r  rU  ro  r  r  ro   r  hermes_cli.codex_modelsr  r/   r   r  r3   r  r  r   r  r  r9   r  )r  r  r  rU  ro  r  r  ro   r  r  r   rs  r  rA   _codex_token_codex_statusr  _codex_credscodex_modelsr]  s                       r   r  r  
  sO                     <;;;;;""$$Fzz+ -/000/0007888o	/006688FF!8, 	 	 	FFF	 S==:;;;GGG$.00	##%n5$(    
    2333   ,s,,--- +*,,F::k** o&&& s]]F  	?@@@	 *,,I	+<^+LMMMM 	 	 	.///FF 	 	 	(3(()))FFFFF	 L--//[)) 	8(,,Y77L    	IIIIII<<>>L'++I66LL 	 	 	D	 '&LAAAL&&|=QQQH 8$$$##N4JKKKDxDDDEEEEElsr   !B4 4C
	C
1'D E5	E>EE6%G H8	HHH$4I 
I&%I&,%J 
JJqwen3-coder-pluszqwen3-coderc                    ddl m}m}m}m}m}m} ddlm}  |            }	|		                    d          st          d           t          d           |		                    d          }
|
rt          d|
            |		                    d	          r%t          d
|		                    d	                      dS d}	  |d          } ||d         |d                   }n# t          $ r Y nw xY w|st          t                    }|p|r|d         nd} |||          }|r, ||            |d|           t          d| d           dS t          d           dS )zAQwen OAuth provider: reuse local Qwen CLI login, then pick model.r   )get_qwen_auth_status resolve_qwen_runtime_credentialsrU  ro  r  DEFAULT_QWEN_BASE_URLfetch_api_modelsr}   zNot logged into Qwen CLI OAuth.zRun: qwen auth qwen-oauthr   zExpected credentials file: r   r'   NT)refresh_if_expiringru   r   r  r  r  rw  z (via Qwen OAuth)r  )r   r  r  rU  ro  r  r  r  r  r/   r   r9   r   _DEFAULT_QWEN_PORTAL_MODELS)_configr  r  r  rU  ro  r  r  r  r   r   rE  r   r
   r]  s                  r   r  r  b
  s                   322222!!##F::k"" /000)***JJ{++	 	=;	;;<<<::g 	31FJJw//11222 F00TJJJ!!%	"2E*4EFF    3122LV Kq		9KG&&vWEEEH 8$$$##L2GHHHBxBBBCCCCCls   <$C! !
C.-C.c           
      &   ddl m}m}m}m}m}m}m}	m}
m	}  |d          }|r|
                    d          st          d           t                       	 t          j        t          |dd          pdt          t          |d	d
                    t          |dd          pd          } |
||d                    nE# t           $ r t          d           Y dS t"          $ r}t          d|            Y d}~dS d}~ww xY w	  |            }n+# |$ r#}t           |	|                     Y d}~dS d}~ww xY wddlm}  |j
        dg           } |||          }|sdS  ||            |d|d                    t          d|            dS )z:MiniMax OAuth provider: ensure logged in, then pick model.r   )	r~  rU  ro  r  )resolve_minimax_oauth_runtime_credentialsr  r  _login_minimax_oauthro   r  r  z0Not logged into MiniMax. Starting OAuth login...regionNglobalr  Fr3  r  )r  r  r3  r  r  _PROVIDER_MODELSr   u   ✓ Using MiniMax model: )r   r~  rU  ro  r  r  r  r  r  ro   r/   r   r   r  rG  r  r  r9   r  r  )r  r  rL  r~  rU  ro  r  r  r  r  r  ro   r  r  rA   r   r  rs  r]  s                      r   r  r  
  s   
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 $#O44E 		.11 @AAA	 *tXt44@lE B BCCi66>$  I
 ! ,=o,NOOOO 	 	 	.///FF 	 	 	(3(()))FFFFF	99;;   $$%%% 322222$ $_b99I&&y-@@H x   z1BCCC	
3
3
344444s7   A'B? ?D	D$C<<D
D D8D33D8c                 j   ddl m}m}m}m}m}m} ddlm} t                       t          d           t          d           t          d           t          d           t                       	 t          d                                                                          }	n'# t          t          f$ r t          d	           Y d
S w xY w|	dvrt          d	           d
S  |            }
|
                    d          sK	 ddlm}m}  |            } |d|           n*# t&          $ r}t          d|            Y d
}~d
S d
}~ww xY w	  |d          }|                    dd          }|rt          d|            nt          d           n*# t&          $ r}t          d|            Y d
}~d
S d
}~ww xY wt)           |j        d          pg           }|p|r|d         nd} |||          }|r, ||            |d|           t          d| d           d
S t          d           d
S )u  Google Gemini OAuth (PKCE) via Cloud Code Assist — supports free AND paid tiers.

    Flow:
      1. Show upfront warning about Google's ToS stance (per opencode-gemini-auth).
      2. If creds missing, run PKCE browser OAuth via agent.google_oauth.
      3. Resolve project context (env -> config -> auto-discover -> free tier).
      4. Prompt user to pick a model.
      5. Save to ~/.hermes/config.yaml.
    r   )!DEFAULT_GEMINI_CLOUDCODE_BASE_URLget_gemini_oauth_auth_status(resolve_gemini_oauth_runtime_credentialsrU  ro  r  r  uH   ⚠  Google considers using the Gemini CLI OAuth client with third-partyz@   software a policy violation. Some users have reported accountzC   restrictions. You can use your own API key via 'gemini' providerz"   for the lowest-risk experience.z"Continue with OAuth login? [y/N]: rq  N>   r
  r0  r}   )resolve_project_id_from_envstart_oauth_flowT)force_relogin
project_idzOAuth login failed: Frt  r  rn   z  Using GCP project: uT     No GCP project configured — free tier will be auto-provisioned on first request.z&Failed to resolve Gemini credentials: r  zgemini-3-flash-previewr  rw  z( (via Google Gemini OAuth / Code Assist)r  )r   r  r  r  rU  ro  r  r  r  r   r  r3   r   r  r  r/   agent.google_oauthr  r  r9   r   )r  r  r  r  r  rU  ro  r  r  proceedr   r  r  env_projectrA   r   r  rE  r
   r]  s                       r   r  r  
  sO                   322222	GGG	
TUUU	
LMMM	
OPPP	
.///	GGG<==CCEEKKMM'(   l l""l))++F::k"" 	XXXXXXXX5577K4KHHHHH 	 	 	...///FFFFF	
88uMMMYY|R00
 	6*667777f      <s<<=== &"&':;;ArBBFRV Qq		9QG&&vWEEEH 	8$$$##!B	
 	
 	
 	WXWWW	
 	
 	
 	
 	
 	lsC   03B$ $ CC D   
E*EEAF 
F9F44F9c           
      b   ddl m}m} ddlm}m}m}  |d          pd} |d          pd}t          d           |rt          d|            |rt          d	|d
d          d           t                       	 t          d|pd d          	                                }dd
l
}	|	
                    d|r|d
d         dz   nd d          	                                }
n'# t          t          f$ r t          d           Y d
S w xY w|s|st          d           d
S |p|}|                    d          st          d| d           d
S |
p|}|                    d                                          t!          fddD                       }|r                    d          st                       t          d           t          d           t          d|                    d           d           	 t          d          	                                                                }n# t          t          f$ r d}Y nw xY w|d v r.|                    d          dz   }|r|}t          d!|            t                       dd"lm}  |||          }|                    d#          r;|                    d$          r&t          d%|d$          d&           |d$         }|r|}n|                    d'          Lt          d(|                    d)           d*t+          |                    d'          pg            d+           n}t          d,|                    d)           d-           |                    d.          rB|d.         }|                    d          rt          d/|            nt          d0|            d}|                    d'          pg }	 t+          |          d1k    r{t          d2|d                     t          d3          	                                                                }|d v r
|d         }nt          d4          	                                }nt+          |          d1k    rt          d5           t-          |d1          D ]\  }}t          d6| d7|            t          d8t+          |           d9          	                                }|                                rCd1t1          |          cxk    rt+          |          k    rn n|t1          |          d1z
           }n&|r|}n!t          d4          	                                }t          d:          	                                }t3          |          }t          d;| d          	                                p|}n'# t          t          f$ r t          d           Y d
S w xY wd
}|rz	 t1          |                    d<d                              d=d>                              d?d>                    }|dk    rd
}n%# t6          $ r t          d@| dA           d
}Y nw xY w|r ||            |            }|                    dB          }t9          |t:                    s|rdC|ini }||dB<   dD|dE<   ||dF<   |r||dG<   |                    dHd
            ||            |             t;          |          | dB<   t          dI| dJ| dK           n{|s|
r
 |             |                     dB          }t9          |t:                    s|rdC|ini }dD|dE<   ||dF<   |r||dG<   |                    dHd
           || dB<   t          dL           t?          |||pd||M           d
S )NzCustom endpoint: collect URL, API key, and model name.

    Automatically saves the endpoint to ``custom_providers`` in config.yaml
    so it appears in the provider menu on subsequent runs.
    r   ro  rp  )r_  rS   r!  rr   rn   rp   z0Custom OpenAI-compatible endpoint configuration:z  Current URL: z  Current key: Nr   r  zAPI base URL [ze.g. https://api.example.com/v1r  	API key [r  
Cancelled.zNo URL provided. Cancelled.r  r  Invalid URL: & (must start with http:// or https://)r   c              3       K   | ]}|v V  	d S rw   r   )ry   h
_url_lowers     r   r{   z%_model_flow_custom.<locals>.<genexpr>7  s;         	
Z     r   )	localhost	127.0.0.1z0.0.0.0z:11434z:8080z:5000z/v1z+  Hint: Did you mean to add /v1 at the end?z@  Most local model servers (Ollama, vLLM, llama.cpp) require it.z  e.g. z  Add /v1? [Y/n]: r.  r/  z  Updated URL: )probe_api_modelsused_fallbackresolved_base_urlz)Warning: endpoint verification worked at zL/models, not the exact URL you entered. Saving the working base URL instead.rE  zVerified endpoint via 
probed_urlr  z model(s) visible)z,Warning: could not verify this endpoint via z. Hermes will still save it.suggested_base_urlz8  If this server expects /v1 in the path, try base URL: z-  If /v1 should not be in the base URL, try: r   z  Detected model: z  Use this model? [Y/n]: z&Model name (e.g. gpt-4, llama-3-70b): z  Available models:    r  z  Select model [1-z] or type name: z8Context length in tokens [leave blank for auto-detect]: zDisplay name [r  r  000KzInvalid context length: u    — will auto-detect.rm   r
   r  r   r   ru   r  rw   (via r   zFEndpoint saved. Use `/model` in chat or `hermes model` to set a model.)context_lengthr?   ) r   ro  rp  r   r_  rS   r!  r   r  r3   ra  r  r  r+   r  r   r   r  r  r  r/   r*   r)   isdigitrc   _auto_provider_namern  r7   r   r   r  _save_custom_provider) r  ro  rp  r_  rS   r!  current_urlcurrent_keyr   ra  ru   effective_urleffective_key_looks_local_add_v1r  rR  	suggested
model_namedetected_modelsconfirmr<   mpickcontext_length_strdefault_namerM  r  r   rm   _caller_modelr  s                                   @r   r  r    s	    HGGGGGGGIIIIIIIIII- 1228bK- 0117RK	
<=== /---... 64BQB444555	GGGR[M,MRRR
 

%'' 	 	//S;NBQB%//JSSS
 

%'' 	 x(   n  K +,,, +M##$;<< SmSSSTTT*{M
 %%c**0022J    R    L  J//66 <===QRRR6,,S11666777	0117799??AAGG!8, 	 	 	GGG	&&&)0055=M )(3M33444222222]M::Eyy!! Seii0C&D&D SS>Q8R S S S	
 	
 	
 12 	%$H	8			(CUYY|%<%< C CEIIh''-2..C C C	
 	
 	
 	

 	*599\;R;R * * *	
 	
 	
 99)** 	S23I!!%(( SZyZZ    QiQQRRR Jii))/RO1$$;q'9;;<<<788>>@@FFHHG***,Q/

"#KLLRRTT

!!A%%'(((!/155 ' '1oQoo!oo&&&&KS%9%9KKK egg  ||~~ "!s4yy"H"H"H"HC4H4H"H"H"H"H"H,SYY];

 "!
GHHNNPPJ"F
 

%'' 	
 +=99?l???@@FFHHXLx(   n N "
	" "**333e$$e$$ N
 ""!% 	" 	" 	"W-?WWWXXX!NNN	"  &X:&&& kmm  %&& 	!*/7Y&&RE CL$j)j 	-,E)		*d###C u++wIzIIIIIJJJJ 	"w 	"!!! 

7++-.. 	P:GOY66RM$,j!$1j! 	5'4M)$*d+++'wVWWW b%     sK   =A%C# # DD=3H1 1II$G!W  W*)W*2AY Y('Y(c                 l   ddl }|                     dd                              dd                              d          }|                    dd|          }|                    d          d         }d|v sd	|v rd
| d}n1d|                                v rd| d}n|                                }|S )zGenerate a display name from a custom endpoint URL.

    Returns a human-friendly label like "Local (localhost:11434)" or
    "RunPod (xyz.runpod.io)".  Used as the default when prompting the
    user for a display name during custom endpoint setup.
    r   Nr  rn   r  r   z/v1/?$r  r  zLocal (r   runpodzRunPod ()rern  r  subr,   r   
capitalize)r   r  cleanr?   s       r   r  r    s     IIIZ,,44YCCJJ3OOEFF9b%((E;;sADdkT11    	TZZ\\	!	!!$!!!  Kr   c                    t          |                     dd          pd                                          }|r|S t          |                     dd          pd                                          }|r=t          |                     dd          pd                                          sd| dS t          |pd                                          S )zDReturn the value that should be persisted for a custom provider key.r  rn   r  ru   r  })r   r/   r3   )r  resolved_api_keyr  r  s       r   %_custom_provider_api_key_config_valuer    s    m''r::@bAAGGIIK -##Ir228b99??AAG !s=,,Y;;ArBBHHJJ ! W    %2&&,,...r   c                    ddl m}m}  |            }|                    d          pg }t	          |t
                    sg }|D ]}	t	          |	t                    r|	                    dd                              d          |                     d          k    rxd}
|r |	                    d          |k    r||	d<   d	}
|r=|r;|	                    d
i           }t	          |t                    si }d|i||<   ||	d
<   d	}
|
r||d<    ||            dS |st          |           }|| d}	|r||	d<   |r||	d<   |r|r	|d|ii|	d
<   |	                    |	           ||d<    ||           t          d| d           dS )u  Save a custom endpoint to custom_providers in config.yaml.

    Deduplicates by base_url — if the URL already exists, updates the
    model name and context_length but doesn't add a duplicate entry.
    Uses *name* when provided, otherwise auto-generates from the URL.
    r   r   r  r   rn   r   Frm   TrE  r  N)r?   r   ru   u%     💾 Saved to custom providers as "z" (edit in config.yaml))r   rS   r!  r/   r   r   r   r  r  r  r   )r   ru   rm   r  r?   rS   r!  r   r  r  r)  
models_cfgs               r   r  r    s#    ;:::::::
+--C*++1rIi&& 	   eT"" 	uyyR'@'@'G'G(
 (
__S!!(" (" G 7++u44!&g  "YYx44
!*d33 $!#J%5~$F
5!",h !*3&'C   FF  -"8,,x00E #"i g F F #3^"DEhU'CK	
O$
O
O
OPPPPPr   c                    ddl m}m} ddlm}m}m}m} ddlm	} ddl
}	|                     di           }
t          |
t                    rd|
                    d          dk    rKt          |
                    d	d
          pd
          }t          |
                    dd
          pd
          }nd
}d
} |d          pd
}t                       t          d           t          d           t                       t          d           t          d           t          d           t          d           t                       |rt          d|            |r|dk    rdnd}t          d|            |rt          d|dd          d           t                       	 t!          d|pd d                                          }n'# t$          t&          f$ r t          d           Y dS w xY w|p|                    d          }|st          d            dS |                    d!          st          d"| d#           dS t                       	 |	
                    d$|r|dd         dz   nd% d                                          }n'# t$          t&          f$ r t          d           Y dS w xY w|p|}|st          d&           dS t                       t          d'           |                    ||          }t/          |j                  }|j        pd
}|r^|dk    rdnd}t          d(|            |j        rt          d)|j         d*           |r t          d+t7          |           d,           nt          d-|j                    t                       t          d.           t          d/           t          d0           t          d1           t          d2           	 |d3k    rd4nd5}t!          d6| d7                                          p|}n'# t$          t&          f$ r t          d           Y dS w xY w|d4k    rd3nd}t                       d
}|rSt          d8           t9          |dd9         d:;          D ]\  }}t          d<|d=d>|            t7          |          d9k    r#t          d?t7          |          d9z
   d@           t                       	 t!          dA|p|d          d                                          }n'# t$          t&          f$ r t          d           Y dS w xY w|s|p|d         }n|                                rQd:t=          |          cxk    r!t?          t7          |          d9          k    rn n|t=          |          d:z
           }nW|}nT	 t!          dB|pdC d                                          }n'# t$          t&          f$ r t          d           Y dS w xY w|p|}|st          dD           dS |                     |||          } |d|            |            }|                    d          } t          | t                    s| rdE| ini } | |d<   d| d<   || d	<   || d<   || dE<   |r|| dF<    ||            |             t          |           | d<    |dG          r |dGd
            |dH          r |dHd
           |dk    rdnd}t                       t          dI           t          dJ|            t          dK|            t          dL|            |rt          dM|dNdO           nt          dP           t                       dS )Qu.  Azure Foundry provider: configure endpoint, API mode, API key, and model.

    Azure Foundry supports both OpenAI-style (``/v1/chat/completions``) and
    Anthropic-style (``/v1/messages``) endpoints.  The wizard auto-detects
    the transport and available models when possible:

    * URLs ending in ``/anthropic`` → Anthropic Messages API.
    * Successful ``GET <base>/models`` probe → OpenAI-style + populates
      a picker with the returned deployment / model IDs.
    * Anthropic Messages probe fallback when ``/models`` fails.
    * Manual entry when every probe fails (private endpoints, etc.).

    Context lengths for the chosen model are resolved via the standard
    :func:`agent.model_metadata.get_model_context_length` chain
    (models.dev, provider metadata, hardcoded family fallbacks).
    r   r  r_  r`  rS   r!  )azure_detectNrm   r   r  r   rn   r  AZURE_FOUNDRY_API_KEYzAzure Foundry Configurationra  z9Azure Foundry can host models with either OpenAI-style orz6Anthropic-style API endpoints.  Hermes will probe yourz6endpoint to auto-detect the transport and the deployedzmodels when possible.z  Current endpoint: rv  zOpenAI-stylezAnthropic-stylez  Current API mode: z  Current API key:  r   r  zAPI endpoint URL [z5e.g. https://your-resource.openai.azure.com/openai/v1r  r  r   z$No endpoint URL provided. Cancelled.r  r  r  r  requiredzNo API key provided. Cancelled.u;   ◐ Probing endpoint to auto-detect transport and models...u   ✓ Detected API transport: z    (r   u
   ✓ Found z# deployed model(s) on this endpointu   ⚠ Auto-detection incomplete: z7Select the API format your Azure Foundry endpoint uses:z.  1. OpenAI-style  (POST /v1/chat/completions)z:     For: GPT models, Llama, Mistral, and most open modelsz)  2. Anthropic-style  (POST /v1/messages)z9     For: Claude models deployed via Anthropic API formatanthropic_messagesr  r  zAPI format [1/2] (rh  z"Available models on this endpoint:   r   )rB   r   z>2r  z
  ... and z' more (type name manually if not shown)z+Pick by number, or type a deployment name [zModel / deployment name [ze.g. gpt-5.4, claude-sonnet-4-6z"No model name provided. Cancelled.r
   r  rr   rp   u   ✓ Azure Foundry configured:z    Endpoint:       z    API mode:       z    Model:          z    Context length: r  z tokenszA    Context length: not auto-detected (will fall back at runtime))!r   ro  rp  r   r_  r`  rS   r!  
hermes_clir
  ra  r/   r   r   r   r   r  r3   r  r  r  r+   detectr   rE  r  reasonr*   r)   r  rc   r   lookup_context_length)!r  r  ro  rp  r_  r`  rS   r!  r
  ra  r   rB  current_api_modecurrent_api_key_lblr   r  ru   r  	detectiondiscovered_modelsr  ru  default_choicemode_choiceeffective_modelr<   midr  r  ctx_lenr   rm   s!                                    r   r  r  &  s	   " HGGGGGGGYYYYYYYYYYYY''''''NNN 

7B''I)T"" y}}Z'@'@O'S'Sy}}Z<<BCCy}}Z<<BCC#m$;<<BO	GGG	
'(((	(OOO	GGG	
EFFF	
BCCC	
BCCC	
!"""	GGG 97%577888 -!15G!G!G~~M^+T++,,, ?=_RaR%8===>>>	GGGq!1!l5lqqq
 

%'' 	 x(   n 1!199#>>M 4555##$;<< SmSSSTTT 
GGG//[V+e33J[[[
 

%'' 	 x(   n .M /000 
GGG	
GHHH##M=AAI#'	(8#9#9&,"H V'/3E'E'E^^K\
9Z99::: 	/-)*---... 	\Zs#455ZZZ[[[B	0@BBCCCGHHH>???JKKK9:::IJJJ	$48L$L$LSSRUN H^ H H HIIOOQQcUcKK!8, 	 	 	.!!!FF	 ,7#+=+=''CU 
GGGO 62333 1#2# 6a@@@ 	& 	&FAs$q$$$s$$%%%% !!B&&cs#455:cccddd	hm>cO`abOchhh egg D "8, 	 	 	.!!!FF	  	#+C/@/COO\\^^ 	#SYY Q Q Q Q#c:K6L6Lb2Q2Q Q Q Q Q Q/D		A>OO"OO	cM,^=^ccc egg J "8, 	 	 	.!!!FF	 %5 2333 00 G
 N*M:::
+--CGGGEeT"" &+3E""G'E*%E* E*&E) *")K5kkF7O }&'' .("---}%&& -',,,#+/A#A#AGXJ	GGG	
)***	
0
0
0111	
-
-
-...	
2
2
2333 S7W77778888QRRR	GGGGGsZ   !'G	 	 G-,G-:J  J21J2-1P  QQ,-T  T>=T>7'W  XXc           
         ddl m}m}  |            }|                    d          pg }t	          |t
                    r|st          d           dS t          d           g }|D ]}t	          |t                    r|                    dd          }|                    d	d
          }|                    dd
                              dd
          	                    d          }	|
                    | d|	 d           |
                    t          |                     |
                    d           	 ddlm}
  |
d |D             ddddddd          }|                                }ddlm}  |             t                       n# t"          t$          t&          t(          j        f$ r t-          |d          D ]\  }}t          d| d|            t                       	 t/          dt1          |           d                                          }|rt5          |          dz
  nd}n# t6          t8          t:          f$ r d}Y nw xY wY nw xY w||t1          |          k    rt          d            dS |                    |          }||d<    ||           t	          |t                    r|                    dd          nt          |          }t          d!| d"           dS )#z=Let the user remove a saved custom provider from config.yaml.r   r   r  zNo custom providers configured.NzRemove a custom provider:
r?   unnamedr   rn   r  r  r   r  r   CancelTerminalMenuc                     g | ]}d | S r   r   )ry   rl  s     r   r   z+_remove_custom_provider.<locals>.<listcomp>  s    '''!X!XX'''r   -> )fg_redbold)r%  TFzSelect provider to remove:cursor_indexmenu_cursormenu_cursor_stylemenu_highlight_stylecycle_cursorclear_screenr   flush_stdinr   r   r  rg  r  r  u   ✅ Removed "z" from custom providers.)r   rS   r!  r/   r   r   r   r   rn  r  r  r   simple_term_menur!  showhermes_cli.curses_uir/  r  NotImplementedErrorr5   r4  r  r)   r  r*   r3   rc   r7   r  r  r  )r  rS   r!  r   r  rk  r  r?   rc  r  r!  menur   r/  r<   rl  r   removedremoved_names                      r   r  r    s^   ::::::::
+--C*++1rIi&& i /000	
'(((G ' 'eT"" 	'99VY//D))J++CJ33;;IrJJQQRUVVINNd22i2223333NN3u::&&&&NN8111111|''w'''0!,.	
 	
 	
 iikk444444,gz7QR   gq)) 	! 	!DAq-q--A--    	6S\\66677==??C"%/#c((Q,,4CC-x8 	 	 	CCC	 {cS^^++lmmC  G'CK*4Wd*C*CUFI&&&W  

@,
@
@
@AAAAAs9   :AF AI,AH54I5IIIIIc                 x  " ddl m}m} ddlm}m} ddlm} |d         }|d         }|                    dd          }	|                    d	d          }
|                    d
d          }|                    dd          "|                    d          pd	                                }|
s"|r t          j                            |d          }
t          ||
          }t          d|            t          d|            "rt          d"            t                       t          d            ||
|d|	pd          }|rd}"r"|v r|                    "          }t          dt          |           d           	 ddlm} "fd|D             dgz   } |||dddddd| d           }|                                }dd!lm}  |             t                       ||t          |          k    rt          d"           dS ||         }n# t*          t,          t.          t0          j        f$ r) t5          |d#          D ]&\  }}|"k    rd$nd}t          d%| d&| |            't          d%t          |          d#z    d'           t                       	 t7          d(t          |          d#z    d)          	                                }|st          d"           Y dS t9          |          d#z
  }|dk     s|t          |          k    rt          d"           Y dS ||         }n.# t:          t<          t>          f$ r t          d*           Y Y dS w xY wY nw xY w"r_t          d+           	 t7          d," d)          	                                p"}n# t<          t>          f$ r t          d*           Y dS w xY wt          d-           	 t7          d.          	                                }n'# t<          t>          f$ r t          d*           Y dS w xY w|st          d/           dS  ||            |            }|                    d          }tA          |tB                    s|rd0|ini }||d<   |r2||d1<   |"                    dd           |"                    d	d           nd2|d1<   ||d<   |r||d	<   |                    dd          }|r||d<   n|"                    dd            ||            |             |rs |            }|                    d3          }tA          |tB                    r=|                    |          }tA          |tB                    r||d4<   tG          |                    d5d          pd          	                                }tG          |                    d	d          pd          	                                } tI          |p|           }!|!r>|r<tG          |                    d	d          pd          	                                s||d	<   |r<tG          |                    d
d          pd          	                                s||d
<   ||d3<    ||           ntK          |||           t          d6|            t          d7| d8| d9           dS ):a  Handle a named custom provider from config.yaml custom_providers list.

    Always probes the endpoint's /models API to let the user pick a model.
    If a model was previously saved, it is pre-selected in the menu.
    Falls back to the saved model if probing fails.
    r   r  r   r  r?   r   r  rn   ru   r  rm   r  z  Provider: z  URL:      z  Current:  zFetching available models...g       @N)r3  r  zFound z model(s):
r   c                 2    g | ]}|k    rd | dnd | S )r   
 (current)r   )ry   r  r   s     r   r   z,_model_flow_named_custom.<locals>.<listcomp>X  sG       IJa;&6&6"Q""""HHH  r   z  Cancelr$  fg_greenr&  r;  TFzSelect model from :r'  r.  rq  r   r9  r   r  z. Cancelrg  r  r  z%Could not fetch models from endpoint.zModel name [z@Could not fetch models from endpoint. Enter model name manually.Model name: zNo model specified. Cancelled.r
   r   r  r  r  r  u   
✅ Model set to: z   Provider: r  r   )&r   ro  rp  r   rS   r!  r  r  r/   r3   r-   r.   r  r   indexr*   r0  r!  r1  r2  r/  r  r3  r5   r4  r  r)   r  rc   r7   r  r  r   r   r  r   r  r  )#r  r  ro  rp  rS   r!  r  r?   r   r  ru   r  r  config_api_keyrE  r  r!  
menu_itemsr4  r   r/  r  r<   r  r  r   r   rm   custom_api_modeproviders_cfgprovider_entryoriginal_api_key_reforiginal_api_keyhad_inline_api_keyr   s#                                     @r   r  r  +  sb    HGGGGGGG::::::::222222 DZ(H  R00H	2..G	2..G##GR00K!%%n55;BBDDL  .w .*.."--:='RRN	


   	
#
#
#$$$ ,*[**+++	GGG	
()))3!T  F
  B 	4;&00 ,,{33K0s6{{000111+	555555   NT  J  <(!"6%2!"24222	 	 	D ))++C888888KMMMGGG{cS[[00l###JJ0':;UV 	 	 	!&!,, - -1)*k)9)9r+1+++6++,,,,0s6{{Q000111GGG=Vq===>>DDFF ,'''FF#hhl77cS[[00,'''FF#C[

 18<   n%%% 
	& 
 5666	>k>>>??EEGGV;JJ!8, 	 	 	.!!!FF	 	PQQQ	~..4466JJ!8, 	 	 	.!!!FF	  	2333F z"""
+--CGGGEeT"" &+3E""G .(j		*d###		)T""""$j$j 	.-E)#''
B77O $+j		*d###K  "Dkmm,,mT** 	!*..|<<N.$// !2</ (+!%%mR88>B( (%'' % $'!%%i44:$ $%'' ! &**>*RBR%S%S"&?&?   2 29b A A GRHHNNPP?
 1?N9- 83~'9'9)R'H'H'NB#O#O#U#U#W#W 807N9-#0K C    	h
CCC	
-
-
-...	
-$
-
-(
-
-
-.....so   BH H BM!!AL0*:L0'L0/M!0&MM!MM! M!6'N  OO!O7 7 PPr  c                     |                      d          }t          |t                    rHt          |                     d          pd                                                                          S dS )Nagentreasoning_effortrn   )r/   r   r   r   r3   r   )r  	agent_cfgs     r   _current_reasoning_effortrL    sc    

7##I)T"" L9==!344:;;AACCIIKKK2r   effortc                 r    |                      d          }t          |t                    si }|| d<   ||d<   d S )NrI  rJ  )r/   r   r   )r  rM  rK  s      r   _set_reasoning_effortrO    sD    

7##Ii&& $	#w$*I !!!r   c           
         t          t                              d | D                                 dfdD             }|                    fdD                        |sdS fdd}d}d	k    rt	          |          }n6|v r|                              }nd
|v r|                    d
          }nd}	 ddlm} fd|D             }|                    d|            |                    d|             |||dddddd          }|	                                }	ddl
m}
  |
             |	dS t                       |	t	          |          k     r||	         S |	t	          |          k    rd	S dS # t          t          t          t           j        f$ r Y nw xY wt          d           t%          |d          D ]#\  }}t          d| d |                      $t	          |          }t          d|dz    d|            t          d|dz    d|            t                       	 	 t'          d|dz    d                                          }|sdS t+          |          }	d|	cxk    r|k    rn n||	dz
           S |	|dz   k    rd	S |	|dz   k    rdS t          d|dz               n2# t,          $ r t          d           Y nt.          t0          f$ r Y dS w xY w)zOPrompt for a reasoning effort. Returns effort, 'none', or None to keep current.c              3      K   | ]X}t          |                                          #t          |                                                                          V  Yd S rw   r  )ry   rM  s     r   r{   z5_prompt_reasoning_effort_selection.<locals>.<genexpr>  sk       
 
,2VARARATAT
KK%%''
 
 
 
 
 
r   )minimallowmediumhighxhighc                     g | ]}|v |	S r   r   )ry   rM  dedupeds     r   r   z6_prompt_reasoning_effort_selection.<locals>.<listcomp>  s#    III&v7H7Hv7H7H7Hr   c              3   $   K   | ]
}|v|V  d S rw   r   )ry   rM  canonical_orders     r   r{   z5_prompt_reasoning_effort_selection.<locals>.<genexpr>  s-      QQf63P3P63P3P3P3PQQr   Nc                     | k    r|  dS | S )Nu     ← currently in user   )rM  current_efforts    r   rQ  z2_prompt_reasoning_effort_selection.<locals>._label  s"    ^##4444r   zDisable reasoningzSkip (keep current)r  rT  r   r   c                 ,    g | ]}d  |           S r#  r   )ry   rM  rQ  s     r   r   z6_prompt_reasoning_effort_selection.<locals>.<listcomp>
  s*    ???V(v((???r   r   r$  r:  r<  TFzSelect reasoning effort:r'  r.  r   r  r    rg  z] (default: keep current): ri  rj  )r   r   fromkeysrN  r*   r?  r0  r!  r  r1  r2  r/  r   r  r3  r5   r4  r  r)   r  r3   rc   r7   r  r  )effortsr\  r  disable_label
skip_labelr  r!  rk  r4  r   r/  r<   rM  r.  rs  rQ  rZ  rX  s    `             @@@r   "_prompt_reasoning_effort_selectionrb    s    
 
6=
 
 
 	
 	
 G
 DOIIIIOIIIGNNQQQQQQQQQQ t    
 (M&J'll	7	"	"mmN33	W		mmH--111111????w???+M++,,,(J(()))|$2!.,	
 	
 	
 iikk444444;4W3<#g,,6t,gz7QR    

$%%%w** * *	6(1((v(())))GA	
'q1u
'
'
'
'(((	
$q1u
$
$

$
$%%%	GGG	JAJJJKKQQSSF tf++CC}}}}1}}}}}sQw''a!e||va!e||t+AE++,,,, 	+ 	+ 	+)*****!8, 	 	 	44	sO   A=F   (F  )F   "F%$F%:*J< &)J< 	J< 	J< &J< <K+K+*K+c                 @   ddl m}m}m}m}m} ddlm}m}m	}	 ddl
m}
m}m}m}m} d}||         } ||          }|                    dd          }|                    dd          }|st#          d	           t#                       t#          d
           t#          d           t#          d           t#          d           t#          d           t#                       t#          d           t#          d           t#          d           t#          d           t#                       	 t%          d                                          }n&# t(          t*          f$ r t#                       Y dS w xY w|dk    rz	 ddlm}  |            }|r* |d|           t#          d           t#                       nt#          d           dS n# t0          $ r}t#          d|            Y d}~dS d}~ww xY w|dk    r	 ddl}|                    d                                          }n&# t(          t*          f$ r t#                       Y dS w xY w|st#          d           dS 	 ddlm}  ||          \  }}|st#          d|            dS n# t6          $ r Y nw xY w |d|           t#          d            t#                       nt#          d           dS  ||          }|                    dd          }|                    dd          }nV|d!v rt#          d"|dd#          d$| d%           n%|d&k    rt#          d'           nt#          d(           t#                       |j        } ||          }|rd) |D             n |
||          } ||||*          p|} |r-d+ |D             }!t#          d,t;          |!           d-           n5t=          j        |g           }!|!rt#          d.           t#          d/           |!r ||!| 0          }"n<	 t%          d1                                          }"n# t(          t*          f$ r d}"Y nw xY w|"r; ||"||*          p|"}" |            }#t?          |#          }$ ||"||*          }%d}&|%r$t#          d2|" d3           tA          |%|$4          }& ||"            |            }'|'                    d5          }(tC          |(tD                    s|(rd6|(ini }(|(|'d5<   ||(d7<   ||(d8<    ||"||*          |(d9<   |&tG          |'|&            |	|'            |             t#          d:|" d;|j$         d%           |%r-|&d<k    rt#          d=           dS |&rt#          d>|&            dS dS dS t#          d?           dS )@zAGitHub Copilot flow using env vars, gh CLI, or OAuth device code.r   )ro   rU  ro  rp  $resolve_api_key_provider_credentials)r`  rS   r!  )r  fetch_github_model_cataloggithub_model_reasoning_effortscopilot_model_api_modenormalize_copilot_model_idr  ru   rn   r   z.No GitHub token configured for GitHub Copilot.z  Supported token types:uL       → OAuth token (gho_*)          via `copilot login` or device code flowuI       → Fine-grained PAT (github_pat_*)  with Copilot Requests permissionu=       → GitHub App token (ghu_*)     via environment variableuA       ✗ Classic PAT (ghp_*)          NOT supported by Copilot APIz
  Options:z1    1. Login with GitHub (OAuth device code flow)z    2. Enter a token manuallyr  z  Choice [1-3]: Nr  )copilot_device_code_loginCOPILOT_GITHUB_TOKENz  Copilot token saved.z  Login cancelled or failed.z  Login failed: r  z   Token (COPILOT_GITHUB_TOKEN):   Cancelled.)validate_copilot_token     ✗ z  Token saved.)GITHUB_TOKENGH_TOKENz  GitHub token: r   u	   ... ✓ (r   zgh auth tokenu*     GitHub token: ✓ (from `gh auth token`)u     GitHub token: ✓c                 d    g | ]-}|                     d           |                     d d          .S r   rn   r/   r  s     r   r   z'_model_flow_copilot.<locals>.<listcomp>  s5    BBB488D>>B$		BBBr   catalogru   c                     g | ]}||S r   r   )ry   model_ids     r   r   z'_model_flow_copilot.<locals>.<listcomp>  s    GGG8hGhGGGr     Found  model(s) from GitHub CopilotL     ⚠ Could not auto-detect models from GitHub Copilot — showing defaults.?    Use "Enter custom model name" if you do not see your model.r  r>  r   z supports reasoning controls.)r\  rm   r
   r   r   r  rw  r  r  z"Reasoning disabled for this model.zReasoning effort set to: r  )%r   ro   rU  ro  rp  rd  r   r`  rS   r!  r  r  re  rf  rg  rh  r/   r   r  r3   r  r  hermes_cli.copilot_authri  r9   ra  rl  r  inference_base_urlr*   r  rL  rb  r   r   rO  r?   ))r  r  ro   rU  ro  rp  rd  r`  rS   r!  r  re  rf  rg  rh  r   r   r   ru   r   rs  ri  tokenrA   ra  new_keyrl  validr  effective_basert  live_modelsnormalized_current_modelr\  r]  initial_cfgr\  reasoning_effortsselected_effortr   rm   s)                                            r   r  r  A  s8                 KJJJJJJJJJ              K,G00==Eii	2&&GYYx$$F K>???()))Z	
 	
 	
 	YZZZMNNNQRRRlABBB-...o	-..4466FF!8, 	 	 	GGGFF	 S==MMMMMM1133 "N#95AAA2333GGGG8999F     .../// s]]!//*LMMSSUU%x0     n%%%JJJJJJ33G<<
s .3..)))F    N17;;;"###GGGG.!!!F44[AA))Ir**8R((111DWRaR[DD6DDDEEEE&&>????'(((/N((11G 	7BBBBBBg~66  	#"	
 	
 	
 	
    	UGG{GGG
GZGGGHHHH%)+r::
 	U^   STTT **&>
 
 
	^,,2244HH!8, 	 	 	HHH	  1&&   
  	 "kmm2;??::
 
 

  	>x>>>???@!.  O 	8$$$kmm  %&& 	!*/7Y&&RE CL'j*j22
 
 
j
 &!#777CFxFFw|FFFGGG 	E&((:;;;;;  EC/CCDDDDD		E 	EE E 	lsa   ,!E E10E1;AG
 

G1G,,G1;+H' 'I
	I
!(J 
JJ!P8 8QQc                    ddl m}m}m}m}m}m}m} ddlm	}	m
}
 ddlm}m} ~ d}||         } ||          }|                    d          p|                    d          pd}|                    d	          p|j        }t!          d
           t!          d           t!          d           t!          d|            t!          d|            t!                       	  ||          }n9# t"          $ r,}t!          d|            t!          d           Y d}~dS d}~ww xY w|                    d	          p|}d}	  |d          }|                    dd          }n# t"          $ r Y nw xY w |	|          } |
|||          p|}|r-d |D             }t!          dt%          |           d           n5t'          j        dg           }|rt!          d           t!          d           |r |||          }n<	 t)          d                                          }n# t,          t.          f$ r d}Y nw xY w|st!          d           dS  |
|||          p|} ||            |            }|                    d          }t1          |t2                    s|rd|ini }||d<   ||d<   ||d	<   d |d!<    ||            |             t!          d"| d#|j         d$           dS )%z4GitHub Copilot ACP flow using the local Copilot CLI.r   )ro   rU  ro  rp  $get_external_process_provider_statusrd  -resolve_external_process_provider_credentials)re  rh  r   r  resolved_commandcommandr  r   z?  GitHub Copilot ACP delegates Hermes turns to `copilot --acp`.zB  Hermes currently starts its own ACP subprocess for each request.zH  Hermes uses your selected model as a hint for the Copilot ACP session.z  Command: z  Backend marker:      ⚠ z[  Set HERMES_COPILOT_ACP_COMMAND or COPILOT_CLI_PATH if Copilot CLI is installed elsewhere.Nrn   ru   rs  c                 d    g | ]-}|                     d           |                     d d          .S rq  rr  r  s     r   r   z+_model_flow_copilot_acp.<locals>.<listcomp>@  s5    OOOTOdhhtR((OOOr   rw  rx  ry  rz  r  r>  r  rm   r
   r   rv  r  rw  r  r   )r   ro   rU  ro  rp  r  rd  r  r  re  rh  r   rS   r!  r/   r|  r   r9   r*   r  r  r3   r  r  r   r   r?   )r  r  ro   rU  ro  rp  r  rd  r  re  rh  rS   r!  r   r   r   r  r  r   rA   catalog_api_keycatalog_credsrt  r  r\  r]  r   rm   s                               r   r  r     s                            ;:::::::K,G11+>>F

%&&L&**Y*?*?L9  ZZ
++Iw/IN	
KLLL	
NOOO	
TUUU	
*(
*
*+++	
/~
/
/000	GGG==kJJ   nsnni	
 	
 	
 	 YYz**<nNO<<YGG'++Ir::    )(99G""#	
 	
 	
 	
    	UOOWOOO
GZGGGHHHH%))R88
 	U^   STTT 	**2
 
 

	^,,2244HH!8, 	 	 	HHH	  l 	#"#	
 	
 	
 	
   x   
+--CGGGEeT"" &+3E""G#E*&E**E*K	
B8
B
B7<
B
B
BCCCCCs<   !C- -
D#7!DD# !E" "
E/.E/!H$ $H:9H:c                    ddl m}m}m}m}m} ddlm}m}m	}	m
}
 d}||         }|j        r|j        d         nd}|j        pd}d}|j        D ]&} ||          pt          j        |d          }|r n'|st          d|j         d           |r	 ddl}|                    | d	                                          }n&# t&          t(          f$ r t                       Y dS w xY w|st          d
           dS  |||           |}t          d           t                       n1t          d|j         d|dd          d           t                       |                    d          }|r|}t          d|            n|j        }t          d|            |r ||          r ||d           t                       |rg d}nt/          j        dg           }|r |||          }n<	 t3          d                                          }n# t&          t(          f$ r d}Y nw xY w|r ||            |	            }|                    d          }t5          |t6                    s|rd|ini }||d<   ||d<   ||d<   |                    dd            |
|            |             |rdnd}t          d| d| d            dS t          d!           dS )"u  Kimi / Moonshot model selection with automatic endpoint routing.

    - sk-kimi-* keys   → api.kimi.com/coding/v1  (Kimi Coding Plan)
    - Other keys        → api.moonshot.ai/v1      (legacy Moonshot)

    No manual base URL prompt — endpoint is determined by key prefix.
    r   )ro   KIMI_CODE_BASE_URLrU  ro  rp  r	  r  rn   No  API key configured.N (or Enter to cancel): rq  rr  r   
 API key: r      ... ✓zsk-kimi-u$     Detected Kimi Coding Plan key → u     Using Moonshot endpoint → )z	kimi-k2.6z	kimi-k2.5zkimi-for-codingzkimi-k2-thinkingzkimi-k2-thinking-turbomoonshotr  zEnter model name: rm   r
   r   r   r  zKimi CodingMoonshotrw  r  r   r  )r   ro   r  rU  ro  rp  r   r_  r`  rS   r!  r   base_url_env_varr-   rx   r   r?   ra  r3   r  r  r+   r|  r  r/   r  r   r   r  )r  r  ro   r  rU  ro  rp  r_  r`  rS   r!  r   r   r  base_url_envexisting_keyevra  r~  is_coding_planr  r\  r]  r   rm   endpoint_labels                             r   r  r  q  sA                             K,G-4-EMg&q))2G+1rL L&  $}R((=BIb",=,= 	E	  6GL666777 	!//W*M*M*MNNTTVV%x0     l###N7G,,,"L"###GGGD7<DD<+;DDDEEE ",,Z88N A+E^EEFFFF 3?~??@@@ )l33 )|R(((	GGG  :
 
 


 &)*b99
 **:]SSS	12288::HH!8, 	 	 	HHH	  8$$$ kmm  %&& 	!*/7Y&&RE CL'j*j		*d###C*8HjHxHH~HHHIIIIIls$   .C   C#"C#/!H H'&H'c                 b    | pd                                                                 }d|v rdS dS )z>Infer the current StepFun region from the configured endpoint.rn   zapi.stepfun.comchinainternational)r3   r   )r   r  s     r   _infer_stepfun_regionr    s8    .b''))//11JJ&&w?r   r  c                 &    ddl m}m} | dk    r|n|S )Nr   )STEPFUN_STEP_PLAN_CN_BASE_URLSTEPFUN_STEP_PLAN_INTL_BASE_URLr  )r   r  r  )r  r  r  s      r   _stepfun_base_url_for_regionr    sG            W 	&%,r   c                    ddl m}m}m}m} ddlm}m}m}m	}	 ddl
m}
 d}||         }|j        r|j        d         nd}|j        pd}d}|j        D ]&} ||          pt          j        |d          }|r n'|st!          d|j         d           |r	 dd	l}|                    | d
                                          }n&# t(          t*          f$ r t!                       Y d	S w xY w|st!          d           d	S  |||           |}t!          d           t!                       n1t!          d|j         d|d	d          d           t!                       d}|r  ||          pt          j        |d          }|s`|                     d          }t/          |t0                    r6t3          |                    d          pd                                          }t5          |p|j                  }ddt9          d           dfddt9          d           dfg}g }|D ]>\  }}||k    r|                    d|| df           '|                    ||f           ?|                    d           t?          d |D                       }|||         d         dk    rt!          d           d	S ||         d         }t9          |          }|r |||            |
||          }|r+|}t!          dtA          |           d|j         d           n/tC          j        |g           }|rt!          d |j         d!           |r |||"          }n<	 tE          d#                                          }n# t(          t*          f$ r d	}Y nw xY w|r ||            |            } |                     d          }!t/          |!t0                    s|!rd$|!ini }!|!| d<   ||!d%<   ||!d<   |!#                    d&d	            |	|             |             t1          |!          | d<   t!          d'| d(|j         d           d	S t!          d           d	S ))z6StepFun Step Plan flow with region-specific endpoints.r   )ro   rU  ro  rp  r	  r  r  rn   r  r  Nr  rq  rr  r   r  r   r  rm   r   r  zInternational (r   r  zChina (r  )r  r  c                     g | ]\  }}|S r   r   r  s      r   r   z'_model_flow_stepfun.<locals>.<listcomp>4  s    )P)P)PHAu%)P)P)Pr   r  r  rw   model(s) from  APIz$  Could not auto-detect models from u,    API — showing Step Plan fallback catalog.r  r>  r
   r   r  rw  r  )$r   ro   rU  ro  rp  r   r_  r`  rS   r!  r  r  r   r  r-   rx   r   r?   ra  r3   r  r  r/   r   r   r   r  r|  r  r  r  r  r*   r  r  r  )"r  r  ro   rU  ro  rp  r_  r`  rS   r!  r  r   r   r  r  r  r  ra  r~  current_baser   current_regionregion_choicesordered_regions
region_keyr  
region_idxselected_regionr  r  r\  r]  r   rm   s"                                     r   r  r    s               ZYYYYYYYYYYY222222K,G-4-EMg&q))2G+1rLL&  $}R((=BIb",=,= 	E	  6GL666777 	!//W*M*M*MNNTTVV%x0     l###N7G,,,"L"###GGGD7<DD<+;DDDEEEL R$}\22Qbib6Q6Q HJJw''	i&& 	Hy}}Z88>B??EEGGL*<+U7;UVVN 
\,H,Y,Y\\\]	D8AADDDEN O+ 8 8
E''""1ze3S3S3S&TUUUU""J#67777/000()P)P)P)P)PQQJ_Z8;xGGl%j1!4O1/BBN 5|^444""<@@K 	 
KZKKKKKLLLL%)+r::
 	6w| 6 6 6  
  **:]SSS	^,,2244HH!8, 	 	 	HHH	  8$$$kmm  %&& 	!*/7Y&&RE CL'j*j		*d###Cu++wFxFFw|FFFGGGGGls$   .C C'&C'!M< <NNc                    ddl m}m}m} ddlm}m}m}m}	 ddl	m
}
 d| d} |d          pd}|rt          d	|d
d          d           nt          d|            t                       	 dd
l}|                    d	                                          }n&# t          t          f$ r t                       Y d
S w xY w|st          d           d
S  |	d|           |}t          d           t                        |
j        dg           }t          dt#          |           d           |r |||          }n<	 t%          d                                          }n# t          t          f$ r d
}Y nw xY w|r ||            |            }|                    d          }t'          |t(                    s|rd|ini }||d<   d|d<   ||d<   |                    dd
           |                    di           }t'          |t(                    si }||d<   ||d<    |	d|            |	d|            ||            |             t          d| d| d            t          d|            d
S t          d!           d
S )"u   Bedrock API Key mode — uses the OpenAI-compatible bedrock-mantle endpoint.

    For developers who don't have an AWS account but received a Bedrock API Key
    from their AWS admin. Works like any OpenAI-compatible endpoint.
    r   rn  )rS   r!  r_  r`  r  zhttps://bedrock-mantle.z.api.aws/v1AWS_BEARER_TOKEN_BEDROCKrn   z  Bedrock API Key: N   r  z  Endpoint: rk       ✓ API key saved.r  
  Showing z curated modelsr    Model ID: rm   r
   r  r   r   r  r  rp   rr     Default model set to: z (via Bedrock API Key, r     No change.)r   rU  ro  rp  r   rS   r!  r_  r`  r  r  r   ra  r3   r  r  r/   r*   r  r   r   r  )r  r  r  rU  ro  rp  rS   r!  r_  r`  r  mantle_base_urlr  ra  ru   r\  r]  r   rm   bedrock_cfgs                       r   _model_flow_bedrock_api_keyr  f  s            
            322222CCCCO !=!;<<BL &>L"$5>>>????._..///	NNNoo&;<<BBDDGG!8, 	 	 	GGGFF	  	.!!!F17;;;$%%%	GGG &!%i44J	
7s:
7
7
7888 **:]SSS	^,,2244HH!8, 	 	 	HHH	  8$$$ kmm  %&& 	!*/7Y&&RE CL$j+j		*d### ggi,,+t,, 	K &H$I 	'666(/:::CSSS&SSSTTT._../////ns$   /+B B>=B>!E# #E98E9c                 
    ddl m}m}m} ddlm}m} ddlm} 	 ddl	m
}m}	m}
m} n=# t          $ r0 t          d           t          d           t                       Y dS w xY w |            s,t          d	           t          d
           t                        |	            }|rt          d| d           nt          d           t                        |
            }	 t!          d| d                                          }n&# t$          t&          f$ r t                       Y dS w xY w|p|}t          d           t                       t          d           t          d           t          d           t          d           t          d           t                       	 t!          d                                          }n&# t$          t&          f$ r t                       Y dS w xY w|dk    rt)          | ||           dS t          d| d            ||          }|rid}d}g }|D ]W}|d          t+           fd|D                       r&t+           fd|D                       rB|                    |           Xt/                      }|D ]^}|d                               d          r?d  d!d         v r                     d d"          d"         n }|                    |           _g }|D ]9}|d                               d          s |v r$|                    |           :g d#fd$}|                    |%           d& |D             }t          d't9          |           d(t9          |           d)           nE |j        d*g           }|r!t          d+t9          |           d,           nt          d-           dS |r |||.          }n<	 t!          d/                                          }n# t$          t&          f$ r d}Y nw xY w|r ||            |            }|                    d0          }t=          |t>                    s|rd1|ini }||d0<   d*|d2<   d3| d4|d5<   |                     d6d           |                    d*i           }t=          |t>                    si }||d7<   ||d*<    ||            |             t          d8| d9| d:           dS t          d;           dS )<u$  AWS Bedrock provider: verify credentials, pick region, discover models.

    Uses the native Converse API via boto3 — not the OpenAI-compatible endpoint.
    Auth is handled by the AWS SDK default credential chain (env vars, profile,
    instance role), so no API key prompt is needed.
    r   rn  r   r  )has_aws_credentialsresolve_aws_auth_env_varresolve_bedrock_regiondiscover_bedrock_modelsu.     ✗ boto3 is not installed. Install it with:z    pip install boto3Nu<     ⚠ No AWS credentials detected via environment variables.zE  Bedrock will use boto3's default credential chain (IMDS, SSO, etc.)z  AWS credentials: u    ✓z<  AWS credentials: boto3 default chain (instance role / SSO)z  AWS Region [r    Choose authentication method:z)    1. IAM credential chain (recommended)zB       Works with EC2 instance roles, SSO, env vars, aws configurez    2. Bedrock API Keyu<          Enter your Bedrock API Key directly — also supportsz5       team scenarios where an admin distributes keysz  Choice [1]: r  z  Discovering models in r  )z
stability.zcohere.embedztwelvelabs.zus.stability.zus.cohere.embedzus.twelvelabs.zglobal.cohere.embedzglobal.twelvelabs.)	safeguardvoxtralzpalmyra-visionr   c              3   B   K   | ]}                     |          V  d S rw   r  )ry   r  r  s     r   r{   z&_model_flow_bedrock.<locals>.<genexpr>  s/      @@3>>!$$@@@@@@r   c              3   D   K   | ]}|                                 v V  d S rw   r   )ry   r   r  s     r   r{   z&_model_flow_bedrock.<locals>.<genexpr>  s0      AA1		#AAAAAAr   )zus.global.rX  r   r   )	zus.anthropic.claude-sonnet-4-6zus.anthropic.claude-opus-4-6zus.anthropic.claude-haiku-4-5zus.amazon.nova-prozus.amazon.nova-litezus.amazon.nova-microzdeepseek.v3zus.meta.llama4-maverickzus.meta.llama4-scoutc                     | d         }t                    D ]!\  }}|                    |          rd||fc S "|                    d          rdd|fS dd|fS )Nr   r   r  r   r    )r)   r+   )r  r  r<   rec_RECOMMENDEDs       r   	_sort_keyz&_model_flow_bedrock.<locals>._sort_key8  s~    D'C#L11 ' '3>>#&& 'q#;&&&'~~i(( #1c{"q#;r   )r   c                     g | ]
}|d          S )r   r   ry   r  s     r   r   z'_model_flow_bedrock.<locals>.<listcomp>B  s    ///!ag///r   rw  z text model(s) (filtered from z total)r  z  Using z, curated models (live discovery unavailable)zJ  No models found. Check IAM permissions for bedrock:ListFoundationModels.r  r  rm   r
   r   zhttps://bedrock-runtime.z.amazonaws.comr   r  r  r  z (via AWS Bedrock, r   r  )!r   rU  ro  rp  r   rS   r!  r  r  agent.bedrock_adapterr  r  r  r  r  r   r  r3   r  r  r  r   r  setr+   r,   addsortr*   r/   r   r   r  )!r  r  rU  ro  rp  rS   r!  r  r  r  r  r  auth_varr  region_inputr  auth_choicer  _EXCLUDE_PREFIXES_EXCLUDE_SUBSTRINGSr  r  profile_base_idsbaserX  r  r\  r]  r   rm   r  r  r  s!                                  @@r   r  r    s            
 ;:::::::222222	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
    >???%&&&	    LMMMUVVV''))H N2H2223333LMMM	GGG ,+--NAnAAABBHHJJx(    +^F 

+,,,	GGG	
5666	
NOOO	
"###	
HIII	
ABBB	GGG,--3355x(    c#FFMBBB 

0V
0
0
0111))&11K I	
 I 	 	AD'C@@@@.?@@@@@ AAAA-@AAAAA OOA 55 	+ 	+AD'C~~011 +/2c!""g~~syya((++3 $$T*** 	 	AD'C>>"455 #AQ:Q:QNN1

 

 

	 	 	 	 	 	###//w///
_s:__c+FVFV___	
 	
 	
 	
 *%))R88
 	X3z??XXX    \   F  **:]SSS	^,,2244HH!8, 	 	 	HHH	  8$$$kmm  %&& 	!*/7Y&&RE CL%jMvMMMj		*d###ggi,,+t,, 	K &H$ICOOOfOOOPPPPPnsE   ) 6A#"A#$%D
 
D-,D-+!G G0/G0,!P P$#P$c                 D  - ddl m}m}m}m}m} ddlm}m}	m	}
m
} ddlm}m}m- |         }|j        r|j        d         nd}|j        pd}d}|j        D ]&} ||          pt#          j        |d          }|r n'|st'          d|j         d           |r	 ddl}d	k    r	| d
|d}n| d}|                    |                                          }n&# t.          t0          f$ r t'                       Y dS w xY w|sd	k    r|}nt'          d           dS  |	||           |}t'          d           t'                       n1t'          d|j         d|dd          d           t'                       dk    rS|rP	 ddlm} n# t6          $ r d}Y nw xY w|3t'          d           |r ||          ndpt#          j        |pdd          p|j        } |||          }|dk    rt'                       t'          d           t'          d           t'          d           t'          d           t'                       t'          d           t'          d           t'                       t'          d           t'                       t'          d           dS |dk    rt'          d            nt'          d!           t'                       d}|r  ||          pt#          j        |d          }|s	  |
                                d"          pi }t=          |                    d#          pd                                                                          k    r6t=          |                    d$          pd                                          }n# t6          $ r Y nw xY w|p|j        }	 tA          d%| d&                                          }n'# t.          t0          f$ r t'                       d}Y nw xY w|r5|r3|!                    d'          st'          d(           n |	||           |}d	k    rdd)l m"} dd*lm#} |p|r ||          nd}	  |||+          } n5# |$ r-}!t'          d,|!            t'          d-           g } Y d}!~!nd}!~!ww xY w| r t'          d.tI          |            d/           nd0k    rIdd1lm%}" |p|r ||          nd} |"||d23          } | r t'          d.tI          |            d4           ntM          j        g           }#g }$	 dd5l'm(}%  |%          }$n# t6          $ r Y nw xY w|$r|#rud6 |$D             }&tS          |$          }'|#D ]T}(|(                                |&vr<|'*                    |(           |&+                    |(                                           U|'} n|$} t'          d.tI          |            d7           n|#r6tI          |#          dk    r#|#} t'          d8tI          |            d9           n|p|r ||          nd} |||          })|)rKtI          |)          tI          |#          k    r+|)} t'          d.tI          |            d:|j         d;           n$|#} | r t'          d8tI          |            d9           d<v rL-fd=| D             }  -|          }tS          tX          -                    d> | D                                 } | r || |?          }*n<	 tA          d@                                          }*n# t.          t0          f$ r d}*Y nw xY w|*rd<v r -|*          }* ||*            |
            }+|+                    d"          },t]          |,tX                    s|,rdA|,ini },|,|+d"<   |,d#<   ||,d$<   d<v r ||*          |,dB<   n|,/                    dBd            ||+            |             t'          dC|* dD|j         dE           dS t'          dF           dS )GzCGeneric flow for API-key providers (z.ai, MiniMax, OpenCode, etc.).r   )LMSTUDIO_NOAUTH_PLACEHOLDERro   rU  ro  rp  r	  )r  opencode_model_api_modenormalize_opencode_model_idrn   r  r  Nr  z (Enter for no-auth default rh  r  rq  rr  r   r  r   r  r  )probe_gemini_tierz  Checking Gemini API tier...freeuW   ❌ This Google API key is on the free tier (<= 250 requests/day for gemini-2.5-flash).z[   Hermes typically makes 3-10 API calls per user turn (tool iterations + auxiliary tasks),zO   so the free tier is exhausted after a handful of messages and cannot sustainz   an agent session.zX   To use Gemini with Hermes, enable billing on your Google Cloud project and regeneratezK   the key in a billing-enabled project: https://aistudio.google.com/apikeyzY   Alternatives with workable free usage: DeepSeek, OpenRouter (free models), Groq, Nous.z*Not saving Gemini as the default provider.paidu     Tier check: paid ✓z3  Tier check: could not verify (proceeding anyway).rm   r   r   r`  r  r  uM     Invalid URL — must start with http:// or https://. Keeping current value.)r  )fetch_lmstudio_models)ru   r   z"  LM Studio rejected the request: zC  Set LM_API_KEY (or update it) to match the server's bearer token.rw  z model(s) from LM Studior  )fetch_ollama_cloud_modelsT)ru   r   ru  z model(s) from Ollama Cloud)list_agentic_modelsc                 6    h | ]}|                                 S r   r  r  s     r   	<setcomp>z/_model_flow_api_key_provider.<locals>.<setcomp>=  s     777a		777r   z" model(s) from models.dev registryr  r  r  r  >   r  r  c                 (    g | ]} |          S r   r   )ry   r  r  r   s     r   r   z0_model_flow_api_key_provider.<locals>.<listcomp>^  s4     
 
 
>A''S99
 
 
r   c              3      K   | ]}||V  	d S rw   r   )ry   r  s     r   r{   z/_model_flow_api_key_provider.<locals>.<genexpr>b  s'      'I'IS'I'I'I'I'I'I'Ir   r  r>  r
   r  rw  r  r   r  )0r   r  ro   rU  ro  rp  r   r_  r`  rS   r!  r  r  r  r  r   r  r-   rx   r   r?   ra  r3   r  r  agent.gemini_native_adapterr  r9   r|  r/   r   r   r  r+   r  r  r*   r  r  agent.models_devr  r   r  r  r   r^  r   r  ).r  r   r  r  ro   rU  ro  rp  r_  r`  rS   r!  r  r  r   r  r  r  r  ra  promptr~  r  
probe_basetierr  _mr  overrider  r  api_key_for_prober\  rA   r  curatedmdev_modelsr  seenmergedr  r  r]  r   rm   r  s.    `                                           @r   r  r  u  s                                      ,G-4-EMg&q))2G+1rL L&  $}R((=BIb",=,= 	E	  6GL666777 	
*,, 'ggE`gggFF '@@@F!//&117799%x0     *,,9GG,'''FN7G,,,"L"###GGGD7<DD<+;DDDEEE h<	%EEEEEEE 	% 	% 	% $	%(12220<D|,,," .9\/R44.- 
 %$\:>>Dv~~B   ;   2   ,---:   9   <   BCCCv~~.////
 KLLLGGG L R$}\22Qbib6Q6Q 	""7++1rB266*%%+,,2244::<<KK"266*#5#5#;<<BBDD 	 	 	D	!?W%?N9n999::@@BBx(     &L &""#:;; 	&_    N<222%N j  ------;;;;;;(Ww-V]]7-C-C-CTV	..7HSabbbJJ 	 	 	<s<<===WXXXJJJJJJ	  	HFS__FFFGGG		&	&??????(Ww-V]]7-C-C-CTV
 /.%#
 
 


  	KIS__IIIJJJ"&{B77 	<<<<<<--k::KK 	 	 	D	  !	  	)77;777k**  , ,Awwyy,,a(((+++#

(
PS__PPPQQQQ 	W** JkS__kkk    !- !*19g&&&r  +*+<nMMK s;//3w<<??(
SZSSSSSTTTT$
 sS__sss  
 555
 
 
 
 
EO
 
 

 43KOO$--'I'Iz'I'I'IIIJJ
 **:]SSS	^,,2244HH!8, 	 	 	HHH	  99922;IIH8$$$ kmm  %&& 	!*/7Y&&RE CL'j*j999 7 7X N NE*IIj$'''CFxFFw|FFFGGGGGls   ?C C>=C>F FF;B!N 
N*)N*7%O !P PQ- -R2#RR-T? ?
UU!\4 4]
	]
c                    	 ddl m}mm ddlm}m	 dt          f 	fd}	 t                       t          d           t          d           t                        |            }|r* |            rdS  || 	           t          d
           dS t                       t          d           t                       	 ddl	}|	                    d          
                                }n&# t          t          f$ r t                       Y dS w xY w|r || 	           t          d           dS t          d           dS # t          $ r7 t                       t          d           t                       t          d           t                       t          d           t          d           t          d           t          d           t                       t          d           t                       	 ddl	}|	                    d          
                                }n'# t          t          f$ r t                       Y Y dS w xY w|r || 	           t          d           Y dS t          d           Y dS w xY w)zNRun the Claude OAuth setup-token flow. Returns True if credentials were saved.r   )run_oauth_setup_tokenr   r   )save_anthropic_oauth_token%use_anthropic_claude_code_credentialsr   c                     	              } n# t           $ r d } Y nw xY w| rk |           s"t          |                     d                    r>            t          d           ddlm} t          d |             d           dS d	S )
Nr   save_fnu%     ✓ Claude Code credentials linked.r   display_hermes_homez]    Hermes will use Claude's credential store directly instead of copying a setup-token into z/.env.TF)r9   r  r/   r   r0   r  )r   _dhh_fnr   r   r`  r  s     r   ._activate_claude_code_credentials_if_availablezQ_run_anthropic_oauth_flow.<locals>._activate_claude_code_credentials_if_available  s    	0022EE 	 	 	EEE	 
	&&u--
	15eii6O6O1P1P
	 21.IIII9:::GGGGGG Bpwpwpypy  B  B  B   4us   
 u<     Running 'claude setup-token' — follow the prompts below.z9  A browser window will open for you to authorize access.Tr  u     ✓ OAuth credentials saved.z8  If the setup-token was displayed above, paste it here:Nz*  Paste setup-token (or Enter to cancel): Fu     ✓ Setup-token saved.u)     ⚠ Could not detect saved credentials.z/  The 'claude' CLI is required for OAuth login.z  To install and authenticate:zE    1. Install Claude Code:  npm install -g @anthropic-ai/claude-codez/    2. Run:                  claude setup-tokenz.    3. Follow the browser prompts to authorizez)    4. Re-run:               hermes modelz8  Or paste an existing setup-token now (sk-ant-oat-...):z$  Setup-token (or Enter to cancel): u2     Cancelled — install Claude Code and try again.)r   r  r   r   r   r  r  r  r   ra  r3   r  r  r8   )
r`  r  r  r  r}  ra  manual_tokenr   r   r  s
   `      @@@r   _run_anthropic_oauth_flowr    sK            
       
D         $<LMMMIJJJ%%'' 	==?? t&&unEEEE23334 	HIII	NNN"??< egg L "8, 	 	 	GGG55	  	&&|^LLLL,---49:::u   ?@@@.///UVVV?@@@>???9:::HIII	NNNOO$JKKQQSSEE!8, 	 	 	GGG555	  	&&unEEEE,---44BCCCuu5ss   AE :E +E +C0 /E 0DE D!E 6E B:J	+H.-J	.IJ	I!J	6J	J	c                    ddl m}m}m} ddlm}m}m}m} ddl	m
}	 ddl m}
  |
            }d}	 ddlm}m}m}  |            }|r ||          rd}n# t           $ r Y nw xY wd}|r ||          r|sd}t#          |          r| p|}| }|r|rt%          d	|d
d          d           n|rt%          d           t%                       t%          d           t%          d           t%          d           t%                       	 t'          d                                          }n# t*          t,          f$ r d}Y nw xY w|dk    rd}n|dk    rd
S |rt%                       t%          d           t%                       t%          d           t%          d           t%          d           t%                       	 t'          d                                          }n&# t*          t,          f$ r t%                       Y d
S w xY w|dk    rt/          |          sd
S n|dk    rt%                       t%          d           t%                       	 dd
l}|                    d                                          }n&# t*          t,          f$ r t%                       Y d
S w xY w|st%          d           d
S  |||           t%          d           nt%          d           d
S t%                        |	j        dg           }|r |||          }n<	 t'          d                                           }n# t*          t,          f$ r d
}Y nw xY w|r ||            |            }|                    d!          }t5          |t6                    s|rd"|ini }||d!<   d|d#<   |                    d$d
            ||            |             t%          d%| d&           d
S t%          d'           d
S )(uR   Flow for Anthropic provider — OAuth subscription, API key, or Claude Code creds.r   rn  )r`  rS   r!  save_anthropic_api_keyr  )get_anthropic_keyF)r   r   _is_oauth_tokenTz  Anthropic credentials: Nr  r  u.     Claude Code credentials: ✓ (auto-detected)r  r  r  r  r  r  r  r  z0    1. Claude Pro/Max subscription (OAuth login)z(    2. Anthropic API key (pay-per-token)z>  Get an API key at: https://platform.claude.com/settings/keysz  API key (sk-ant-...): rk  r  r  r  r  r  z-Model name (e.g., claude-sonnet-4-20250514): rm   r
   r   r   rw  z (via Anthropic)r  )r   rU  ro  rp  r   r`  rS   r!  r  r  r  r  r   r   r   r  r9   r  r   r  r3   r  r  r  ra  r/   r   r   r  )r  r  rU  ro  rp  r`  rS   r!  r  r  r  r  cc_availabler   r   r  cc_credsexisting_is_stale_oauth	has_creds
needs_authrs  ra  ru   r\  r]  r   rm   s                              r   r  r    s            
            322222 211111$$&&LL	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 0/11 	 228<< 	 L    $ '55 'l '"&l##C,C(CTIJ  	DHl3B3.?HHHIIII 	DBCCC/0007888o	/006688FF!8, 	 	 	FFF	 S==JJs]]F  &/000@AAA8999o	/006688FF!8, 	 	 	GGGFF	 S==,^<<  s]]GGGRSSSGGG!//*DEEKKMM%x0     n%%%""7NCCCC()))) .!!!F	GGG &!%k266J **:]SSS	LMMSSUUHH!8, 	 	 	HHH	  8$$$ kmm  %&& 	!*/7Y&&RE CL'j		*d###CAxAAABBBBBlsY   #A 
A! A!	!D+ +E E?!G! !HH+I= =J J !L6 6MMc                 (    ddl m}  ||            dS )z(Authenticate Hermes CLI with a provider.r   )login_commandN)r   r
  )rL  r
  s     r   	cmd_loginr  m  s*    ------M$r   c                 (    ddl m}  ||            dS )zClear provider authentication.r   )logout_commandN)r   r  )rL  r  s     r   
cmd_logoutr  t  s*    ......N4r   c                 (    ddl m}  ||            dS )zManage pooled credentials.r   )auth_commandN)hermes_cli.auth_commandsr  )rL  r  s     r   cmd_authr  {  s*    555555Lr   c                 (    ddl m}  ||            dS )zShow status of all components.r   )show_statusN)hermes_cli.statusr  )rL  r  s     r   
cmd_statusr    s*    ------Kr   c                 (    ddl m}  ||            dS )zCron job management.r   )cron_commandN)hermes_cli.cronr  )rL  r  s     r   cmd_cronr    s*    ,,,,,,Lr   c                 (    ddl m}  ||            dS )z Webhook subscription management.r   )webhook_commandN)hermes_cli.webhookr  )rL  r  s     r   cmd_webhookr    r[  r   c                     t          | dd          }|dv rt          dt          j                   dS |dk    rdd	lm}  ||           S t          d
| t          j                   dS )u   Slack integration helpers.

    Dispatches ``hermes slack <subcommand>``. Currently supports:
      manifest — print or write a Slack app manifest with every gateway
                 command registered as a first-class slash.
    slack_commandN)Nrn   zusage: hermes slack <subcommand>

subcommands:
  manifest   Generate a Slack app manifest with every gateway
             command registered as a native slash

Run `hermes slack manifest -h` for details.r   r   manifestr   )slack_manifest_commandzUnknown slack subcommand: )rG  r   r   r   hermes_cli.slack_clir"  )rL  r  r"  s      r   	cmd_slackr$    s     $
.
.C
j: 		
 		
 		
 		
 q
j??????%%d+++	
,s
,
,3:>>>>1r   c                 $    ddl m}  ||           S )z"Multi-profile collaboration board.r   )kanban_command)hermes_cli.kanbanr&  )rL  r&  s     r   
cmd_kanbanr(    s$    000000>$r   c                 (    ddl m}  ||            dS )z%Shell-hook inspection and management.r   )hooks_commandN)hermes_cli.hooksr*  )rL  r*  s     r   	cmd_hooksr,    s*    ......M$r   c                 (    ddl m}  ||            dS )z%Check configuration and dependencies.r   )
run_doctorN)hermes_cli.doctorr.  )rL  r.  s     r   
cmd_doctorr0    *    ,,,,,,Jtr   c                 (    ddl m}  ||            dS )z)Dump setup summary for support/debugging.r   )run_dumpN)hermes_cli.dumpr3  )rL  r3  s     r   cmd_dumpr5    s%    ((((((HTNNNNNr   c                 (    ddl m}  ||            dS )z!Debug tools (share report, etc.).r   )	run_debugN)hermes_cli.debugr7  )rL  r7  s     r   	cmd_debugr9    s%    ******IdOOOOOr   c                 (    ddl m}  ||            dS )zConfiguration management.r   )config_commandN)r   r;  )rL  r;  s     r   
cmd_configr<    s*    000000N4r   c                 p    t          | dd          rddlm}  ||            dS ddlm}  ||            dS )z,Back up Hermes home directory to a zip file.quickFr   )run_quick_backup)
run_backupN)rG  hermes_cli.backupr?  r@  )rL  r?  r@  s      r   
cmd_backuprB    sg    tWe$$ 666666000000
4r   c                 (    ddl m}  ||            dS )z(Restore a Hermes backup from a zip file.r   )
run_importN)rA  rD  )rL  rD  s     r   
cmd_importrE    r1  r   c           	      <   t          dt           dt           d           t          dt                      t          dt          j                                        d                     	 ddl}t          d|j                    n# t          $ r t          d	           Y nw xY w	 dd
l	m
} ddlm}  |            }|r3|dk    r-|dk    rdnd}t          d| d| d |             d           dS |dk    rt          d           dS dS # t          $ r Y dS w xY w)zShow version.zHermes Agent vr  r   z	Project: zPython: r   NzOpenAI SDK: zOpenAI SDK: Not installed)check_for_updatesrecommended_update_commandr   commitcommitszUpdate available: r   u    behind — run ''z
Up to date)r   rY   rZ   r  r   versionr,   openair  rJ  rG  r   rI  r9   )rL  rN  rG  rI  behindcommits_words         r   cmd_versionrQ    s   	
=;
=
=*:
=
=
=>>>	
$l
$
$%%% 

-S[&&((+
-
-...+1V/112222 + + +)*****+777777@@@@@@""$$ 	 fqjj'-{{88	L8V 8 8l 8 822448 8 8     q[[, [   s+   -B	 	B%$B%)A	D 4D 
DDc                 F    t          d           ddlm}  ||            dS )zUninstall Hermes Agent.	uninstallr   )run_uninstallN)r   hermes_cli.uninstallrT  )rL  rT  s     r   cmd_uninstallrV    s8    222222M$r   c                 &   d}t          j        |           D ]y\  }}}d |D             |dd<   t           j                            |          dk    r?	 t	          j        |           |dz  }n# t          $ r Y nw xY w|                                 z|S )a~  Remove all __pycache__ directories under *root*.

    Stale .pyc files can cause ImportError after code updates when Python
    loads a cached bytecode file that references names that no longer exist
    (or don't yet exist) in the updated source.  Clearing them forces Python
    to recompile from the .py source on next import.

    Returns the number of directories removed.
    r   c                     g | ]}|d v|	S ))venvz.venvrz  .gitz
.worktreesr   )ry   r  s     r   r   z)_clear_bytecode_cache.<locals>.<listcomp>)  s.     
 
 
OOO OOOr   N__pycache__r   )r-   r  rc  basenamerJ  rq  r5   r   )rx  r5  r  r  r   s        r   _clear_bytecode_cacher]    s     G "  1
 

 
 

 7G$$55g&&&1   NNNs   A,,
A98A9     r@prompt_textr
   r3  c                    ddl }ddl}ddlm}  |            }|dz  }|dz  }|                    d           | |t          |                                          d}	|                    d	          }
|
                    |	                    |	                     |

                    |           t          j                    |z   }t          j                    |k     r|                                rp	 |                                                                }|                    d           |                    d           |r|n|S # t           t"          f$ r Y nw xY wt          j        d
           t          j                    |k     |                    d           |                    d           t'          dt)          |           d|d           |S )aw  File-based IPC prompt for gateway mode.

    Writes a prompt marker file so the gateway can forward the question to the
    user, then polls for a response file.  Falls back to *default* on timeout.

    Used by ``hermes update --gateway`` so interactive prompts (stash restore,
    config migration) are forwarded to the messenger instead of being silently
    skipped.
    r   NrD   z.update_prompt.jsonz.update_responseT)
missing_ok)r  r
   r   z.tmp      ?z  (no response after zs, using default: r   )r   uuidr0   rE   r  r   uuid4with_suffix
write_textdumpsrn  ra   	monotonicr1   r2   r3   r5   r7   sleepr   rc   )r_  r
   r3  _json_uuidrE   r  prompt_pathresponse_pathpayloadtmpdeadlineanswers                r   _gateway_promptrr  8  s    000000?D..K--M D))) %++--   G
 
!
!&
)
)CNN5;;w''(((KK   7*H
/

h
&
&!! 	&002288::$$$555""d"333!'4vvW4Z(   C /

h
&
& $'''D)))	
N#g,,
N
N'
N
N
NOOONs   2AE
 
EEweb_dirc                 ~  
 | j         dz  dz  }|dz  dz  }|                                s|dz  }|                                sdS |                                j        }t	          ddh          
t          j        | d	          D ]x\  }}}
fd
|D             |dd<   |D ]\}|                    d          rEt
          j        	                    t
          j        
                    ||                    |k    r  dS ]ydD ];}| |z  }	|	                                r |	                                j        |k    r dS <dS )a  Return True if the web UI dist is missing or stale.

    Mirrors the staleness logic used by ``_tui_build_needed()`` for the TUI.
    The Vite build outputs to ``hermes_cli/web_dist/`` (per vite.config.ts
    outDir: "../hermes_cli/web_dist"), NOT to ``web/dist/``.  Uses the Vite
    manifest as the sentinel because it is written last and therefore has the
    newest mtime of any build output.
    r  web_distz.vitezmanifest.jsonz
index.htmlTrz  r  r  c                     g | ]}|v|	S r   r   r  s     r   r   z(_web_ui_build_needed.<locals>.<listcomp>|  r  r   N)r  r  z.jsz.jsxz.cssz.htmlz.vue)r|  r}  z	yarn.lockzpnpm-lock.yamlzvite.config.tszvite.config.jsF)r  r1   r  r  r  r-   r  r  rc  r  rM  )rs  dist_dirsentinel
dist_mtimer  r  r  r  r  r  r  s             @r   _web_ui_build_neededrz  j  sl    ~,z9H'!O3H?? +l*?? t)Jnf-..D(*(F(F(F    $9<<<<(<<< 	  	 B{{RSS  7##BGLL"$=$=>>KK444	  
 
 t^99;; 	27799-
::445r   r   )
extra_argsr1  r  r  r{  .r1  c                    |dz  }|                                 r,| dg|}t          j        |||dd          }|j        dk    r|S | dg|}t          j        |||dd          S )u  Run a deterministic npm install that does not mutate ``package-lock.json``.

    Prefers ``npm ci`` (strict, lockfile-preserving) when a lockfile is present;
    falls back to ``npm install`` only if ``npm ci`` fails (e.g. lockfile out of
    sync on a WIP checkout).  Without this, ``npm install`` on npm ≥ 10 silently
    rewrites committed lockfiles (stripping ``"peer": true`` etc.), which leaves
    the working tree dirty and causes the next ``hermes update`` to stash the
    lockfile — repeatedly.
    r}  ciTFr  r1  r2  r  r   r  )r1   r4  r5  rL  )r  r  r{  r1  lockfileci_cmd	ci_resultinstall_cmds           r   _run_npm_install_deterministicr    s      ((H 
t)j)N)
 
 
	 1$$ 	/J/K>%   r   fatalr  c                P   | dz                                   sdS t          |           sdS t          j        d          }|s#|rt	          d           t	          d           | S t	          d           t          || d          }|j        d	k    r1t	          d
|rdnd d|rdndz              |rt	          d           dS t          j        |ddg| d          }|j        d	k    r1t	          d
|rdnd d|rdndz              |rt	          d           dS t	          d           dS )aM  Build the web UI frontend if npm is available.

    Args:
        web_dir: Path to the ``web/`` source directory.
        fatal: If True, print error guidance and return False on failure
               instead of a soft warning (used by ``hermes web``).

    Returns True if the build succeeded or was skipped (no package.json).
    r|  Tr  z3Web UI frontend not built and npm is not available.zBInstall Node.js, then run:  cd web && npm install && npm run buildu   → Building web UI...)r  r{  r   r   u   ✗u   ⚠z Web UI npm install failedrn   z# (hermes web will not be available)z7  Run manually:  cd web && npm install && npm run buildFr5  r  r  r1  z Web UI build failedu     ✓ Web UI built)	r1   rz  rJ  rK  r   r  rL  r4  r5  )rs  r  r  r1r2s        r   _build_web_uir    s    n$,,.. t(( t
,u

C  	XGHHHVWWWy	
"###	'W	O	O	OB	}F%*UFFFErr EG	
 	
 	
  	MKLLLu	eW-74	P	P	PB	}@%*U@@@Err EG	
 	
 	
  	MKLLLu	
4r   c                    	
 g d} t          j                    }g }	 t          j        dk    rt	          j        g dddddd          }|j        d	k    s|j        g S d
|j                            d          D ]}|	                                }|
                    d          r|t          d          d
         
C|
                    d          ry|t          d          d
         }t          
fd| D                       rGt          |          |k    r4	 |                    t          |                     # t          $ r Y w xY wnt	          j        g dddd          }|j        d	k    rt!          |dd                              d          D ]}|	                                }|rd|v r|                    d
d          }t          |          dk    rG	 t          |d	                   }n# t          $ r Y jw xY w|d         	t          	fd| D                       r||k    r|                    |           n$# t"          t          j        t&          f$ r g cY S w xY w|S )u]  Return PIDs of ``hermes dashboard`` processes other than ourselves.

    ``hermes dashboard`` is a long-lived server process commonly started and
    forgotten.  When ``hermes update`` replaces files on disk, the running
    process keeps the old Python backend in memory while the JS bundle on
    disk is updated, causing a silent frontend/backend mismatch (e.g. new
    auth headers the old backend doesn't recognise → every API call 401s).

    The dashboard has no service manager (systemd / launchd), no PID file,
    and we can't know the original launch args — so the only sane action
    after an update is to kill the stale process and let the user restart
    it.  This helper is just the detection step; see
    ``_kill_stale_dashboard_processes`` for the kill.

    Returns an empty list on any scan error (missing ps/wmic, timeout, etc.).
    )zhermes dashboardzhermes_cli.main dashboardzhermes_cli/main.py dashboardwin32)wmicprocessr/   zProcessId,CommandLinez/FORMAT:LISTTr   rJ   ignore)r1  r2  r3  rL   errorsr   Nrn   r  zCommandLine=z
ProcessId=c              3       K   | ]}|v V  	d S rw   r   )ry   r  current_cmds     r   r{   z-_find_stale_dashboard_pids.<locals>.<genexpr>  s(      ??A,??????r   )psz-A-ozpid=,command=r0  r  grepr   r    c              3       K   | ]}|v V  	d S rw   r   )ry   r  r  s     r   r{   z-_find_stale_dashboard_pids.<locals>.<genexpr>3  s'      ;;QAL;;;;;;r   )r-   getpidr   platformr4  r5  rL  r  r,   r3   r+   r*   r   rc   r  r7   rG  r8   r6  r5   )patternsself_piddashboard_pidsr  r   pid_strstrippedr  pidr  r  s            @@r   _find_stale_dashboard_pidsr    s   "  H
 y{{H "N:<7""  ^! ! !#$ 	  F  A%%)>	K++D11 ! !zz||??>22 	!"&s>':':';';"<KK__\22 !"3|#4#4#5#56G????h????? ! #G 8 8!*11#g,,????) ! ! ! D!!&  ^333#$  F  A%%#FHb99??EE 3 3D#zz||H# !v'9'9 $NN433E5zzQ !!%(mm% ! ! ! !#AhG;;;;(;;;;; 3 #x&--c222z8'B   			 sc   A I B9I "D;:I ;
EI EBI G43I 4
H>I  HAI I%$I%c                     	 ddl m}  n# t          $ r Y dS w xY w	 |                                 sdS |                                 }n# t          $ r Y dS w xY w|                    d          rdS 	 |                                 }n# t          $ r d}Y nw xY wt          d|dz            }t                       t          d           t          d	| d
           t          d           t          d           t          d           dS )a  Print a short heads-up about the skill curator after `hermes update`.

    Only fires when the curator is enabled AND has no recorded run yet, which
    is exactly the window where the gateway ticker used to fire Curator
    against a fresh skill library immediately after an update. We defer the
    first real pass by one ``interval_hours``; this notice tells the user how
    to preview or disable before then. Silent on steady state.
    r   )r  Nlast_run_at   r      u   ℹ Skill curatorzC  Background skill maintenance is enabled. First pass is deferred ~zwd after installation; only agent-created skills are in scope and nothing is ever auto-deleted (archive is recoverable).z,  Preview now:  hermes curator run --dry-runz$  Pause it:     hermes curator pausezV  Docs:         https://hermes-agent.nousresearch.com/docs/user-guide/features/curator)	rI  r  r9   
is_enabled
load_stater/   get_interval_hoursr   r   )r  r  hoursdayss       r   _print_curator_first_run_noticer  <  ss   !!!!!!!   !!## 	F""$$   yy **,,   q%2+D	GGG	
		L	L 	L 	L  
 

8999	
0111	
bcccccs4   	 
A A 
AA/B BB:the running backend no longer matches the updated frontendr  c                   
 t                      }|sdS t                       t          dt          |           d|  d           g g 
t          j        dk    r|D ]}	 t          j        ddt          |          dgd	d	d
          }|j        dk    r	                    |           n7
	                    ||j
        p|j        pd                                f           # t          t
          j        t          f$ r.}
	                    |t          |          f           Y d}~d}~ww xY wnddl}ddl}|D ]}	 t%          j        ||j                   # t*          $ r 	                    |           Y ?t,          t          f$ r.}
	                    |t          |          f           Y d}~xd}~ww xY w |j                    dz   }
fd|D             }|r |j                    |k     r |j        d           g }	|D ]y}	 t%          j        |d           |		                    |           .# t*          $ r 	                    |           Y Ot,          t          f$ r |		                    |           Y vw xY w|	}|r |j                    |k     |D ]}	 t%          j        ||j                   	                    |           3# t*          $ r 	                    |           Y Tt,          t          f$ r.}
	                    |t          |          f           Y d}~d}~ww xY wD ]}t          d|            
D ]\  }} t          d| d|             r t          d           t          d           dS dS )u  Kill running ``hermes dashboard`` processes.

    Called at the end of ``hermes update`` (default ``reason``) and also
    from ``hermes dashboard --stop`` (which overrides ``reason``).  The
    dashboard has no service manager, so after a code update the running
    process is guaranteed to be serving stale Python against a
    freshly-updated JS bundle.  Leaving it alive produces silent
    frontend/backend mismatches (new auth headers the old backend doesn't
    recognise → every API call 401s).

    POSIX: SIGTERM, wait up to ~3s for graceful exit, SIGKILL any survivors.
    Windows: ``taskkill /PID <pid> /F`` since there's no clean SIGTERM
    equivalent for background console apps.

    The dashboard isn't auto-restarted because we don't know the original
    launch args (--host, --port, --insecure, --tui, --no-open).  The user
    restarts it manually; a hint is printed.
    Nu   ⟲ Stopping z dashboard process(es) (r   r  taskkillz/PIDz/FTr   r0  r   rn         @c                 8    g | ]}|vr|d  D             v|S )c                     h | ]
}|d          S )r   r   )ry   fs     r   r  z=_kill_stale_dashboard_processes.<locals>.<listcomp>.<setcomp>  s     6 6 6!1 6 6 6r   r   )ry   r  failedkilleds     r   r   z3_kill_stale_dashboard_processes.<locals>.<listcomp>  sD     8 8 8avoo 6 6v 6 6 666 666r   g?u       ✓ stopped PID u       ✗ failed to stop PID r[  z*  Restart the dashboard when you're ready:z"    hermes dashboard --port <port>)r  r   r*   r   r  r4  r5  r   rL  r  r   r  r3   r8   r6  r5   signalrb   r-   killSIGTERMProcessLookupErrorPermissionErrorrh  ri  SIGKILL)r  pidsr  r  rU  _signalra   rp  pendingstill_pendingr  r  s             @@r   _kill_stale_dashboard_processesr  c  s   * &''D 	GGG	
F#d))
F
FV
F
F
FGGGF$&F
|w 	- 	-C
-#S48#'dB   $))MM#&&&&MM3)M&-)M2(T(T(V(V"WXXX%z'@'J - - -sCFFm,,,,,,,,-	- 	!     	- 	-C-W_----% # # #c"""""#W- - - -sCFFm,,,,,,,,- #5?$$s*8 8 8 8 8d 8 8 8 	$/%/++h66EKM 	. 	..GCOOO "((---- * ' ' 'MM#&&&&&'1 . . .!((-----.
 $G  	$/%/++h66   	- 	-C-W_---c""""% # # #c"""""#W- - - -sCFFm,,,,,,,,-  , ,*S**++++ = =V;C;;6;;<<<< 4:;;;2333334 4sm   BC!!D+=$D&&D+=EF79F7	$F22F7H22I;%I;:I;/K

L)+L);$L$$L)c           	      $   ddl }ddl}ddlm} d}d| d}t	          d           	 |                    d	          }t          j                            |d
| d          } |||           t	          d           |	                    |d          5 }t          j        
                    |          }	|                                D ]}
t          j        
                    t          j                            ||
j                            }|                    |	t          j        z             s||	k    rt          d|
j         d          |                    |           ddd           n# 1 swxY w Y   t          j                            |d
|           }t          j                            |          s`t          j        |          D ]K}t          j                            ||          }t          j                            |          r
|dk    r|} nLh d}d}t          j        |          D ]}||v rt          j                            ||          }t          j                            t'          t(                    |          }t          j                            |          rIt          j                            |          rt-          j        |           t-          j        ||           nt-          j        ||           |dz  }t	          d| d           t-          j        |d           n=# t4          $ r0}t	          d|            t7          j        d           Y d}~nd}~ww xY wt;          t(                    }|rt	          d| d|dk    rdnd            t	          d           t-          j        d          }|r;i t          j        dt'          t(          dz            i}tA          |dg|            nt6          j!        d!dg}	 tE          j#        |d"gz   t(          dd#           n@# tD          j$        $ r. tE          j#        t6          j!        d!d$d%d&gt(          d'           Y nw xY wtA          |           tK                       tM          t(          d(z             	 dd)l'm(} t	          d*            |d+          }|d,         rAt	          d-tS          |d,                    d.d/                    |d,                               |*                    d0          rAt	          d1tS          |d0                    d2d/                    |d0                               |*                    d3          r&t	          d4tS          |d3                    d5           |*                    d6          r&t	          d7tS          |d6                    d8           |d,         s$|*                    d0          st	          d9           n# t4          $ r Y nw xY wt	                       t	          d:           	 tW                       n2# t4          $ r%}tX          -                    d;|           Y d}~nd}~ww xY wt]                       dS )<zUpdate Hermes Agent by downloading a ZIP archive.

    Used on Windows when git file I/O is broken (antivirus, NTFS filter
    drivers causing 'Invalid argument' errors on file creation).
    r   N)urlretriever>  z@https://github.com/NousResearch/hermes-agent/archive/refs/heads/z.zipu!   → Downloading latest version...zhermes-update-)r  zhermes-agent-u   → Extracting...rzZip-slip detected: z escapes extraction directory__MACOSX>   rY  rz  rG   rZ  r   u   ✓ Updated z items from ZIPTrk  u   ✗ ZIP update failed:      ✓ Cleared  stale __pycache__ directorr
  ies#   → Updating Python dependencies...uvVIRTUAL_ENVrY  pipr  -m	--versionr  r  r1  	ensurepip	--upgrade--default-pipr  r  webr2     → Syncing bundled skills...r4  copied  +  new: , updated     ↑ 
 updated: user_modified  ~  user-modified (kept)cleaned     −  removed from manifest     ✓ Skills are up to date   ✓ Update complete!#Curator first-run notice failed: %s)/r  zipfileurllib.requestr  r   mkdtempr-   rc  rM  ZipFilerealpathinfolistfilenamer+   sepr7   
extractallisdirlistdirr   r  r1   rJ  rq  copytreecopy2r9   r   r   r]  rK  r.   3_install_python_dependencies_with_optional_fallbackr  r4  r5  CalledProcessError_update_node_dependenciesr  rK  r3  r*   r/   r  loggerdebugr  )rL  r  r  r  branchzip_urltmp_dirzip_pathzftmp_dir_realmembermember_path	extractedr  	candidatepreserveupdate_countr  r  dstrU  r5  uv_binuv_envpip_cmdr3  r  s                              r   _update_via_zipr    sU    OOONNN******FW6WWW  

-...5""*:";;7<<)E)E)E)EFFGX&&&!"""__Xs++ 	#r7++G44L++--   g..rw||GV_/U/UVV#..|bf/DEE#|33$\fo\\\   MM'"""	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# GLL*B&*B*BCC	w}}Y'' 	Z((  GLL!44	7==++ Z )IE <;;Jy)) 	 	Dx',,y$//C',,s<00$77Cw}}S!! '7>>#&& 'M#&&&S))))S#&&&ALL:\:::;;; 	gT22222   +++,,,
 $L11G 
aWaaSTZ_aa	
 	
 	
 

/000\$F EJBJJs<&3H/I/IJJ;VUOQWXXXXX >4/	N;-' #	     , 	 	 	N{KQ      	 	<GDDD,&'''111111-...4(((( 	USVH-..SSdiix@P6Q6QSSTTT::i   	YVI.//YY499VIEV;W;WYY   ::o&& 	NLVO455LLLMMM::i   	KI3vi011IIIJJJh 	1

9(=(= 	1/000    
GGG	
 !!!?')))) ? ? ?:A>>>>>>>>?#%%%%%s{   A+L9 CE, L9 ,E00L9 3E04GL9 9
M3&M..M3!P; ;:Q87Q80E"X 
X X Y 
Y?Y::Y?git_cmdc                 ^   t          j        | ddgz   |ddd          }|j                                        sd S t          j        | ddgz   |dd          }|j                                        r*t	          d           t          j        | d	gz   |d
           ddlm}m}  |j        |j                  	                    d          }t	          d           t          j        | dddd|gz   |d           t          j        | g dz   |ddd          j                                        }|S )Nr   z--porcelainTr~  zls-filesz
--unmergedr  u?   → Clearing unmerged index entries from a previous conflict...resetr  r   )rX   timezonez%hermes-update-autostash-%Y%m%d-%H%M%Su8   → Local changes detected — stashing before update...stashpushz--include-untrackedr  r  )	rev-parsez--verifyz
refs/stash)
r4  r5  r  r3   r   rX   r
  nowutcre   )r  r  r   unmergedrX   r
  
stash_name	stash_refs           r   _stash_local_changes_if_neededr  W  s   ^8]++  F =   t ~:|,,	  H  JOPPPw'*DIIII++++++++hl++44/ J 

DEEEN7F$94LL   
 9999   UUWW  r   r  c                    t          j        | g dz   |ddd          }|j                                        D ]I}|                    d          \  }}}|                                |k    r|                                c S Jd S )N)r  r   z--format=%gd %HTr~  r   )r4  r5  r  r   r   r3   )r  r  r  
stash_listr   selectorr   rJ  s           r   _resolve_stash_selectorr    s     6666  J !,,.. $ $"nnS11!V<<>>Y&&>>##### '4r   stash_selectorc                     t          d           t          d           |rt          d|            d S t          d|  d           d S )NzS  Check `git status` first so you don't accidentally reapply the same change twice.z@  Find the saved entry with: git stash list --format='%gd %H %s'z!  Remove it with: git stash drop z  Look for commit z7, then drop its selector with: git stash drop stash@{N})r   )r  r  s     r   _print_stash_cleanup_guidancer    sy     
]   

LMMM 
B.BBCCCCCeeee	
 	
 	
 	
 	
r   prompt_userc                 p   |rt                       t          d           t          d           t          d           t          d           | |dd          }n2t                                                                                      }|dvr2t          d           t          d           t          d	|            d
S t          d           t	          j        | dd|gz   |dd          }t	          j        | g dz   |dd          }t          |j                                                  }|j        dk    s|r@t          d           |j                                        r&t          |j                                                   |j	                                        r&t          |j	                                                   |j                                        }	|	r8t          d           |	
                                D ]}
t          d|
            t          d           t          d|            t	          j        | g dz   |d           t          d           t          d|            d
S t          | ||          }|.t          d           t          d           t          |           nt	          j        | dd|gz   |dd          }|j        dk    rt          d           |j                                        r&t          |j                                                   |j	                                        r&t          |j	                                                   t          d           t          ||           t          d           t          d            dS )!Nu/   ⚠ Local changes were stashed before updating.zL  Restoring them may reapply local customizations onto the updated codebase.z=  Review the result afterward if Hermes behaves unexpectedly.z Restore local changes now? [Y/n]r
  r/  z Skipped restoring local changes.z.Your changes are still preserved in git stash.z'Restore manually with: git stash apply Fu   → Restoring local changes...r  applyTr  )diffz--name-onlyz--diff-filter=Ur   uF   ✗ Update pulled new code, but restoring local changes hit conflicts.z
Conflicted files:u     • u8   
Your stashed changes are preserved — nothing is lost.z  Stash ref: )r	  --hardHEADr  z"Working tree reset to clean state.z1Restore your changes later with: git stash apply uR   ⚠ Local changes were restored, but Hermes couldn't find the stash entry to drop.zT  The stash was left in place. You can remove it manually after checking the result.dropuP   ⚠ Local changes were restored, but Hermes couldn't drop the saved stash entry.u?   ⚠ Local changes were restored on top of the updated codebase.zB  Review `git diff` / `git status` if Hermes behaves unexpectedly.)r   r  r3   r   r4  r5  r  r  rL  r   r   r  r  )r  r  r  r  input_fnrx  restorer  has_conflictsconflicted_filesr  r  r!  s                r   _restore_stashed_changesr&    s"     ?@@@Z	
 	
 	
 	MNNN0111x BCHHHHww}},,..H+++4555BCCCGIGGHHH5	
*+++n7GY//	  G ~<<<<	  H ..0011MQ-VWWW>!! 	*'.&&(()))>!! 	*'.&&(())) $?0022 	$'(((%0022 $ $lqll####IJJJ)i))***
 	1111	
 	
 	
 	

 	2333M)MMNNN u,Wc9EEN`	
 	
 	
 	b	
 	
 	
 	&i0000~w77	
 
 
 ?ab   {  "" +dk''))***{  "" +dk''))***f   *)^DDD	
KLLL	
NOOO4r   >   (git@github.com:NousResearch/hermes-agent,git@github.com:NousResearch/hermes-agent.git,https://github.com/NousResearch/hermes-agent0https://github.com/NousResearch/hermes-agent.gitr*  z.skip_upstream_promptc                     	 t          j        | g dz   |dd          }|j        dk    r|j                                        S n# t
          $ r Y nw xY wdS )z5Get the URL of the origin remote, or None if not set.)remoteget-urloriginTr  r   N)r4  r5  rL  r  r3   r9   r  r  r  s      r   _get_origin_urlr0    s    
5555	
 
 
 !!=&&((( "   4s   A A 
AA
origin_urlc                    | sdS |                      d          }|                    d          r
|dd         }t          D ]?}|                     d          }|                    d          r
|dd         }||k    r dS @dS )zDCheck if the origin remote points to a fork (not the official repo).Fr   rZ  NT)r  r  OFFICIAL_REPO_URLS)r1  r  officialofficial_normalizeds       r   _is_forkr7  /  s     u""3''J6"" %_
&  &ooc22''// 	;"5crc":,,,55 -4r   c                 v    	 t          j        | g dz   |dd          }|j        dk    S # t          $ r Y dS w xY w)z-Check if an 'upstream' remote already exists.)r,  r-  upstreamTr  r   Fr4  r5  rL  r9   r/  s      r   _has_upstream_remoter;  @  sg    	7777	
 
 
  A%%   uu   '* 
88c                     	 t          j        | dddt          gz   |dd          }|j        dk    S # t          $ r Y dS w xY w)zHAdd the official repo as the 'upstream' remote. Returns True on success.r,  r  r9  Tr  r   F)r4  r5  OFFICIAL_REPO_URLrL  r9   r/  s      r   _add_upstream_remoter?  N  sj    	x
4EFF	
 
 
  A%%   uus   .1 
??r  headc                     	 t          j        | dd| d| gz   |dd          }|j        dk    r&t          |j                                                  S n# t          $ r Y nw xY wdS )zDCount commits on `head` that are not on `base`. Returns -1 on error.rev-list--countz..Tr  r   r   )r4  r5  rL  rc   r  r3   r9   )r  r  r  r@  r  s        r   _count_commits_betweenrD  \  s    
z9.?.?.?.?@@	
 
 
 !!v}**,,--- "   2s   AA 
A$#A$c                  V    ddl m}   |             t          z                                  S )z2Check if user previously declined to add upstream.r   rD   )r0   rE   SKIP_UPSTREAM_PROMPT_FILEr1   rD   s    r   _should_skip_upstream_promptrG  l  s4    000000O 99AACCCr   c                  ~    	 ddl m}   |             t          z                                   dS # t          $ r Y dS w xY w)z3Create marker file to skip future upstream prompts.r   rD   N)r0   rE   rF  touchr9   rD   s    r   _mark_skip_upstream_promptrJ  s  sa    444444			6	6==?????   s   *. 
<<c                 v    	 t          j        | g dz   |dd          }|j        dk    S # t          $ r Y dS w xY w)znAttempt to push updated main to origin (sync fork).

    Returns True if push succeeded, False otherwise.
    )r  r.  r>  z--force-with-leaseTr  r   Fr:  r/  s      r   _sync_fork_with_upstreamrL  }  sg    
	FFFF	
 
 
  A%%   uur<  c                     t          | |          }|st                      rdS t                       t          d           t          d           t                       	 t          d                                                                          }n'# t          t          f$ r t                       d}Y nw xY w|dv rBt          d           t          | |          rt          d           d	}n0t          d
           dS t          d           t                       dS t                       t          d           	 t          j        | g dz   |d	d	           n%# t          j        $ r t          d           Y dS w xY wt          | |dd          }t          | |dd          }|dk     s|dk     rt          d           dS |dk    rPt                       t          d| d           t          d           t          d           t          d           dS |dk    rt          d           dS t                       t          d| d           t          d           	 t          j        | g dz   |d	           n%# t          j        $ r t          d           Y dS w xY wt          d            t          d!           t          | |          rt          d"           dS t          d#           t          d$           dS )%a[  Check if fork is behind upstream and sync if safe.

    This implements the fork upstream sync logic:
    - If upstream remote doesn't exist, ask user if they want to add it
    - Compare origin/main with upstream/main
    - If origin/main is strictly behind upstream/main, pull from upstream
    - Try to sync fork back to origin if possible
    Nu=   ℹ Your fork is not tracking the official Hermes repository.zA  This means you may miss updates from NousResearch/hermes-agent.z/Add official repo as 'upstream' remote? [Y/n]: r.  r/  u   → Adding upstream remote...uF     ✓ Added upstream: https://github.com/NousResearch/hermes-agent.gitTu<     ✗ Failed to add upstream remote. Skipping upstream sync.zg  Skipped. Run 'git remote add upstream https://github.com/NousResearch/hermes-agent.git' to add later.u   → Fetching upstream...)fetchr9  --quiet)r  r1  r  u7     ✗ Failed to fetch upstream. Skipping upstream sync.zupstream/mainzorigin/mainr   u9     ✗ Could not compare branches. Skipping upstream sync.u   ℹ Your fork has z commit(s) not on upstream.z2  Skipping upstream sync to preserve your changes.z-  If you want to merge upstream changes, run:z    git pull upstream mainu&     ✓ Fork is up to date with upstreamu   → Fork is z commit(s) behind upstreamu   → Pulling from upstream...)pull	--ff-onlyr9  r>  r  uO     ✗ Failed to pull from upstream. You may need to resolve conflicts manually.u     ✓ Updated from upstreamu   → Syncing fork...u     ✓ Fork synced with upstreamuL     ℹ Got updates from upstream but couldn't push to fork (no write access?)zF    Your local repo is updated, but your fork on GitHub may be behind.)r;  rG  r   r  r3   r   r  r  r?  rJ  r4  r5  r  rD  rL  )r  r  has_upstreamrx  origin_aheadupstream_aheads         r   _sync_with_upstream_if_neededrU    s    (55L !')) 	F 	MNNNQRRR	GHHNNPPVVXX H +, 	 	 	GGGHHH	 '''1222#GS11 \    $TUUUy   '(((F 
GGG	
$%%%	6666		
 	
 	
 	
 	
 (   GHHH
 *'3WWL+m_ N a>A--IJJJ aL<LLLMMMBCCC=>>>*+++ 6777 
GGG	
C
C
C
CDDD	
()))
????	
 	
 	
 	
 	

 (   ]	
 	
 	
 		 

'((( 

   -- X/00000Z	
 	
 	
 	VWWWWWs6   3B !B76B7=E E=<E=I< <JJc                     g } ddl m}  |            }|                     |           |dz  }|                                r@|                                D ]+}|                                r|                     |           ,| D ]@}	 |dz  }|                                r|                                 1# t          $ r Y =w xY wdS )u  Delete the update-check cache for ALL profiles so no banner
    reports a stale "commits behind" count after a successful update.

    The git repo is shared across profiles — when one profile runs
    ``hermes update``, every profile is now current.
    r   r#   profilesz.update_checkN)r0   r$   r  r  iterdirr1   r  r9   )homesr$   default_homeprofiles_rootr  r  
cache_files          r   _invalidate_update_cacher]     s    E888888**,,L	LL :-M $"**,, 	$ 	$E||~~ $U###  	/J  "" $!!### 	 	 	D	 s   -B44
C Cc                  4   	 ddl } t          dz                      d          5 }|                     |                              di           }ddd           n# 1 swxY w Y   n# t
          $ r g cY S w xY w|                    di           }t          |t                    sg S |                    dg           }g }|D ]Y}d|v rSd	|v rO|                    dd
          d
                             d	d
          d         }||v r|	                    |           Z|S )u7  Return the optional extras referenced by the ``all`` group.

    Only extras that ``[all]`` actually pulls in are retried individually.
    Extras outside ``[all]`` (e.g. ``rl``, ``yc-bench``) are intentionally
    excluded — they have heavy or platform-specific deps that most users
    never installed.
    r   Nzpyproject.tomlrbprojectzoptional-dependenciesall[]r   )
tomllibr  openloadr/   r9   r   r   r,   r  )rd  handler`  optional_depsall_refs
referencedrefr?   s           r   !_load_installable_optional_extrasrl    s~   --33D99 	>Vll6**..y"==G	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	>   			 KK 7<<MmT** 	   ++HJ ( (#::#**99S!$$Q'--c155a8D}$$!!$'''s4   !A% *AA% AA%  A!A% %A43A4r  install_cmd_prefixr  c          	      v   	 t          j        | g dz   t          d|           dS # t           j        $ r t	          d           Y nw xY wt          j        | g dz   t          d|           g }g }t                      D ]j}	 t          j        | ddd	| d
dgz   t          d|           |                    |           A# t           j        $ r |                    |           Y gw xY w|r%t	          dd                    |                      |r't	          dd                    |                      dS dS )zKInstall base deps plus as many optional extras as the environment supports.)r  rH  z.[all]rO  T)r  r  r  Nu`     ⚠ Optional extras failed, reinstalling base dependencies and retrying extras individually...)r  rH  rX  rO  r  rH  z.[rc  rO  u0     ✓ Reinstalled optional extras individually: r  u1     ⚠ Skipped optional extras that still failed: )r4  r5  r  r  r   rl  r  rM  )rm  r  failed_extrasinstalled_extrasr  s        r   r  r  =  s   
!G!G!GG		
 	
 	
 	
 	( 
 
 
n	
 	
 	
 	
 	


 N>>>>	     "M"$244 
( 
(		(N"i}E}}}i%PP 	    ##E****, 	( 	( 	(  '''''	(  
\tyyIY?Z?Z\\	
 	
 	
  
Z		-@X@XZZ	
 	
 	
 	
 	

 
s!   "& AA=B??$C&%C&c                     t          j        d          } | sd S dt          fdt          dz  ff}t          d |D                       sd S t	          d           |D ]\  }}|dz                                  st          | |d          }|j        d	k    rt	          d
|            Mt	          d|            |j        pd	                                }|r*t	          d|
                                d                     d S )Nr  z	repo rootr  c              3   J   K   | ]\  }}|d z                                   V  dS )r|  Nr1   )ry   r   rc  s      r   r{   z,_update_node_dependencies.<locals>.<genexpr>x  s7      EEGAt~%--//EEEEEEr   u$   → Updating Node.js dependencies...r|  )r  r  r  r  r  r        ✓ u     ⚠ npm install failed in rn   r  r   )rJ  rK  r  r   r   r1   r  rL  r   r3   r   )r  pathsr  rc  r  r   s         r   r  r  o  sQ   
,u

C  
l#	<(*+E EEuEEEEE 	
0111 4 4t~%--// 	/R
 
 

 !!"5""###4U44555-%2,,.. 	42**,,R022333!4 4r   c                   6    e Zd ZdZd Zd Zd Zd Zd Zd Z	dS )	_UpdateOutputStreamu  Stream wrapper used during ``hermes update`` to survive terminal loss.

    Wraps the process's original stdout/stderr so that:

    * Every write is also mirrored to an append-only log file
      (``~/.hermes/logs/update.log``) that users can inspect after the
      terminal disconnects.
    * Writes to the original stream that fail with ``BrokenPipeError`` /
      ``OSError`` / ``ValueError`` (closed file) no longer cascade into
      process exit — the update keeps going, only the on-screen output
      stops.

    Combined with ``SIGHUP -> SIG_IGN`` installed by
    ``_install_hangup_protection``, this makes ``hermes update`` safe to
    run in a plain SSH session that might disconnect mid-install.
    c                 0    || _         || _        d| _        d S NF)	_original_log_original_broken)selforiginallog_files      r   __init__z_UpdateOutputStream.__init__  s    !	 %r   c                    | j         ,	 | j                             |           n# t          $ r Y nw xY w| j        r-t	          |t
          t          f          rt          |          ndS 	 | j                            |          S # t          t          t          f$ r7 d| _        t	          |t
          t          f          rt          |          ndcY S w xY w)Nr   T)r{  writer9   r|  r   r   bytesr*   rz  BrokenPipeErrorr5   r7   )r}  rf  s     r   r  z_UpdateOutputStream.write  s    9 	%%%%      	F *4#u > >E3t999AE	F>''---*5 	F 	F 	F %)D! *4#u > >E3t999AEEE		Fs   $ 
11)B ACCc                     | j         +	 | j                                          n# t          $ r Y nw xY w| j        rd S 	 | j                                         d S # t
          t          t          f$ r d| _        Y d S w xY w)NT)r{  flushr9   r|  rz  r  r5   r7   r}  s    r   r  z_UpdateOutputStream.flush  s    9 	!!!!     	F	)N  """""*5 	) 	) 	)$(D!!!!	)s   # 
00A A:9A:c                 j    | j         rdS 	 | j                                        S # t          $ r Y dS w xY wry  )r|  rz  r   r9   r  s    r   r   z_UpdateOutputStream.isatty  sM      	5	>((*** 	 	 	55	s   $ 
22c                 4    | j                                         S rw   )rz  filenor  s    r   r  z_UpdateOutputStream.fileno  s     ~$$&&&r   c                 ,    t          | j        |          S rw   )rG  rz  )r}  r?   s     r   __getattr__z_UpdateOutputStream.__getattr__  s    t~t,,,r   N)
__name__
__module____qualname____doc__r  r  r  r   r  r  r   r   r   rw  rw    s{         "& & &
F F F() ) )  ' ' '
- - - - -r   rw  gateway_modec                    t           j        t           j        ddd}| r|S ddl}t	          |d          r9	 |                    |j        |j                   n# t          t          f$ r Y nw xY w	 ddl	m
}  |            dz  }|                    dd	           |d
z  }t          |ddd          }ddl}|                    d|j                                                            d           d           ||d<   t#          |d         |          t           _        t#          |d         |          t           _        d|d<   n# t$          $ r d|d<   Y nw xY w|S )u$  Protect ``cmd_update`` from SIGHUP and broken terminal pipes.

    Users commonly run ``hermes update`` in an SSH session or a terminal
    that may close mid-install.  Without protection, ``SIGHUP`` from the
    terminal kills the Python process during ``pip install`` and leaves
    the venv half-installed; the documented workaround ("use screen /
    tmux") shouldn't be required for something as routine as an update.

    Protections installed:

    1. ``SIGHUP`` is set to ``SIG_IGN``.  POSIX preserves ``SIG_IGN``
       across ``exec()``, so pip and git subprocesses also stop dying on
       hangup.
    2. ``sys.stdout`` / ``sys.stderr`` are wrapped to mirror output to
       ``~/.hermes/logs/update.log`` and to silently absorb
       ``BrokenPipeError`` when the terminal vanishes.

    ``SIGINT`` (Ctrl-C) and ``SIGTERM`` (systemd shutdown) are
    **intentionally left alone** — those are legitimate cancellation
    signals the user or OS sent on purpose.

    In gateway mode (``hermes update --gateway``) the update is already
    spawned detached from a terminal, so this function is a no-op.

    Returns a dict that ``cmd_update`` can pass to
    ``_finalize_update_output`` on exit.  Returning a dict rather than a
    tuple keeps the call site forward-compatible with future additions.
    NF)prev_stdoutprev_stderrr  r  r   SIGHUPrD   logsTrh  z
update.logar   rJ   )	bufferingrL   z
=== hermes update started seconds)timespecz ===
r  r  r  r  )r   r  r   r  hasattrr  SIG_IGNr7   r5   r   rE   rp  re  rX   r  r  	isoformatrw  r9   )r  r  r  _get_hermes_homelogs_dirlog_pathr  _dts           r   _install_hangup_protectionr    s   < zz	 E   w!! 	NN7>7?;;;;G$ 	 	 	 D	! 	JIIIII##%%.td333l*#WEEEH|!!++Y+??H H H	
 	
 	

 %j(})=xHH
(})=xHH
!k ! ! ! !j!
 Ls$    A A*)A*.CE EEc                    | sdS |                      d          rx	 |                      dt          j                  t          _        n# t          $ r Y nw xY w	 |                      dt          j                  t          _        n# t          $ r Y nw xY w|                      d          }|<	 |                                 |                                 dS # t          $ r Y dS w xY wdS )zWRestore stdio and close the update.log handle opened by ``_install_hangup_protection``.Nr  r  r  r  )r/   r   r  r9   r   r  r(  )r  r  s     r   _finalize_update_outputr  )  s    yy 	=#*==CJJ 	 	 	D		=#*==CJJ 	 	 	D	yy$$H	NNNN 	 	 	DD		 s5   *A 
AA*B 
BB*(C 
C"!C"c                     t           dz  } |                                 s#t          d           t          j        d           dg}t          j        dk    rg d}t          d           t          j        |dd	gz   t           d
d
          }|j        dk    r|j	        
                                }d|v sd|v rt          d           nSd|v sd|v rt          d           n;t          d           |r*t          d|                                d                     t          j        d           t          j        |g dz   t           d
d
d
          }t          |j        
                                          }|dk    rt          d           d S |dk    rdnd}t          d| d| d           ddlm} t          d |             d           d S )!zIImplement ``hermes update --check``: fetch and report without installing.rZ  u6   ✗ Not a git repository — cannot check for updates.r   gitr  r  r  windows.appendAtomically=falseu   → Fetching from origin...rN  r.  Tr  r   Could not resolve hostunable to access9   ✗ Network error — cannot reach the remote repository.Authentication failedcould not read UsernameD   ✗ Authentication failed — check your git credentials or SSH key.u    ✗ Failed to fetch from origin.r   )rB  zHEAD..origin/mainrC  r~  u   ✓ Already up to date.rJ  rK  u   ⚕ Update available: r   z behind origin/main.rH  z  Run 'z' to install.N)r  r1   r   r   r   r  r4  r5  rL  r   r3   r   rc   r  r   rI  )git_dirr  fetch_resultr   
rev_resultrO  rP  rI  s           r   _cmd_update_checkr  ?  s0   V#G>> FGGGgG
|wAAA	
'(((>7H%%	  L !##$**,,#v--1Cv1M1MMNNNN$..2Kv2U2UXYYYY4555 536,,..q133444>>>>  J "((**++F{{'(((((#)Q;;xxIRvRRRRRSSS@@@@@@C2244CCCDDDDDr   c            
      t   t           j        dk    rdS 	 t          j                    dk    rdS n# t          $ r Y dS w xY wt          d          } |                                 s|                                 sdS t          j        	                    d          pd}	 t          j        ddd	| d
t          j        	                    dd           ddddgddd          }n# t          t          j        f$ r Y dS w xY w|j        dk    rdS d}d}d}dD ]}t          |          |z  }|                                s*	 |                    d          }n# t"          $ r Y Nw xY wt%          d |                                D                       }	|	r	 |                    dd          5 }
|
                    d|z   dz   |z   dz              ddd           n# 1 swxY w Y   n,# t"          $ r}t-          d| d|            Y d}~d}~ww xY wt-          d |            d}|rt-          d!           dS dS )"aH  Ensure /usr/local/bin is on PATH for RHEL-family root non-login shells.

    Mirrors the post-symlink probe added to ``scripts/install.sh`` so that
    existing FHS-layout root installs on RHEL/CentOS/Rocky/Alma 8+ get
    repaired on ``hermes update`` without requiring a reinstall.  The
    installer's assumption that ``/usr/local/bin`` is on PATH for every
    standard shell breaks on those distros in non-login interactive shells
    (su, sudo -s, tmux panes, some web terminals): /etc/bashrc doesn't
    add /usr/local/bin and /root/.bash_profile doesn't either.  Symptom:
    ``hermes`` prints ``command not found`` even though the symlink lives
    at /usr/local/bin/hermes.

    Silent no-op on: non-Linux, non-root, non-FHS installs, and any system
    where ``bash -i -c 'command -v hermes'`` already resolves.  Idempotent.
    linuxNr   z/usr/local/bin/hermesHOMEz/rootr  rC  zHOME=zTERM=rD  dumbr  r  zcommand -v hermesTr   r0  z"export PATH="/usr/local/bin:$PATH"uK   # Hermes Agent — ensure /usr/local/bin is on PATH (RHEL non-login shells)F)z.bashrcz.bash_profilern  r  c              3   v   K   | ]4}d |v o+d|v o'|                                                     d           V  5dS )z/usr/local/binr  r|   N)lstripr+   )ry   r   s     r   r{   z)_ensure_fhs_path_guard.<locals>.<genexpr>  sj       
 
  $ 2$2KKMM,,S111
 
 
 
 
 
r   r  rJ   rK   r  u     ⚠ Could not update r[  u&     ✓ Added /usr/local/bin to PATH in z?    (reload your shell or run 'source ~/.bashrc' to pick it up))r   r  r-   geteuidr  r   
is_symlinkr1   r.   r/   r4  r5  r8   r6  rL  r  r2   r5   r   r   re  r  r   )fhs_linkr  rR  	path_linepath_comment	wrote_anyr  r   existingalready_guardedr  rU  s               r   _ensure_fhs_path_guardr  o  sJ     |w:<<1F     +,,H   ):): 
 :>>&!!,WD	DT^^5RZ^^FF3355T4!46  dB
 
 
 z89   14I	"  I1  	4jj9${{}} 		}}I}66HH 	 	 	H	  
 
 !++--	
 
 
 
 
  		#00 GA|+d2Y>EFFFG G G G G G G G G G G G G G G 	 	 	6C66166777HHHH	 	<s<<===		 QOPPPPPQ Qsm   . 
<<AC C98C9<E
E E G#)"GG#G	G#G	G##
H-HHc           	      <   t          | dd          rt          d           t                       dS t          t          | dd                    }	 ddlm}  |            }nF# t
          $ r9}t          j        t                    	                    d|           i }Y d}~nd}~ww xY wt          |t                    r|                    d	i           ni }|                    d
d          }|                    dd          }|s|sdS 	 ddlm} n9# t
          $ r,}t          d| d           t                       Y d}~dS d}~ww xY wt          d           t          j                    }		  |t#          |                    }
nG# t
          $ r:}t          d|            t          d           t                       Y d}~dS d}~ww xY wt          j                    |	z
  }|
t          d           t                       dS 	 |
                                j        }n# t(          $ r d}Y nw xY w| d}dD ]}|dk     r n|dz  }|dd| }	 ddlm}m}  |            }	  |             d|
                    |           }n# t2          $ r t5          |
          }Y nw xY wn# t
          $ r t5          |
          }Y nw xY wt          d| d| d|dd           t          d |
            t          d!           t          d"           t                       dS )#u  Create a full zip backup of HERMES_HOME before running the update.

    Gated on ``updates.pre_update_backup`` in config (default false).  Off
    by default because the zip can add minutes to every update on large
    HERMES_HOME directories.  The ``--backup`` flag on ``hermes update``
    opts in for a single run; ``--no-backup`` forces it off when config
    has it enabled.  Never raises — a backup failure should not block the
    update itself.
    	no_backupFu,   ◆ Pre-update backup: skipped (--no-backup)Nbackupr   rR   z/Could not load config for pre-update backup: %supdatespre_update_backupbackup_keepr   )create_pre_update_backupu5   ⚠ Pre-update backup: could not load backup module (z); continuing update.u!   ◆ Creating pre-update backup...)keepu     ⚠ Backup failed: z  Continuing with update.uI     ⚠ Backup skipped (no files found or write failed); continuing update.z B)KBMBGBi   .1fr   rE   r  r   z  Saved:    r  r  zs)z  Restore:  hermes import z6  Disable:  omit --backup (backups are off by default)z?            set updates.pre_update_backup: false in config.yaml)rG  r   r  r   rS   r9   logging	getLoggerr  r  r   r   r/   rA  r  ra   rh  rc   r  st_sizer5   r0   rE   r  relative_tor7   r   )rL  force_backuprS   r   rA   updates_cfgenabledr  r  t0out_pathelapsed
size_bytessize_strunitrE   r  r  display_paths                      r   _run_pre_update_backupr    s    t[%(( <===h6677L111111kmm   (##))*[]`aaa -7sD,A,AI#'')R(((rKoo1599G??=!,,D <  	>>>>>>>   `c```aaa
 

-...			B++T;;;   +c++,,,)***	 o"$GYZZZ]]__,

   


    H" . .Ed
 ---t--%IIIIIIII  	)1133RRh6J6J46P6PRRLL 	) 	) 	)x==LLL	) % % %8}}% 

D
D
D
D
DW
D
D
D
DEEE	
1x
1
1222	
CDDD	
LMMM	GGGGGs   A! !
B$+/BB$D 
E!D??E*F 
G/GGH H,+H,J% ""J J% J!J%  J!!J% %K Kc                 2   ddl m}m}  |            r |d           dS t          | dd          rt	                       dS t          | dd          }t          |          }	 t          | |           t          |           dS # t          |           w xY w)	zUpdate Hermes Agent to the latest version.

    Thin wrapper around ``_cmd_update_impl``: installs hangup protection,
    runs the update, then restores stdio on the way out (even on
    ``sys.exit`` or unhandled exceptions).
    r   )
is_managedmanaged_errorzupdate Hermes AgentNr  Fgateway)r  )r   r  r  rG  r  r  _cmd_update_implr  )rL  r  r  r  _update_io_states        r   
cmd_updater    s     <;;;;;;;z|| +,,,tWe$$ 4E22L
 2|LLL2L9999 011111 01111s   #B Bc                 1  mno |rddnd}t          t          | dd                    }t          d           t                       t          |            d}t          dz  }|                                sEt          j        dk    rd	}n2t          d
           t          d           t          j        d           t          j        dk    r3|                                rt          j
        g dt          dd	           dg}t          j        dk    rg d}t          |t                    }t          |          }|r/t          d           t          d|            t                       |rt          |            dS 	 t          d           t          j
        |ddgz   t          d	d	          }	|	j        dk    r|	j                                        }
d|
v sd|
v r>t          d           t          |
rd|
                                d          nd           nSd|
v sd|
v rt          d           n;t          d           |
r*t          d|
                                d                     t          j        d           t          j
        |g dz   t          d	d	d	           }|j                                        }d!}|d!k    rZ|d"k    rd#nd$| d%}t          d&| d'           t'          |t                    }t          j
        |d(d!gz   t          d	d	d	            nt'          |t                    }|duo@| o=|p;t          j                                        ot          j                                        }t          j
        |d)d*| d+gz   t          d	d	d	           }t-          |j                                                  }|dk    rat/                       |t1          |t          |||,           |d-vr#t          j
        |d(|gz   t          d	d	d            t          d.           dS t          d/| d0           	 dd1lm}  |d23          }|rt          d4|            n2# t6          $ r%}t8                              d5|           Y d}~nd}~ww xY wt          d6           d}	 t          j
        |d7d8d|gz   t          d	d	          }|j        dk    rt          d9           t          j
        |d:d;d<| gz   t          d	d	          }|j        dk    rxt          d=| d>           |j                                        r)t          d|j                                                    t          d?           t          j        d           d	}|>|s#t          d@| dA           t          dB           n`t1          |t          |||,           nF# |?|s#t          d@| dA           t          dB           w t1          |t          |||,           w w xY wt/                       t=          t                    }|rt          dC| dD|dk    rdEndF            |r|d!k    rt?          |t                     t          dG           tA          j!        dH          }|r;i tD          j#        dItI          t          dJz            i}tK          |dKg|L           nt          j&        dMdKg}	 t          j
        |dNgz   t          d	d	           n@# t          j'        $ r. t          j
        t          j&        dMdOdPdQgt          d	R           Y nw xY wtK          |           tQ                       tS          t          dSz             t                       t          dT           	 ddl*}ddl+}|,                    |           n# t6          $ r Y nw xY w	 ddUl-m.} t                       t          dV            |d	W          }|dX         rAt          dYt_          |dX                    dZd[0                    |dX                               |1                    d\          rAt          d]t_          |d\                    d^d[0                    |d\                               |1                    d_          r&t          d`t_          |d_                    da           |1                    db          r&t          dct_          |db                    dd           |dX         s$|1                    d\          st          de           n2# t6          $ r%}t8                              df|           Y d}~nd}~ww xY w	 ddgl2m3} m4}!m5}"  |!            mmfdh |             D             }#|#r^t                       t          di           |#D ]=}$	  |"|$j6        d	W          }%|%rt_          |%1                    dXg                     }&t_          |%1                    d\g                     }'t_          |%1                    d_g                     }(g })|&r|)7                    dj|& dk           |'r|)7                    dl|' dm           |(r|)7                    dn|( do           |)rd[0                    |)          ndp}*ndq}*t          d|$j8         dr|*            # t6          $ r&}+t          d|$j8         ds|+ dA           Y d}+~+7d}+~+ww xY wn# t6          $ r Y nw xY w	 ddtl9m:},  |,            }-|-rt          du|- dv           n# t6          $ r Y nw xY wt                       t          dw           ddxl;m<}.m=}/m>}0m?}1  |.d	y          }2 |/            }3 |0            \  }4}5|2p|3p|4|5k     }6|6rt                       |2r t          dzt_          |2           d{           |3r t          d|t_          |3           d}           t                       |rt          d~           dE}7n|r5t          dd                                          A                                }7nt          j                                        rt          j                                        s!t          d           t          d           d}7nG	 t          d                                          A                                }7n# t          $ r d}7Y nw xY w|7dv rat                        |1|p| d          }8|8d         s|8d         rt                       t          d           |s|r|2rt          d           n-t                       t          d           nt          d           t                       t          d           	 t                       n2# t6          $ r%}t8                              d|           Y d}~nd}~ww xY w	 t                       n2# t6          $ r%}t8                              d|           Y d}~nd}~ww xY w|r8t                      dz  }9	 |9G                    d           n# t          $ r Y nw xY w	 ddlImJ}:mK};mL}<mM}=mN}>mO}?mP}@mQ}A ddlR}B	 ddt          dtH          dt          dt           fd}C	 ddt          dtH          dt          dt          fd}D	 ddl+mU}E n# t6          $ r d}EY nw xY wd}F	 ddl;mV}G  |G            1                    d          pi }H|H1                    d          }Fn# t6          $ r Y nw xY w	 |Ft          |F          nt          |E          }In&# t          t          f$ r t          |E          }IY nw xY wt          |Id          dz   }Ig }Jt                      ng }K |;            r)	  |<             n# t6          $ r Y nw xY wdddgfddgffD ] \  }L}M	 t          j
        |Mg dz   d	d	d          }|j                                                                        D ]}N|N[                                })|)s|)d         }O|O\                    d          s8|O]                    d          }Pt          j
        |Md|Pgz   d	d	d          }Q|Qj                                        dk    rd}R	 t          j
        |Md|Pddgz   d	d	d          }St-          |Sj        pd                                pd          }Rn$# t          t          j^        t          f$ r d}RY nw xY wd}T|Rdk    r0t          d|P dt-          |I           d            |A|R|I          }T|TrY |D|M|Pd          }Ut          d|Udz             }V |C|M|P|V          r|J7                    |P           yt          d|P d           t          j
        |Md|Pgz   d	d	d          }W|Wj        dk    r |C|M|Pd          r|J7                    |P           t          d|P d           t          j
        |Md|Pgz   d	d	d            |C|M|Pd          r*|J7                    |P           t          d|P d           At          d|P d|P d|Ldk    rdnd d|P            ft          d|P dr|Wj                                                    # t          t          j^        f$ r Y w xY w |:            r	 ddlIm`}Xma}Ymb}Z  |Z            }[|[                                rt          j
        dd |Y            gd	d	d          }Q|Qj        dk    r|	  |X             |J7                     |Y                       nS# t          j'        $ rA}t          |dd          pd                                }
t          d|
            Y d}~nd}~ww xY wn"# t          t          j^        t          f$ r Y nw xY w |@            }\ |=|\d	Ȧ          oofdɄ |>|\ʦ          D             }]|]d                                D ]\  }^}_ |?|_je        |^          s |A|^|I          }`|`s3	 tE          jf        |^|Bjg                   n# t          t          f$ r Y nw xY wnj                    |^           |K7                    |_je                   oD ]N}^|^|]v r	 tE          jf        |^|Bjg                   nj                    |^           8# t          t          f$ r Y Kw xY w|Jsnrt                       |JD ]}at          d|a            |Kr'd[0                    |K          }bt          d|b            t_          n          t_          |K          z
  }c|cr7t          d|c dΝ           t          dϦ           |cdk    rt          dЦ           |Jsns	 	 t          jl        dѦ            |@            }d |=|dd	Ȧ          }enfd҄|eD             }f|fryt                       t          dt_          |f           dӝ           |fD ]4}^	 tE          jf        |^|Bjm                   # t          t          f$ r Y 1w xY wt          jl        dԦ           n2# t6          $ r%}gt8                              d|g           Y d}g~gnd}g~gww xY wn2# t6          $ r%}t8                              d|           Y d}~nd}~ww xY w	 ddlImn}hmo}imK};  |;            r |h            rt                       t          dئ            |i            D ]"\  }j}k}l|lrdnd}Lt          d|k d|L d۝           #t                       t          dܦ           t          dݦ           t          dަ           t                       t          dߦ           t                       t          d           n2# t6          $ r%}t8                              d|           Y d}~nd}~ww xY wt                       t                       t          d           t          d           dS # t          j'        $ r}t          j        dk    r?t          d|            t          d           t                       t          |            n,t          d|            t          j        d           Y d}~dS Y d}~dS d}~ww xY w)uj   Body of ``cmd_update`` — kept separate so the wrapper can always
    restore stdio even on ``sys.exit``.rn   c                 "    t          | |          S rw   )rr  )r  r
   s     r   <lambda>z"_cmd_update_impl.<locals>.<lambda>=  s    OFG$D$D r   Nr0  Fu   ⚕ Updating Hermes Agent...rZ  r  Tu+   ✗ Not a git repository. Please reinstall:zg  curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bashr   )r  r  r  r  zwindows.appendAtomicallyfalser  r  r  u   ⚠ Updating from fork:r   u   → Fetching updates...rN  r.  r  r   r  r  r  r  r  r  u(   ✗ Failed to fetch updates from origin.)r  z--abbrev-refr   r~  r>  r   zdetached HEADzbranch 'rL  u     ⚠ Currently on u$    — switching to main for update...checkoutrB  zHEAD..origin/rC  )r  r"  )r>  r   u   ✓ Already up to date!u
   → Found z new commit(s))create_quick_snapshotz
pre-update)r  u     ✓ Pre-update snapshot: zPre-update snapshot failed: %su   → Pulling updates...rP  rQ  uP     ⚠ Fast-forward not possible (history diverged), resetting to match remote...r	  r  zorigin/u   ✗ Failed to reset to origin/rX  z@  Try manually: git fetch origin && git reset --hard origin/mainu1     ℹ️  Local changes preserved in stash (ref: r   z(  Restore manually with: git stash applyr  r  r
  r  r  r  r  rY  r  r  r  r  r  r  r  r  r  u   ✓ Code updated!r2  r  r4  r  r  r  r  r  r  r  r  r  r  r  r  r  r  z$Skills sync during update failed: %s)list_profilesget_active_profile_nameseed_profile_skillsc                 *    g | ]}|j         k    |S r   r?   )ry   r  r   s     r   r   z$_cmd_update_impl.<locals>.<listcomp>  s%    MMMAAFf<L<La<L<L<Lr   u/   → Syncing bundled skills to other profiles...+z newu   ↑z updated~z user-modifiedz
up to datezsync failedr[  z	: error ()sync_honcho_profiles_quietz
-> Honcho: synced z profile(s)u-   → Checking configuration for new options...)get_missing_env_varsget_missing_config_fieldscheck_config_versionmigrate_config)required_onlyu
     ⚠️  z+ new required setting(s) need configurationu
     ℹ️  z new config option(s) availableuG     ℹ --yes: auto-applying config migration (skipping API-key prompts).z2Would you like to configure new options now? [Y/n]r.  uC     ℹ Non-interactive session — skipping config migration prompt.zJ    Run 'hermes config migrate' later to apply any new config/env options.z-Would you like to configure them now? [Y/n]: r/  )interactiver5  	env_addedconfig_addedu   ✓ Configuration updated!u:     ℹ API keys require manual entry: hermes config migratez8Skipped. Run 'hermes config migrate' later to configure.u!     ✓ Configuration is up to dater  r  zFHS PATH guard check failed: %sz.update_exit_code0)is_macossupports_systemd_services_ensure_user_systemd_envfind_gateway_pidsfind_profile_gateway_processes'launch_detached_profile_gateway_restart_get_service_pids_graceful_restart_via_sigusr1      $@
scope_cmd_	svc_name_r3  r   c                 \   t          j                    t          |d          z   }	 	 t          j        | d|gz   ddd          }|j                                        dk    rdS n# t          t          j        f$ r Y nw xY wt          j                    |k    rdS t          j	        d           )az  Poll ``systemctl is-active`` until the unit reports active.

                systemd's Stopped -> Started transition after a graceful exit
                (or a hard restart) is not instantaneous; a one-shot check
                races that window and falsely reports the unit as down.
                Poll every 0.5s up to ``timeout`` seconds before giving up.
                rb  T	is-activer   r0  r   F)
ra   rh  r   r4  r5  r  r3   r8   r6  ri  )r  r  r3  rp  _verifys        r   _wait_for_service_activez2_cmd_update_impl.<locals>._wait_for_service_active*  s     !?,,s7C/@/@@%",.&+y)AA+/dA# # # #>//11X==#'4 >-z/HI   ((H44$uK$$$%s   :A$ $A=<A=        r
   c           
         	 t          j        | d|ddgz   ddd          }n# t          t           j        f$ r |cY S w xY w|j        pd                                }|r|dk    r|S d	}d
}|                                D ]`}dD ][\  }}	|                    |          rA	 |t          |dt          |                              |	z  z  }d}n# t          $ r Y nw xY w n\a|r|n|S )a  Read the unit's ``RestartUSec`` (RestartSec) in seconds.

                After a graceful exit-75, systemd waits ``RestartSec`` before
                respawning the unit.  Callers that poll for ``is-active``
                must use a timeout >= ``RestartSec`` + transition slack, or
                they'll give up *during* the cooldown window and wrongly
                conclude the unit didn't relaunch.
                r1  z--property=RestartUSec--valueTr   r0  rn   infinityr  F))msgMbP?)usgư>)r         N@)r   g      ?N)r4  r5  r8   r6  r  r3   r,   r  floatr*   r7   )
r  r  r
   _showrawrO  matchedr  _suf_mults
             r   _service_restart_secz._cmd_update_impl.<locals>._service_restart_secC  sZ   	#&N""I4i&  (,$  EE *:+DE # # #"NNN#|)r0022  #cZ//"NIIKK " "D( " "e  ==.. "% %tLs4yyjL/A)B)BU)J J*.#- % % % $%!E" !(4uuW4s   " ==-C


CC)%DEFAULT_GATEWAY_RESTART_DRAIN_TIMEOUTr  rR   rI  restart_drain_timeoutg      >@r  user	systemctlz--usersystem)z
list-unitszhermes-gateway*z--plainz--no-legendz
--no-pagerr   r0  z.servicer	  r   r   r1  z--property=MainPIDr  u     → z: draining (up to zs)...)drain_timeoutr  )r3  r  u0    drained but didn't relaunch — forcing restartrestartr/  z  died after restart, retrying...rt  z recovered on retryrm  zL failed to stay running after restart.
    Check logs: journalctl --user -u z5 --since '2 min ago'
    Restart manually: systemctl z--user zrestart u     ⚠ Failed to restart )launchd_restartget_launchd_labelget_launchd_plist_path	launchctlr   r   u     ⚠ Gateway restart failed: )exclude_pidsall_profilesc                 2    i | ]}|j         v |j         |S r   )r  )ry   procmanual_pidss     r   r  z$_cmd_update_impl.<locals>.<dictcomp>J  s4     ! ! !8{** $***r   )r%  u     ✓ Restarted u,     ✓ Restarting manual gateway profile(s): u     → Stopped z manual gateway process(es)z(    Restart manually: hermes gateway runz;    (or: hermes -p <profile> gateway run  for each profile)r  c                     g | ]}|v |	S r   r   )ry   r  killed_pidss     r   r   z$_cmd_update_impl.<locals>.<listcomp>  s#    JJJ#sk7I7I#7I7I7Ir   u6    gateway process(es) ignored SIGTERM — force-killingg      ?z&Post-restart survivor sweep failed: %sz(Gateway restart during update failed: %s)has_legacy_hermes_units_find_legacy_hermes_unitsr  u+   ⚠ Legacy Hermes gateway unit(s) detected:r  z  (z scope)z;  These pre-rename units (hermes.service) fight the currentz<  hermes-gateway.service for the bot token and cause SIGTERMz  flap loops. Remove them with:z!    hermes gateway migrate-legacyz)  (add `sudo` if any are in system scope)z*Legacy unit check during update failed: %sz-Tip: You can now select a provider and model:z7  hermes model              # Select provider and modelu   ⚠ Git update failed: u#   → Falling back to ZIP download...u   ✗ Update failed: rn   )r  )r  )qr  rG  r   r  r  r1   r   r  r   r4  r5  r0  r7  r  rL  r   r3   r   r  r  r   r   rc   r]  r&  rA  r  r9   r  r  r]  rU  rJ  rK  r-   r.   r   r  r  r  r  r  	importlibr0   reloadrK  r3  r*   rM  r/   r6   r  r  r  rc  r  r?   plugins.memory.honcho.clir  r   r  r  r  r  rr  r   r  r  r  r  rE   rf  r5   rY  r  r  r  r   r  r  r  r  r  r   r  r  rS   	TypeErrorr7   r   r  r,   r  removesuffixr6  r8   r!  r"  r#  r  r   profiler  r  r  r  r  ra   ri  r  r,  r-  r  )prL  r  gw_input_fn
assume_yesuse_zip_updater  r  r1  is_forkr  r   r  current_branchr  r  auto_stash_refprompt_for_restorecommit_countr  snap_idrA   update_succeededpull_resultreset_resultr5  r  r  r  r/  _hcr3  rU  r  r  r  other_profilesr  r  r  r  modifiedr  r   per  syncedr  r  r  r  missing_envmissing_configcurrent_ver
latest_verneeds_migrationrx  results_exit_code_pathr  r  r  r   r  r  r  r  r  r  r  _DEFAULT_DRAIN
_cfg_drainrS   
_cfg_agent_drain_budgetrestarted_servicesrelaunched_profilesr  	scope_cmdr   r  svc_namer  	_main_pidr  _graceful_ok_restart_sec_post_drain_timeoutr   r!  r"  r#  
plist_pathservice_pidsprofile_processesr  r(  drainedsvcnamesunmapped_count_service_pids_after
_surviving_stuck
_sweep_excr,  r-  r?   rc  is_sysr   r+  r)  sp                                                                                                                @@@r   r  r  8  s!    		D	D	D	D 
 gdE51122J	
()))	GGG 4    NV#G>> <7""!NN?@@@y   HQKKK |w7>>#3#3   	
 	
 	
 	
 gG
|wAAA !,77Jz""G '(((:    X'(((!~w))	
 
 
 "a''!(..00F'6115G65Q5QQRRRvE36,,..q13332FFFF'6115NRX5X5XZ    ABBB 97v00221577888HQKKK ;;;;
 
 
  ,,..  V## "V++  1111 
 SSSSTTT;G\RRNN:v.. #     <G\RRN $& OOM#)"2"2"4"4"L9J9J9L9L 	 z#;6#;#;YGG
 
 
 6=..00111$&&&)( " 2(    %555z>::$#'    +,,,F7<777888	@??????++,???G ?=G==>>> 	@ 	@ 	@LL93????????	@ 	&''' -	$.6;&AA #	  K %** f    *~w2DF2D2DEE$#'	       *a//D6DDDEEE#*0022 B@<#6#<#<#>#>@@AAAZ   HQKKK#) ( ]N]]]   EFFFF,$&$6!,    ) ( ]N]]]   EFFFF,$&$6!,     *" 	!"""
 (55 	eeeGWXLLSS^cee  
  	Av'')'<@@@
 	3444d## 	IN
NM3|f7L3M3MNNF?V     ~tU3G{m+$#'	     0   ^T;_U$      @HHH!###lU*+++!"""	****S!!!! 	 	 	D		D555555GGG1222 [t,,,Fh YWS!122WW$))F8DT:U:UWWXXXzz)$$ ]S	!233]]tyyPYIZ?[?[]]   zz/** RPS!899PPPQQQzz)$$ OMs6)#455MMMNNN(# 5FJJy,A,A 53444 	D 	D 	DLL?CCCCCCCC	D!	          -,..FMMMMMMMN ;GHHH' ; ;A;//dCCC 3%(x)<)<%=%=F&)!%%	2*>*>&?&?G'*155"+E+E'F'FH$&E% ? %-=-=-=-= > > >& F %-D7-D-D-D E E E' K %-I-I-I-I J J J9>%PTYYu%5%5%5LFF%2F51655V556666$ ; ; ;91699B999::::::::; 	 	 	D		LLLLLL//11F B@V@@@AAA 	 	 	D	 	=>>>	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 +*>>>2244"6"6"8"8Z%SS;;S 7	7GGG ^[!1!1^^^    YW3~#6#6WWWXXXGGG #_``` ##Lc  UWWUWW  i&&(( #SZ->->-@-@ #[\\\`   #MNN H
   # # #"HHH# +++ ).%1%?Z @   ;' 87>+B 8GGG6777  XJ XK XVWWWPQQQQ5666$%%%	C+---- 	C 	C 	CLL>BBBBBBBB	C
	?"$$$$ 	? 	? 	?LL:A>>>>>>>>	?&  	-//2EEO**3////   G	H	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 %$$$ DH% % %-0%;@%% % % %4 DG*5 *5 *5-0*5;@*5*5 *5 *5 *5d&        & & &!%&J999999)kmm//88>B
'^^,CDD

   65?5Kj 1 1 1QVWeQfQfz* 6 6 6 %n 5 56  t44t;M!#%%K"$ )(** U,,....    D k845}-) O O$E9K!+%   ,0!%$&" " " %+M$7$7$9$9$D$D$F$F {" {"D$(JJLLE#( ) (#( !$D $(==#<#< ) ('+'8'8'D'DH$.N )[(,C C/3%)()	% % %E  %|1133x?? ( )*I
.(2$-(.(<i1& %& 48dA)" )" )" -01C0J0J0L0L0QPQ,R,R		$.
0IK\#] . . .,-			. ,1L(1}} %$bX$b$b]I[I[$b$b$b!" !" !" 0M/L$-]0" 0" 0"  , " 0D/C$-x0" 0" 0" 7:$(,*=7" 7" 3 $<#;$-x,?$" $" $" !- %7$=$=h$G$G$G$,
 !&$gX$g$g$g!" !" !" '1n )Y,A A/3%)(*	' ' 'G  '1Q66 $<#;$-x$" $" $" !* %7$=$=h$G$G$G$G
 %*([([([([%& %& %& %/N(1Y4I(I7;-102	%& %& %& %& (@'?(18T(& (& (& 
%* );(A(A((K(K(K(-.Tx.T.T.T(U(U(U(U(--HX -H -HT\-H -H\aek\k\kyyqs-H -H ~F-H -H)* )* )* )* !&$cx$c$c7>K_K_KaKa$c$c!" !" !" !"s{"x .z/HI    xzz           "8!7!9!9J!((** Q *(&2C2C2E2EF+/!%$%	! ! ! !+q00Q / 1 1 1 2 9 9:K:K:M:M N N N N#-#@ Q Q Q*1!Xr*B*B*Hb)O)O)Q)Q %&Ov&O&O P P P P P P P PQ *:+DkR   D -,..L++)  K! ! ! !::UUU! ! !
 /4466 9 9	T>>t|SQQ  87}    W_5555.@   $$$#**4<8888"  +++GC111OOC((((*O<   D " [ - 4 4C2S223333& R II&9::EPPPQQQ!$[!1!1C8K4L4L!L! V>VVVWWWDEEE%))Y   & k SC   &7&7&9&9#..!44  
 KJJJJJJ %GGGdVddd    & ! !!GC9999 2OD ! ! ! D! K$$$ S S SEzRRRRRRRRS  	H 	H 	HLLCQGGGGGGGG	H	J          )(** C/F/F/H/H CCDDD*C*C*E*E : :&D$(.:HHFE888%8889999STTTTUUU78889:::ABBB 	J 	J 	JLLEqIIIIIIII	J 	()))=>>>GHHHHH(   <7""/A//0007888GGGD!!!!+++,,,HQKKKKKKKKK "!!!!!s  >J,A_2 ,A_2  &Q' &A_2 '
R1RA_2 RA_2 +C)W AA_2 AXCA_2 )!\ 
A_2 :]A_2 ]AA_2 ^; :A_2 ;
_A_2 _A_2 E0d= <A_2 =
e,e'"A_2 'e,,A_2 0Ak<  Dkk< 
k8k3-k< 3k88k< ;A_2 <
l	A_2 l		A_2 %l3 2A_2 3
m =A_2 ?m  E$A_2 %3s A_2 s(%A_2 's((B2A_2 v* )A_2 *
w4wA_2 wA_2 w, +A_2 ,
x6xA_2 xA_2 2y A_2 
yA_2 yA_2 AAY3 6z= <AY3 ={	AY3 {AY3 :| AY3 
|AY3 |AY3  |? >AY3 ? }"AY3 !}""3AY3 
~!  AY3 !
~.+AY3 -~..AY3 CAJ!BA	AC CAJ!C ADC>AJ!D ADDFAJ!JAY3 J!AJ;J7AY3 J:AJ;J;AY3 K	AAN L 'AM MAN MANM7ANNAN NANNAN NAY3 NAN;N8AY3 N:AN;N;A,AY3 P(AQQAY3 QAQQAY3 QAQQ<AY3 R/ASSAY3 SASSAY3 SASSB2AY3 VA-AY  W9AXXAY  XAX(X%AY  X'AX(X(AY  X?AY3 Y 
AY/Y
AY*Y%AY3 Y*AY/Y/AY3 Y2A_2 Y3
AZ"Y=AZZA_2 ZAZ"Z"A_2 Z&CA^ ^A_2 ^
A^3^A^.^)A_2 ^.A^3^3=A_2 _2Ab`A5AbbAbr(   c                 h   h d}h d}g }d}|t          |           k     r| |         }||v r|                    |           |dz  }g }|t          |           k     r}| |                             d          sb| |         |vrX|                    | |                    |dz  }|t          |           k     r%| |                             d          s
| |         |vX|r(|                    d                    |                     n|                    |           |dz  }|t          |           k     |S )a  Join unquoted multi-word session names after -c/--continue and -r/--resume.

    When a user types ``hermes -c Pokemon Agent Dev`` without quoting the
    session name, argparse sees three separate tokens.  This function merges
    them into a single argument so argparse receives
    ``['-c', 'Pokemon Agent Dev']`` instead.

    Tokens are collected after the flag until we hit another flag (``-*``)
    or a known top-level subcommand.
    >#   acpr  r   chatclawcrondumpr  r  loginrm   setuptoolsr  r  doctorhonchoimportlogoutmemoryr?  r   r   r  pairingpluginsr4  rM  webhookinsightsr   r]  	dashboardrS  
completion>   -r
--continuer  --resumer   r   r  r   )r*   r  r+   rM  )r(   _SUBCOMMANDS_SESSION_FLAGSr  r<   r}  r  s          r   _coalesce_session_name_argsr~    sY   $ $ $LJ <;;NF	A
c$ii--QN""MM%   FAECIIQ**3// G<//T!W%%%Q CIIQ**3// G<//  /chhuoo...MM%   FA% c$ii--& Mr   c                    ddl m}m}m}m}m}m}m}m}m	}	m
}
m} ddlm} t          | dd          }| |            } |            }t          d|            t          d|             |            }|D ]}|j        |k    s|dk    r|j        r|j        r,t          d	|j         |j        rd
|j         dndz              t          d|j        rdnd            t          d|j         d           |j        rt          d|j         d|j                     nt                       dS |dk    r |            } |            }|st          d           dS t          ddddddddddd            t          dd d d! d d" d d#            |D ]y}|j        |k    s|dk    r	|j        rd$nd%}|j        }|j        pd&dd'         }|j        rdnd}|j        r|j        nd&}|j        rd&}t          | |d(d|dd|dd|            zt                       dS |d)k    r| j        }	  ||           |dk    rt          d*           nt          d+|            dS dS # t0          t2          f$ r1}t          d,|            t5          j        d-           Y d}~dS d}~ww xY w|d.k    ra| j        }t          | d/d0          }t          | d1d0          }t          | d2d0          }	 t          | d3d          } ||||||4          }t          d5| d6|            |s|rDt          | d3d          p	 |            }|rt          d7| d8           nt          d9| d8           |s|r6	 dd:lm}  ||          rt          d;| d           n# t<          $ r Y nw xY w|se ||          } | r6t?          |                      d<g                     }!t          |! d=           n"t          d>!                    |                     |s ||          }"|"r<t          d?| d@|"            t          dA| dB           t          dC| dD           nb ||          }#|#rUt          dE|#             |
            s9t          dF |             dG           t          dH           t          dI           	 dJtE          |#                    tI          j%                                        z   }$n# t0          $ r tE          |          }$Y nw xY wt          dK           t          d%| dL           t          d%| dM           t          d%| dN           |s|r't          dO|$ dP           t          dQ|$ dR           n5t          dS| dT           t          dU           t          dQ|$ dV           t                       dS # t0          tL          t2          f$ r1}t          d,|            t5          j        d-           Y d}~dS d}~ww xY w|dWk    rm| j        }t          | dXd0          }%	  |||%Y           dS # t0          t2          f$ r1}t          d,|            t5          j        d-           Y d}~dS d}~ww xY w|dZk    rz| j        }dd[l m'}&m(}'m)}(m*})m+}*  |'|          s't          d\| d]           t5          j        d-            |&|          } |(|          \  }}+ |)|          } |*|          }, |            |z  }-t          d^|            t          d_|            |rt          d`| |+rd
|+ dndz              t          da|rdnd            t          db|,            t          dc|ddz  ,                                rdendf            t          dg|dhz  ,                                rdendf            |-,                                rt          di|-            t                       dS |djk    r4| j        }t          | dkd0          }.t          | dld          }/ddml m(}'  |'|          s't          d\| d]           t5          j        d-           |/p|}0|.r5 |	|0          rt          dn|0 do           dS t          dp|0 dq           dS  ||0          }"|"r&t          d,|"            t5          j        d-            ||0          }#|#rT|/r|#-                    dr| ds           t          dt|#             |
            st          du |             dG           dS dS dS |dvk    rddwl m.}1 	  |1| j/        | j0                  }2t          dx| j/         dy| j0                    t          dz|2 d{           dS # t0          tL          t2          f$ r1}t          d,|            t5          j        d-           Y d}~dS d}~ww xY w|d|k    rdd}l m1}3 | j        }| j2        p| d~}4	  |3||4          }5t          d| d|5            dS # t0          t2          f$ r1}t          d,|            t5          j        d-           Y d}~dS d}~ww xY w|dk    rddl m3}6 	  |6| j4        t          | dd                    }|j        }t          d| d|             ||          }"|"s ||          }#|#rt          d|#            t                       dS # t0          tL          t2          f$ r1}t          d,|            t5          j        d-           Y d}~dS d}~ww xY wdS )u;   Profile management — create, delete, list, switch, alias.r   )r  create_profiledelete_profiler  set_active_profiler  check_alias_collisioncreate_wrapper_scriptremove_wrapper_script_is_wrapper_dir_in_path_get_wrapper_dirr  profile_actionNz
Active profile: zPath:           r
   zModel:          r  r   rn   zGateway:        runningstoppedzSkills:         z
 installedzAlias:          u    → hermes -p r   zNo profiles found.z
 Profilez<16r   Modelz<28Gatewayz<12Aliasu-   ───────────────r  uQ   ───────────────────────────u!   ───────────u$   ────────────u    ◆r      —   z<15usez Switched to: default (~/.hermes)zSwitched to: r'   r   createcloneF	clone_allno_alias
clone_from)r?   r  r  clone_configr  z

Profile 'z' created at zFull copy from rX  z.Cloned config, .env, SOUL.md, and skills from )clone_honcho_for_profilezHoncho config cloned (peer: r  z bundled skills synced.u9   ⚠ Skills could not be seeded. Run `{} update` to retry.u   
⚠ Cannot create alias 'u   ' — z/  Choose a custom alias:  hermes profile alias z --name <custom>z$  Or access via flag:     hermes -p z chatzWrapper created: u   
⚠ z is not in your PATH.z3  Add to your shell config (~/.bashrc or ~/.zshrc):z(    export PATH="$HOME/.local/bin:$PATH"z~/z
Next steps:z0 setup              Configure API keys and modelz" chat               Start chattingz/ gateway start      Start the messaging gatewayz
  Edit z/.env for different API keysz  Edit z"/SOUL.md for different personalityu.   
  ⚠ This profile has no API keys yet. Run 'z setup' first,z8    or it will inherit keys from your shell environment.z!/SOUL.md to customize personalitydeleter0  )r0  r1  )get_profile_dirprofile_exists_read_config_model_check_gateway_running_count_skillszError: Profile 'z' does not exist.z

Profile: z	Path:    z	Model:   z	Gateway: z	Skills:  z	.env:    rG   r1   znot configuredz	SOUL.md: zSOUL.mdz	Alias:   aliasremove
alias_name)r  u   ✓ Removed alias 'rL  z
No alias 'z' found to remove.z#!/bin/sh
exec hermes -p z "$@"
u   ✓ Alias created: u   ⚠ rename)rename_profilez
Profile renamed: r   zPath: r  export)export_profilez.tar.gzu   ✓ Exported 'z' to rp  )import_profileimport_namer  u   ✓ Imported profile 'z' at z  Wrapper created: )5r6   r  r  r  r  r  r  r  r  r  r  r  r0   r  rG  r   r?   
is_defaultrm   r   gateway_runningskill_count
alias_pathr:   r7   r8   r   r   r1  r  r9   r*   r/   formatr   r  r   r  FileExistsErrorr  r  r  r  r  r1   rf  r  old_namenew_namer  outputr  archive)7rL  r  r  r  r  r  r  r  r  r  r  r  r  r	   r:   dhhrW  r  r   r  r?   rm   gwr  rU  r  r  r  r  profile_dirsource_labelr  r  r  	collisionwrapper_pathprofile_dir_displayr0  r  r  r  r  r  r   r?  r  r  custom_namer  r  new_dirr  r  result_pathr  s7                                                          r   cmd_profiler  #  s{                             544444T+T22F~..00!!##1<11222&&&''' =?? 	 	Av%%,)*C*C*C7 4174412C-
----E   VA4E'Tyy9VV   BBBBCCC< NLQVLLAFLLMMM =??((** 	&'''F 	KIKKKGKKK)KKK'KKLLLN*NN*NN*NN*NNOOO 	F 	FA Ff$$9)<)<)<  
 6DW%ss+E/>YBl5AFFE| VDTDDDDDDBDDDUDDEEEE	5 	t$$$y  9::::,d,,----- ;: -. 	 	 	-A--   HQKKKKKKKKK	 
8		 gu--D+u55	4U33X	 |T::J(.%#"!  K @@@;@@AAA \	 \D,55R9P9P9R9R   \;L;;;<<<<Z<ZZZ[[[  	 RRRRRR//55 FDTDDDEEE    D  
,,[99  Hb!9!9::FV<<<====SZZ      O11$77	 OOOOIOOPPP`$```   LLLLMMMM#8#8#>#>L# O@,@@AAA6688 O!"T+;+;+=+="T"T"TUUU! V   ""MNNN7&*S1H1H1U1U-V-V&V## 7 7 7&)+&6&6###7 "###MtMMMNNN?t???@@@LtLLLMMM X	 XS"5SSSTTTW 3WWWXXXXZdZZZ   QRRRV 3VVVWWWGGGGGO->? 	 	 	-A--   HQKKKKKKKKK	 
8		 dE5))	N4S))))))-. 	 	 	-A--   HQKKKKKKKKK	 
6		 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 ~d## 	<T<<<===HQKKK%od++,,[99x##K00{++""$$t+"D""###'+''((( 	P%e%%X)M)9h)9)9)9)92NOOO:r8))y::;;;"&""###[[6%9$A$A$C$CYIY[[	
 	
 	
 	^[9%<$D$D$F$F\L\^^	
 	
 	
 >> 	)'g''(((	7		 x//dL$77666666~d## 	<T<<<===HQKKK (D
 	L$$Z00 C9J999:::::A:AAABBBBB--j99I +	++,,,00<<L L X ++,V,V,V,VWWW:L::;;;..00 LJ!1!1!3!3JJJKKKKKL L
L L 
8		666666	$nT]DMBBGKKKDMKKLLL&7&&&'''''O->? 	 	 	-A--   HQKKKKKKKKK	 
8		666666 04 0 0 0	(.v66K;4;;k;;<<<<<-. 	 	 	-A--   HQKKKKKKKKK	 
8		666666	(.74#E#E  K #DC4CCkCCDDD .-d33I @44T:: @>>>???GGGGGO->? 	 	 	-A--   HQKKKKKKKKK	# 
	s   13I( (J*9&J%%J*/BW
 2$N W
 
N$!W
 #N$$DW
 <6S3 2W
 3TW
 TB9W
 
X!&XX4Y Z&Z  ZAf g#2&gg#!h) )i+:&i&&i+;A7k4 4l<&l77l<c                     t                      } | st          d           dS t          t          |            d           | D ]}d}	 t          j        dk    rd| d}t
          j                            |          rwt          |d          5 }|	                                
                    d	d
                              dd                                          }ddd           n# 1 swxY w Y   n# t          t          f$ r Y nw xY w|rt          d| d|            t          d|            t          |           S )a:  Print ``hermes dashboard`` PIDs and return the count.

    Uses the same detection logic as ``_find_stale_dashboard_pids`` (the
    current process is excluded, but since ``hermes dashboard --status``
    runs in a short-lived CLI process that never matches the pattern,
    the exclusion is irrelevant here).
    &No hermes dashboard processes running.r   z& hermes dashboard process(es) running:rn   r  z/proc/z/cmdliner_          rJ   rn  r  Nz    PID r[  )r  r   r*   r   r  r-   rc  r1   re  readrn  decoder3   r5   r7   )r  r  cmdlinecmdline_pathr  s        r   _report_dashboard_statusr  O  s    &''D 6777q	SYY
>
>
>??? $ $	|w&&55557>>,// ?lD11 ?Q"#&&(("2"27D"A"A"H"H#I #I #7 #77<uww  ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? $ 	 	 	D	 	$-S--G--...."S""####t99s8   AC5AC)C5)C-	-C50C-	1C55D	D	c           
         t          | dd          r*t                      }t          j        |dk    rdnd           t          | dd          rit	                      }|s#t          d           t          j        d           t          d           t	                      }t          j        |rdnd           	 dd	l}dd	l}nq# t          $ rd}t          d
           t          dt           dt          j         d           t          d|            t          j        d           Y d	}~nd	}~ww xY wdt          j        vr-t          t          dz  d          st          j        d           ddlm} | j        p"t          j                            d          dk    } || j        | j        | j         t          | dd          |           d	S )zGStart the web UI server, or (with --stop/--status) manage running ones.r   Fr   stopr  zrequested via --stop)r  r   Nz;Web UI dependencies not installed (need fastapi + uvicorn).zMRe-install the package into this interpreter so metadata updates apply:
  cd z
  zP -m pip install -e .
If `pip` is missing in this venv, use:  uv pip install -e .zImport error: HERMES_WEB_DISTr  Tr  )start_serverHERMES_DASHBOARD_TUIr  r  )hostportopen_browserallow_publicembedded_chat)rG  r  r   r   r  r   r  fastapiuvicornr  r  r  r-   r.   r  hermes_cli.web_serverr  rj  r/   r  r  no_open)	rL  r&  r  	remainingr  r  rU  r  r  s	            r   cmd_dashboardr  p  s     tXu%% )(**eqjja((( tVU## 
()++ 	:;;;HQKKK'/EFFFF /00	i&Q''' 	 	 	KLLLJ J JJ J J	
 	
 	
 	"q""###	 
**\E1>>> 	HQKKK222222HM
/E F F# MMLYY%T:u55#     s   7C   
D.
AD))D.c                     ddl m}m}m} t	          | dd          }|dk    rt           ||                     dS |dk    rt           ||                     dS t           ||                     dS )zPrint shell completion script.r   )generate_bashgenerate_zshgenerate_fishshellr  zshfishN)hermes_cli.completionr  r  r  rG  r   )rL  r   r  r  r  r  s         r   cmd_completionr    s    PPPPPPPPPPD'6**E~~ll6""#####	&mmF##$$$$$mmF##$$$$$r   c                 8   ddl m}m} t          | dd          pd}|dk    r |             dS  ||t          | dd          t          | d	d
          t          | dd          t          | dd          t          | dd          t          | dd                     dS )z!View and filter Hermes log files.r   )tail_log	list_logslog_namerI  r   Nlinesr  followFlevelr`  since	component)	num_linesr  r  r`  r  r  )hermes_cli.logsr  r  rG  )rL  r  r  r  s       r   cmd_logsr    s    33333333tZ11<WH6	H$,,tXu--dGT**i..dGT**$T22     r   c                  g   ddl m}   |             \  }}|                    t                     |                    ddd          }|                    dd	
           |                    dd
           |                    ddd           |                    ddd           |                    ddd           |                    dt          dd           |                    dd
           |                    ddd           |                    t                     ddlm	} |                    d d!d"          }|
                    d#$          }|                    d%d&gd'(           |                    d)d*
           |                    d+d,gd-(           |                    d.d/
           |                    |           |                    d0d1d2          }|
                    d3$          }|                    d4d5
          }	|	                    d6d7d8dd9:           |	                    d;d<dd=           |	                    d>dd?           t          |	           t          |           |                    d@dA
          }
|
                    dBddC           |
                    dDddE           |                    dFdG
          }|                    dBddC           |                    dDddH           |                    dIdJ
          }|                    dBddC           |                    dDddK           |                    dLdM
          }|                    dNddO           |                    dPdQddR           |                    dBddC           |                    dSdT
          }|                    dUddV           |                    dBddW           |                    dXdYdZ[           |                    d\d]
          }|                    dBddC           |                    d^d_
           |                    d`dadb          }|                    dcddddef           |                    dgdhdiddjf           |                    t                     |                    d^dkdl          }|                    dmdng doddpq           |                    drdds           |                    dtddu           |                    dvddw           |                    dxddy           |                    t                     |                    dzd{d|          }|                    t                     |                    d}d~d          }|
                    d$          }|                    ddd          }|                    ddndddd           |                    ddd           |                    ddd           |                    ddd           |                    t                     |                    ddd          }|                    dddgdd           |                    dd
           |                    dd
           |                    ddd           |                    ddd           |                    ddd           |                    dt          dd           |                    dd
           |                    ddd           |                    t                      |                    ddd          }|                    dg ddd           |                    t"                     |                    dd
          }|
                    d$          }|                    d)d
          }|                    dd
           |                    ddg dd           |                    dd
           |                    dd
           |                    dd
           |                    dd
           |                    dd
           |                    dd
           |                    ddd           |                    dt          d           |                    ddd           |                    dd
           |                    d%d
          }|                    ddnd           |                    d+d
          }|                    dd
           |                    dd¬
           |                    ddĬ
          }|                    dd
           |                    dLdŬ
          }|                    dd
           |                    ddƬ
          }|                    dd
           |                    ddȬ
          } |                     ddng dʢd˦           |                     dd̬
           |                     ddά
           |                     ddϬ
           |                     ddd           |                     dt          dЬ           |                    t$                     |                    dLddҬ          }!|!                    dDddӬ           |!                    dNddԬ           |!                    t&                     |                    ddd׬          }"|"
                    dج$          }#|#                    d%d٬
          }$|$                    dDddڬ           |#                    dd)gdܬ(          }%|%                    ddެ
           |%                    ddndା           |%                    dd
           |%                    dd
           |%                    dt(          d嬹           |%                    ddddf           |%                    dd
           |%                    dd
           |#                    dd
          }&|&                    dd
           |&                    dd
           |&                    dd
           |&                    dd
           |&                    dd
           |&                    dt(          d           |&                    ddddf           |&                    ddddf           |&                    ddddf           |&                    d dd           |&                    dd
           |&                    dd
           |#                    dd
          }'|'                    dd
           |#                    dd
          }(|(                    dd	
           |#                    d4d

          })|)                    dd
           t          |)           |#                    d+d,dgd(          }*|*                    dd
           |#                    dLd
           |#                    dd
          }+t          |+           t          |"           |"                    t*                     |                    ddd          },|,
                    d$          }-|-                    dd)gd(          }.|.                    dd
           |.                    ddd           |.                    ddd           |.                    ddd           |.                    ddd            |.                    dd!d"           |.                    d#dd$           |.                    d%dd&           |.                    d'dd(           |-                    d%d&gd)(           |-                    d+d,gd*(          }/|/                    dd+
           |-                    d,d-
          }0|0                    dd.
           |0                    d/dd0           |,                    t,                     dd1lm}1  |1|          }2|2                    t2                     |                    d2d3d4          }3|3
                    d5$          }4|4                    d%d&gd6(           |4                    d,d7
          }5|5                    d8d9
           |5                    d:d;dd<=           |5                    d>d?dd@=           |4                    dAd+d,gdB(          }6|6                    dCdD
           |4                    dEdF
           |3                    t4                     |                    dEdGdH          }7|7                    dIddJ           |7                    t6                     |                    dKdLdM          }8|8                    dNddO           |8                    t8                     |                    dPdQdRt:          j        dST          }9|9
                    dU$          }:|:                    dVdW
          };|;                    dXt(          dYdZ           |;                    d[t(          d\d]           |;                    d^dd_           |:                    dd`
          }<|<                    dadbg dcd           |9                    t>                     |                    dedfdg          }=|=                    dhdidj
           |=                    d;dxddk           |=                    dPddl
           |=                    t@                     |                    dmdndo          }>|>                    dpdq
           |>                    dUdrdds           |>                    tB                     |                    dtdudv          }?|?
                    dw$          }@|@                    dxdy
           |@                    ddz
           |@                    d{d|
          }A|A                    d}dnd~           |A                    ddnd           |@                    dd
           |@                    dd
           |@                    dd
           |@                    dd
           |?                    tD                     |                    ddd          }B|B
                    d$          }C|C                    d%d
           |C                    dd
          }D|D                    dd
           |D                    dd
           |C                    dAd
          }E|E                    dd
           |E                    dd
           |C                    dd
           d }F|B                    |F           |                    ddd          }G|G
                    d$          }H|H                    dd
          }I|I                    dt(          dd           |I                    dt(          dd           |I                    ddg dd           |H                    dd
          }J|J                    dd
           |J                    ddg d           |J                    dt(          dd           |H                    dSd
          }K|K                    dd
           |K                    ddd           |K                    ddd           |K                    dUdd           |K                    dhdgdd           |H                    dd
          }L|L                    dd
           |H                    d%d
          }M|M                    ddg d           |M                    ddd           |H                    dd¬
          }N|N                    ddndì           |H                    dĐdŬ
          }O|O                    ddndƬ           |H                    dǐdȬ
          }P|P                    ddndɬ           |H                    d\dʬ
          }Q|Q                    ddˬ
           |H                    dÐd̐dͬ          }R|R                    ddά
           |R                    dddЬ           |R                    dhdgddѬ           |H                    dҐdӬ
          }S|S                    dԐdլ
           |S                    d֐dאdאdgdِ           |S                    dڐdd۬           |H                    dܐdݬ
          }T|T
                    dެ$          }U|U                    dߐd
          }V|V                    dd
           |U                    dmd
          }W|W                    dd
           |W                    dUdd           |H                    dd
          }X|X
                    d$          }Y|Y                    d%d
           |Y                    d)d
          }Z|Z                    dd
           |Y                    d+d
          }[|[                    dd
           |H                    dtd
           d }\|G                    |\           |                    ddd          }]|]
                    d$          }^|^                    dSd
          }_|_                    dd
           |_                    dUdrdd           |_#                                }`|`                    ddd           |`                    ddd           |^                    dĐd
          }a|a                    dd
           |^                    d+d,d\gd(          }b|b                    dd 
           |^                    d%d&gd(           |^                    dd
          }c|c                    dd
           |^                    dd
          }d|d                    dd
           d }e|]                    |e           	 dd	l$m%}f  |f            D ]e}g|                    |gd         |gd
         |g&                    dd          tO          d          j                  }h |gd         |h           fnE# tP          $ r8}itS          j*        tV                    ,                    d|i           Y d}i~ind}i~iww xY w|                    ddd          }j	 ddl-m.}k  |k|j           nE# tP          $ r8}itS          j*        tV                    ,                    d|i           Y d}i~ind}i~iww xY w|                    ddd          }l|l
                    d$          }m|m                    d^d
           |m                    dLd
           |m                    dd
           |m                    dÐd
          }n|n                    dhdgdd           |n                    dg d dd!           d" }o|l                    |o           |                    d#d$d%          }p|p                    d&dd'           |p
                    d($          }q|q                    d%d)
          }r|r                    d*d+d,           |q                    dd-
          }s|s                    d.d/d0d12           |s                    d*d+d3           |q                    dd4
          }t|t                    d.d/d0d52           |t                    d*d+d3           d6 }u|p                    |u           |                    d7d8d9          }v|v
                    d:$          }w|w                    d;d<
          }x|x                    d6d7dd=           t          |x           |w                    d)d>
          }y|y                    dd?
           |y                    d@dA
           |y                    dBdC
           |y                    dDdbg dEd           |y                    dFdGdHgdIJ           |y                    dKdL
           |y                    dMdbg dNd           |w                    d+d,gdO(          }z|z                    ddP
           |w                    d%d&gdQ(           |w                    d,dR
          }{|{                    ddS
           |w                    dTdtgdU(          }|||                    ddV
           |w                    ddW
          }}|}                    ddX
           t          |v           dY }~|v                    |~           |                    dZd[d\          
                    d]$          }|                    d%d^
          }|                    dd_
           |                    dt(          dd`           |                    dߐda
          }|                    ddb
           |                    ddc
           |                    ddde
           |                    ddf
          }|                    dgdh
           |                    dhdgddi           |                    djdk
          }|                    dlt(          dmdn           |                    ddo
           |                    dhdgddi           |                    dpdq
           |                    drds
          }|                    dgdt
           |                    dud/dv           |                    ddw
          }|                    dd_
           |                    dt(          dxdy           dt^          dzt`          fd{fd|}                    |           |                    d}d~d          }|                    dt(          dd           |                    dd
           d }|                    |           |                    ddd          }|
                    d$          }|                    ddd          }|                    dd
           |                    dcdd           |                    dKddgdd           |                    ddd           |                    ddd           |                    ddd           |                    dd
           |                    dg ddd           |                    dhdgdd           |                    ddgdd          }|                    dd
           |                    dcdd           |                    dhdgdd           d }|                    |           |                    dd
          }|                    tb                     |                    dĐdd          }|                    dddd:           |                    dddd:           |                    dddd:           |                    dddd:           |                    dhdgddd:           |                    td                     |                    d\dd          }|                    dQdd           |                    dhdgdd           |                    tf                     |                    ddd          }t          |           d }|                    |           |                    dd
          }|
                    d$          }|                    d%d
           |                    dd
          }|                    dd
           |                    dېd
          }|                    dd¬
           |                    dddĬ           |                    dddƬ           |                    dǐdȐdɐʦ           |                    ddd̬           |                    ddͬ
          }|                    ddά
           |                    dgdhdd           |                    dxdϬ
          }|                    ddЬ
           |                    dѐdҬ
          }|                    ddӬ
           |                    dddլ           |                    dd֐d0dאئ           |                    drd٬
          }|                    dڐd۬
           |                    dܐdݬ
           |                    dߐdެ
          }|                    dd߬
           |                    dhdidd           |                    dmd
          }|                    dd
           |                    ddd0dئ           |                    th                     |                    dd
          }|                    ddndg dd           |                    fd           |                    ddd          }|                    dt(          dd           |                    ddd           |                    ddd           |                    ddd           |                    ddd           |                    ddd           |                    ddd           |                    tj                     |                    d ddt:          j        dT          }|                    ddnddd           |                    ddXt(          dd	           |                    drd
dd           |                    dddʦ           |                    dddʦ           |                    dddʦ           |                    dd0dʦ           |                    tl                     ddl7m8}  |            }|r8ts          |tt          j;        dd                    tu          j<        d           t{          tt          j;        dd                   }ddl>}t          |d          r&t          |jA        B                                          nt                      t          fd|D                       }|rd|_D        tt          jE        }	 |F                                tt          _E        G                    |          }|tt          _E        ni# t          $ r?}|tt          _E        |jI        dk    r d|_D        G                    |          }Y d}~n%d}~ww xY wd|_D        G                    |          }|jJ        rtc          |           dS h d}dd4dhfd3d4hfd:d;hfd}|&                    |jK        d          \  }}|jK        |v s|r	t          ||d          |v rta          t          |dd                    }	 ddlMmN}  |             n.# tP          $ r! t          ,                    dd            Y nw xY w	 dd!lPmQ}  |             n.# tP          $ r! t          ,                    d"d            Y nw xY w	 dd#l7mR} dd$lSmT}  | |            |%           n.# tP          $ r! t          ,                    d&d            Y nw xY wt          |d'd          r\dd(lUmV} tu          j<         ||jW        t          |dd          t          |dd          t          |d)d          *                     |jX        s|jY        rJ|jK        Cd+|_K        d,D ]&\  }}t          ||          st          |||           't          |           dS |jK        ;d-D ]&\  }}t          ||          st          |||           't          |           dS t          |d.          r|[                    |           dS \                                 dS (/  z Main entry point for hermes CLI.r   )build_top_level_parser)funcrm   z!Select default model and providerz>Interactively select your inference provider and default model)r   descriptionz--portal-urlz;Portal base URL for Nous login (default: production portal))r   z--inference-urlzIInference API base URL for Nous login (default: production inference API)z--client-idNz;OAuth client id to use for Nous login (default: hermes-cli))r
   r   z--scopez%OAuth scope to request for Nous loginz--no-browserr   zBDo not attempt to open the browser automatically during Nous login)r	   r   z	--timeoutr  z<HTTP request timeout in seconds for Nous login (default: 15))typer
   r   z--ca-bundlez4Path to CA bundle PEM file for Nous TLS verificationz
--insecurez6Disable TLS verification for Nous login (testing only))cmd_fallbackfallbackz>Manage fallback providers (tried when the primary model fails)zManage the fallback provider chain.  Fallback providers are tried in order when the primary model fails with rate-limit, overload, or connection errors.  See: https://hermes-agent.nousresearch.com/docs/user-guide/features/fallback-providersfallback_command)destr   lsz<Show the current fallback chain (default when no subcommand))aliasesr   r  zOPick a provider + model (same picker as `hermes model`) and append to the chainr  rmz&Pick an entry to delete from the chainr   zRemove all fallback entriesr  zMessaging gateway managementz:Manage the messaging gateway (Telegram, Discord, WhatsApp)rX  r5  z?Run gateway in foreground (recommended for WSL, Docker, Termux)z-vz	--verboser&  z2Increase stderr log verbosity (-v=INFO, -vv=DEBUG)r   z-qrO  zSuppress all stderr log outputz	--replacez:Replace any existing gateway instance (useful for systemd)rB   z6Start the installed systemd/launchd background servicez--systemz-Target the Linux system-level gateway servicez--allzDKill ALL stale gateway processes across all profiles before startingr  zStop gateway servicez.Stop ALL gateway processes across all profilesr   zRestart gateway servicez@Kill ALL gateway processes across all profiles before restartingr   zShow gateway statusz--deepzDeep status checkz-lz--fullz9Show full, untruncated service/log output where supportedr  z7Install gateway as a systemd/launchd background servicez--forcezForce reinstallz8Install as a Linux system-level service (starts at boot)z--run-as-userrun_as_userz3User account the Linux system service should run as)r  r   rS  zUninstall gateway servicerl  zConfigure messaging platformszmigrate-legacyz;Remove legacy hermes.service units from pre-rename installszStop, disable, and remove legacy Hermes gateway unit files (e.g. hermes.service) left over from older installs. Profile units (hermes-gateway-<profile>.service) and unrelated third-party services are never touched.z	--dry-rundry_runz+List what would be removed without doing it)r  r	   r   z-yz--yesr0  zSkip the confirmation promptzInteractive setup wizardz~Configure Hermes Agent with an interactive wizard. Run a specific section: hermes setup model|tts|terminal|gateway|tools|agentsectionr^   )rm   ttsterminalr  rm  rI  z7Run a specific setup section instead of the full wizard)nargsrk  r
   r   z--non-interactivez,Non-interactive mode (use defaults/env vars)z--resetzReset configuration to defaultsz--reconfigureu   (Default on existing installs.) Re-run the full wizard, showing current values as defaults. Kept for backwards compatibility — a bare 'hermes setup' now does this.z--quickzvOn existing installs: only prompt for items that are missing or unset, instead of running the full reconfigure wizard.r]  zSet up WhatsApp integrationz'Configure WhatsApp and pair via QR codeslackz5Slack integration helpers (manifest generation, etc.)z%Slack integration helpers for Hermes.r   r!  zvPrint or write a Slack app manifest with every gateway command registered as a native slash (/btw, /stop, /model, ...)u(  Generate a Slack app manifest that registers every gateway command in COMMAND_REGISTRY as a first-class Slack slash command (matching Discord and Telegram parity). Paste the output into Slack app config → Features → App Manifest → Edit, then Save. Reinstall the app if Slack prompts for it.z--writeTr  zdWrite manifest to a file instead of stdout. With no PATH writes to $HERMES_HOME/slack-manifest.json.)r  constr
   metavarr   z--namez$Bot display name (default: "Hermes")z--descriptionz/Bot description shown in Slack's app directory.z--slashes-onlyz]Emit only the features.slash_commands array (for merging into an existing manifest manually).rk  z'Authenticate with an inference providerz2Run OAuth device authorization flow for Hermes CLIz
--providerr  r  z-Provider to authenticate with (default: nous))rk  r
   r   z,Portal base URL (default: production portal)z:Inference API base URL (default: production inference API)z,OAuth client id to use (default: hermes-cli)zOAuth scope to requestz0Do not attempt to open the browser automaticallyz-HTTP request timeout in seconds (default: 15)z/Path to CA bundle PEM file for TLS verificationz'Disable TLS verification (testing only)rq  z.Clear authentication for an inference providerz3Remove stored credentials and reset provider config)r  r  spotifyz3Provider to log out from (default: active provider)r   z"Manage pooled provider credentialsauth_actionzAdd a pooled credentialr   z>Provider id (for example: anthropic, openai-codex, openrouter)z--typer   )oauthzapi-keyru   zCredential type to add)r  rk  r   z--labelzOptional display labelz	--api-keyz+API key value (otherwise prompted securely)zNous portal base URLzNous inference base URLzOAuth client idzOAuth scope overridez*Do not auto-open a browser for OAuth loginz OAuth/network timeout in seconds)r  r   z(Disable TLS verification for OAuth loginz Custom CA bundle for OAuth loginzList pooled credentialszOptional provider filter)r  r   z1Remove a pooled credential by index, id, or labelzProvider idrt  z*Credential index, entry id, or exact labelr	  z:Clear exhaustion status for all credentials for a providerzShow auth status for a providerz.Log out a provider and clear stored auth stater   z)Authenticate Hermes with Spotify via PKCEspotify_action)rk  r   rq  )r  rk  r
   z7Spotify app client_id (or set HERMES_SPOTIFY_CLIENT_ID)z--redirect-uriz8Allow-listed localhost redirect URI for your Spotify appz!Override requested Spotify scopesz*Callback/token exchange timeout in secondszShow status of all componentsz)Display status of Hermes Agent componentsz'Show all details (redacted for sharing)z!Run deep checks (may take longer)ri  zCron job managementzManage scheduled tasksr  zList scheduled jobszInclude disabled jobsr  zCreate a scheduled jobschedulez/Schedule like '30m', 'every 2h', or '0 9 * * *'r  z2Optional self-contained prompt or task instructionz Optional human-friendly job namez	--deliverzNDelivery target: origin, local, telegram, discord, signal, or platform:chat_idz--repeatzOptional repeat countz--skillr?  r  z.Attach a skill. Repeat to add multiple skills.z--scriptzIPath to a Python script whose stdout is injected into the prompt each runz	--workdirzAbsolute path for the job to run from. Injects AGENTS.md / CLAUDE.md / .cursorrules from that directory and uses it as the cwd for terminal/file/code_exec tools. Omit to preserve old behaviour (no project context files).editzEdit an existing scheduled jobjob_idzJob ID to editz
--schedulezNew schedulez--promptzNew prompt/task instructionzNew job namezNew delivery targetzNew repeat countzIReplace the job's skills with this set. Repeat to attach multiple skills.z--add-skill
add_skillsz?Append a skill without replacing the existing list. Repeatable.z--remove-skillremove_skillsz-Remove a specific attached skill. Repeatable.z--clear-skillsz'Remove all attached skills from the jobzfPath to a Python script whose stdout is injected into the prompt each run. Pass empty string to clear.zqAbsolute path for the job to run from (injects AGENTS.md etc. and sets terminal cwd). Pass empty string to clear.pausezPause a scheduled jobzJob ID to pauser(  zResume a paused jobzJob ID to resumez$Run a job on the next scheduler tickzJob ID to triggerr  zRemove a scheduled jobzJob ID to removez"Check if cron scheduler is runningtickzRun due jobs once and exitru  z$Manage dynamic webhook subscriptionszPCreate, list, and remove webhook subscriptions for event-driven agent activationwebhook_action	subscribezCreate a webhook subscriptionr?   z*Route name (used in URL: /webhooks/<name>)rn   z0Prompt template with {dot.notation} payload refsz--eventsz%Comma-separated event types to acceptzWhat this subscription doesz--skillsz#Comma-separated skill names to loadlogz4Delivery target: log, telegram, discord, slack, etc.z--deliver-chat-idz*Target chat ID for cross-platform deliveryz--secretz'HMAC secret (auto-generated if omitted)z--deliver-onlyu   Skip the agent — deliver the rendered prompt directly as the message. Zero LLM cost. Requires --deliver to be a real target (not 'log').zList all dynamic subscriptionszRemove a subscriptionzSubscription name to removetestz#Send a test POST to a webhook routezSubscription name to testz	--payloadz,JSON payload to send (default: test payload))build_parserhooksz%Inspect and manage shell-script hookszInspect shell-script hooks declared in ~/.hermes/config.yaml, test them against synthetic payloads, and manage the first-use consent allowlist at ~/.hermes/shell-hooks-allowlist.json.hooks_actionz?List configured hooks with matcher, timeout, and consent statusz<Fire every hook matching <event> against a synthetic payloadeventzAHook event name (e.g. pre_tool_call, pre_llm_call, subagent_stop)z
--for-toolfor_toolz^Only fire hooks whose matcher matches this tool name (used for pre_tool_call / post_tool_call))r  r
   r   z--payload-filepayload_filezYPath to a JSON file whose contents are merged into the synthetic payload before executionrevokezCRemove a command's allowlist entries (takes effect on next restart)r  z?The exact command string to revoke (as declared in config.yaml)rn  zeCheck each configured hook: exec bit, allowlist, mtime drift, JSON validity, and synthetic run timingz$Check configuration and dependenciesz'Diagnose issues with Hermes Agent setupz--fixz#Attempt to fix issues automaticallyrj  z(Dump setup summary for support/debuggingzyOutput a compact, plain-text summary of your Hermes setup that can be copy-pasted into Discord/GitHub for support contextz--show-keyszOShow redacted API key prefixes (first/last 4 chars) instead of just set/not setr  u7   Debug tools — upload logs and system info for supportzDebug utilities for Hermes Agent. Use 'hermes debug share' to upload a debug report (system info + recent logs) to a paste service and get a shareable URL.aR  Examples:
    hermes debug share              Upload debug report and print URL
    hermes debug share --lines 500  Include more log lines
    hermes debug share --expire 30  Keep paste for 30 days
    hermes debug share --local      Print report locally (no upload)
    hermes debug delete <url>       Delete a previously uploaded paste
)r   r  formatter_classepilogdebug_commandsharez@Upload debug report to a paste service and print a shareable URLz--lines   z:Number of log lines to include per log file (default: 200)z--expire   z!Paste expiry in days (default: 7)z--localz-Print the report locally instead of uploadingz/Delete a paste uploaded by 'hermes debug share'urls*z?One or more paste URLs to delete (e.g. https://paste.rs/abc123))r  r
   r   r  z+Back up Hermes home directory to a zip filezCreate a zip archive of your entire Hermes configuration, skills, sessions, and data (excludes the hermes-agent codebase). Use --quick for a fast snapshot of just critical state files.r  z--outputzGOutput path for the zip file (default: ~/hermes-backup-<timestamp>.zip)zNQuick snapshot: only critical state files (config, state.db, .env, auth, cron)z/Label for the snapshot (only used with --quick)rp  z'Restore a Hermes backup from a zip filezExtract a previously created Hermes backup into your Hermes home directory, restoring configuration, skills, sessions, and datar  zPath to the backup zip filez-fz-Overwrite existing files without confirmationr  zView and edit configurationz!Manage Hermes Agent configurationr;  r1  zShow current configurationzOpen config file in editorr  zSet a configuration valuer   z1Configuration key (e.g., model, terminal.backend)valuezValue to setrc  zPrint config file pathzenv-pathzPrint .env file pathr  z!Check for missing/outdated configmigratezUpdate config with new optionsrs  z.Manage DM pairing codes for user authorizationz/Approve or revoke user access via pairing codespairing_actionzShow pending + approved usersapprovezApprove a pairing coder  z2Platform name (telegram, discord, slack, whatsapp)r#  zPairing code to approvezRevoke user accesszPlatform nameuser_idzUser ID to revokezclear-pendingzClear all pending codesc                 (    ddl m}  ||            d S )Nr   )pairing_command)hermes_cli.pairingr$  )rL  r$  s     r   cmd_pairingzmain.<locals>.cmd_pairingO#  s*    666666r   z-Search, install, configure, and manage skillszSearch, install, inspect, audit, configure, and manage skills from skills.sh, well-known agent skill endpoints, GitHub, ClawHub, and other registries.skills_actionbrowsez'Browse all available skills (paginated)z--pager   zPage number (default: 1)z--sizer   zResults per page (default: 20)z--sourcera  )ra  r5  z	skills-shz
well-knowngithubclawhublobehubzFilter by source (default: all))r
   rk  r   searchzSearch skill registriesr   zSearch query)r
   rk  z--limitr   zMax resultszInstall a skill
identifierz^Skill identifier (e.g. openai/skills/skill-creator) or a direct HTTP(S) URL to a SKILL.md filez
--categoryzCategory folder to install intozeOverride the skill name (useful when installing from a URL whose SKILL.md has no `name:` frontmatter)z$Install despite blocked scan verdictz-Skip confirmation prompt (needed in TUI mode)r>  z"Preview a skill without installingzSkill identifierzList installed skills)ra  hubbuiltinlocalz--enabled-onlyzcHide disabled skills. Use with -p <profile> to see exactly which skills will load for that profile.z&Check installed hub skills for updatesz&Specific skill to check (default: all)r   zUpdate installed hub skillsz7Specific skill to update (default: all outdated skills)auditzRe-scan installed hub skillsz&Specific skill to audit (default: all)zRemove a hub-installed skillzSkill name to removeuO   Reset a bundled skill — clears 'user-modified' tracking so updates work againzClear a bundled skill's entry from the sync manifest (~/.hermes/skills/.bundled_manifest) so future 'hermes update' runs stop marking it as user-modified. Pass --restore to also replace the current copy with the bundled version.z+Skill name to reset (e.g. google-workspace)z	--restorez<Also delete the current copy and re-copy the bundled versionz-Skip confirmation prompt when using --restorepublishzPublish a skill to a registry
skill_pathzPath to skill directoryz--tor)  r*  zTarget registryz--repoz'Target GitHub repo (e.g. openai/skills)snapshotz"Export/import skill configurationssnapshot_actionr  z!Export installed skills to a filer  z(Output JSON file path (use - for stdout)z%Import and install skills from a filer  zInput JSON file pathz%Force install despite caution verdicttapzManage skill sources
tap_actionzList configured tapsz!Add a GitHub repo as skill sourcerepozGitHub repo (e.g. owner/repo)zRemove a tapzTap name to removeuD   Interactive skill configuration — enable/disable individual skillsc                     t          | dd           dk    r"t          d           ddlm}  ||            d S ddlm}  ||            d S )Nr'  r  zskills configr   )skills_command)rG  r   hermes_cli.skills_configr:  hermes_cli.skills_hub)rL  skills_config_commandr:  s      r   
cmd_skillszmain.<locals>.cmd_skills$  sx    4$//8;;)))XXXXXX!!$'''''<<<<<<N4     r   rt  u0   Manage plugins — install, update, remove, listzDInstall plugins from Git repositories, update, remove, or list them.plugins_actionz-Install a plugin from a Git URL or owner/repozNGit URL or owner/repo shorthand (e.g. anpicasso/hermes-plugin-chrome-profiles)z$Remove existing plugin and reinstallz--enablez?Auto-enable the plugin after install (skip confirmation prompt)z--no-enablez]Install disabled (skip confirmation prompt); enable later with `hermes plugins enable <name>`z+Pull latest changes for an installed pluginzPlugin name to updatezRemove an installed pluginzPlugin directory name to removezList installed pluginsenablezEnable a disabled pluginzPlugin name to enabledisablez$Disable a plugin without removing itzPlugin name to disablec                 (    ddl m}  ||            d S )Nr   )plugins_command)hermes_cli.plugins_cmdrC  )rL  rC  s     r   cmd_pluginszmain.<locals>.cmd_pluginsV$  s*    ::::::r   )discover_plugin_cli_commandsr   r  r   )r   r  r  setup_fnzPlugin CLI discovery failed: %sr  uB   Background skill maintenance (curator) — status, run, pause, pina  The curator is an auxiliary-model background task that periodically reviews agent-created skills, prunes stale ones, consolidates overlaps, and archives obsolete skills. Bundled and hub-installed skills are never touched. Archives are recoverable; auto-deletion never happens.)register_clizcurator CLI wiring failed: %srr  z"Configure external memory providerzSet up and manage external memory provider plugins.

Available providers: honcho, openviking, mem0, hindsight,
holographic, retaindb, byterover.

Only one external provider can be active at a time.
Built-in memory (MEMORY.md/USER.md) is always active.memory_commandz0Interactive provider selection and configurationz#Show current memory provider configoffz)Disable external provider (built-in only)z1Erase all built-in memory (MEMORY.md and USER.md)zSkip confirmation promptz--target)ra  rr  r  z:Which store to reset: 'all' (default), 'memory', or 'user'c           
         t          | dd           }|dk    ruddlm}m}  |            }t	          |                    d          t                    si |d<   d|d         d<    ||           t          d           t          d	           d S |d
k    rddlm	}m
}  |            dz  t          | dd          }g }|dv r|                    d           |dv r|                    d           fd|D             }	|	st          d |             d           d S t          d           |	D ]=\  }
}|
z  }|                                j        }t          d|
 d| d|dd           >t          | dd          ss	 t          d                                                                          }n'# t"          t$          f$ r t          d           Y d S w xY w|dk    rt          d            d S |	D ]2\  }
}|
z                                   t          d!|
 d| d"           3t          d#           t          d$ |             d           d S dd%lm}  ||            d S )&NrI  rJ  r   r   rr  rn   r   u%   
  ✓ Memory provider: built-in onlyz  Saved to config.yaml
r	  r  memoriesrt  ra  )ra  rr  )z	MEMORY.mdzagent notes)ra  r  )zUSER.mdzuser profilec                 L    g | ] \  }}|z                                   ||f!S r   rs  )ry   r  r0  mem_dirs      r   r   z,main.<locals>.cmd_memory.<locals>.<listcomp>$  sF       %aGaK;O;O;Q;QD	  r   u1   
  Nothing to reset — no memory files found in z/memories/
z:
  This will permanently erase the following memory files:u       ◆ r  u   ) — r  z bytesr0  Fz
  Type 'yes' to confirm: z
  Cancelled.
z  Cancelled.
u     ✓ Deleted r   zE
  Memory reset complete. New sessions will start with a blank slate.z  Files were in: )rI  )rG  r   rS   r!  r   r/   r   r   r0   rE   r  r  r  r  r  r3   r   r  r  r  hermes_cli.memory_setuprI  )rL  r  rS   r!  r  rE   r  rt  files_to_resetr  r  r0  rc  sizerq  rI  rN  s                   @r   
cmd_memoryzmain.<locals>.cmd_memory$  sT   d,d33%<<BBBBBBBB []]Ffjj22D99 &#%x +-F8Z(K:;;;,-----G^^MMMMMMMM%o''*4GT8U33FN***%%&BCCC((%%&ABBB   )7  H  lI\I\I^I^lll   PQQQ# B B4{yy{{*@@@d@@$@@@@AAAA4.. "#@AAGGIIOOQQFF "34   ,---FF U??*+++F# 5 541$$&&&3q33D3334444Y   I&9&9&;&;IIIJJJJJ>>>>>>N4     s   =3F1 1 GGrm  z.Configure which tools are enabled per platforma  Enable, disable, or list tools for CLI, Telegram, Discord, etc.

Built-in toolsets use plain names (e.g. web, memory).
MCP tools use server:tool notation (e.g. github:create_issue).

Run 'hermes tools' with no subcommand for the interactive configuration UI.z	--summaryz6Print a summary of enabled tools per platform and exittools_actionz0Show all tools and their enabled/disabled statusz
--platformrP   zPlatform to show (default: cli)zDisable toolsets or MCP toolsr^  r  NAMEz7Toolset name (e.g. web) or MCP tool in server:tool form)r  r  r   z#Platform to apply to (default: cli)zEnable toolsets or MCP toolsz,Toolset name or MCP tool in server:tool formc                     t          | dd           }|dv rddlm}  ||            d S t          d           ddlm}  ||            d S )NrS  )r   rA  r@  r   )tools_disable_enable_commandrm  )tools_command)rG  hermes_cli.tools_configrV  r   rW  )rL  r	   rV  rW  s       r   	cmd_toolszmain.<locals>.cmd_tools*%  s~    ~t44222LLLLLL((.....!!!======M$r   r  z2Manage MCP servers and run Hermes as an MCP serverzManage MCP server connections and run Hermes as an MCP server.

MCP servers provide additional tools via the Model Context Protocol.
Use 'hermes mcp add' to connect to a new server, or
'hermes mcp serve' to expose Hermes conversations over MCP.
mcp_actionservezBRun Hermes as an MCP server (expose conversations to other agents)z Enable verbose logging on stderrz+Add an MCP server (discovery-first install)z Server name (used as config key)z--urlzHTTP/SSE endpoint URLz	--commandzStdio command (e.g. npx)z--argszArguments for stdio commandz--authr  r  zAuth method)rk  r   z--presetzKnown MCP preset namez--envz3Environment variables for stdio servers (KEY=VALUE)zRemove an MCP serverzServer name to removezList configured MCP serverszTest MCP server connectionzServer name to test	configurezToggle tool selectionzServer name to configurez5Force re-authentication for an OAuth-based MCP serverzServer name to re-authenticatec                 (    ddl m}  ||            d S )Nr   )mcp_command)hermes_cli.mcp_configr^  )rL  r^  s     r   cmd_mcpzmain.<locals>.cmd_mcpy%  s*    555555Dr   r   z<Manage session history (list, rename, export, prune, delete)z(View and manage the SQLite session storesessions_actionzList recent sessionsz/Filter by source (cli, telegram, discord, etc.)zMax sessions to showzExport sessions to a JSONL filez)Output JSONL file path (use - for stdout)zFilter by sourcez--session-idzExport a specific sessionzDelete a specific sessionre  zSession ID to deletezSkip confirmationprunezDelete old sessionsz--older-thanZ   z/Delete sessions older than N days (default: 90)z$Only prune sessions from this sourcestatszShow session store statisticsr  zSet or change a session's titlezSession ID to renamer   zNew title for the sessionuB   Interactive session picker — browse, search, and resume sessions  z#Max sessions to load (default: 500)r   c                     	 t          |                                                                           dv S # t          t          f$ r Y dS w xY w)z?Prompt for y/N confirmation, safe against non-TTY environments.rg  F)r  r3   r   r  r  )r  s    r   _confirm_promptzmain.<locals>._confirm_prompt%  sX    	==&&((..00L@@+, 	 	 	55	s   47 AAc           
      ~   dd l }	 ddlm}  |            }n*# t          $ r}t	          d|            Y d }~d S d }~ww xY w| j        }t          | dd           }|rd ndg}|dk    r|                    | j        || j	                  }|st	          d           d S t          d	 |D                       }	|	r-t	          d
ddddddddd            t	          d           n,t	          dddddddddd            t	          d           |D ]}
t          |
                    d                    }|	r|
                    dd          d d         n|
                    dd          d d         }|	rE|
                    d          pdd d         }|
d         }t	          |dd|dd|dd|            |
d         }t	          |dd|dd|
d         dd|            Րn|d k    r| j        r
|                    | j                  }|st	          d!| j         d"           d S |                    |          }|st	          d!| j         d"           d S |                    |d#$          d%z   }| j        d&k    r!t$          j                            |           nt+          | j        d'd()          5 }|                    |           d d d            n# 1 swxY w Y   t	          d*| j                    n|                    | j        +          }| j        d&k    r>|D ]9}
t$          j                            |                    |
d#$          d%z              :nBt+          | j        d'd()          5 }|D ]/}
|                    |                    |
d#$          d%z              0	 d d d            n# 1 swxY w Y   t	          d,t/          |           d-| j                    n|d.k    r|                    | j                  }|st	          d!| j         d"           d S | j        s  "d/| d0          st	          d1           d S t3                      d2z  }|                    ||3          rt	          d4| d5           nt	          d!| j         d"           n|d6k    r| j        }| j        rd7| j         d8nd}| j        s# "d9| d:| d;          st	          d1           d S t3                      d2z  }|                    || j        |<          }t	          d=| d>           no|d?k    r|                    | j                  }|st	          d!| j         d"           d S d                    | j                  }	 |                    ||          rt	          d!| d@|            nt	          d!| j         d"           n# t@          $ r}t	          dA|            Y d }~nd }~ww xY w|dBk    rt          | dCdD          pdD}t          | dd           }|rd ndg}|                    |||          }|!                                 |st	          d           d S tE          |          }|st	          d1           d S t	          dE|            ddFl#m$}  |dG|g           d S |dHk    r|%                                }|&                                }t	          dI|            t	          dJ|            dKD ]4}|%                    |+          }|dk    rt	          dL| dM| dN           5|j'        } | (                                r6tR          j*        +                    |           dOz  }!t	          dP|!dQdR           n#,                                 |!                                 d S )SNr   r#  z(Error: Could not open session database: r   toolr   )r   exclude_sourcesr%  r   c              3   @   K   | ]}|                     d           V  dS )r   Nrr  )ry   r   s     r   r{   z-main.<locals>.cmd_sessions.<locals>.<genexpr>%  s,      >>QUU7^^>>>>>>r   Titlez<32r   Previewz<40zLast Activez<13r   uJ  ──────────────────────────────────────────────────────────────────────────────────────────────────────────────r  r   z<6u  ───────────────────────────────────────────────────────────────────────────────────────────────r   r   rn   &   0   r   r  r  r   r  z	Session 'z' not found.F)ensure_asciir  r  wrJ   rK   zExported 1 session to rk  z	Exported z sessions to r  zDelete session 'z' and all its messages? [y/N] rq  r   )sessions_dirzDeleted session 'r)  rb  z from 'rL  z%Delete all ended sessions older than z daysz? [y/N] )older_than_daysr   rr  zPruned z session(s).r  z' renamed to: r'   r(  r%  re  zResuming session: )relaunchr{  rd  zTotal sessions: zTotal messages: )rP   telegramdiscordr]  r  r   r[  r   i   zDatabase size: r  z MB)-r   r&  r$  r9   r   ra  rG  list_sessions_richr   r%  r   rh   r/   re  resolve_session_idexport_sessionrg  r  r   r  r  re  
export_allr*   r0  rE   delete_session
older_thanprune_sessionsrM  r   set_session_titler7   r(  r!  hermes_cli.relaunchrt  session_countrl  db_pathr1   r-   rc  getsize
print_help)$rL  rj  r$  r)  rU  r	   _source_excluder   
has_titlesr   r   r   r   r   resolved_session_idrf  r   r  rr  r  
source_msgr&  r%  r   _browse_excludeselected_idrt  rO  msgsr  rl  r  size_mbrg  sessions_parsers$                                     r   cmd_sessionszmain.<locals>.cmd_sessions%  sU
   	......BB 	 	 	@Q@@AAAFFFFF	 % $$//"044V,,{HDJ -  H  *+++>>X>>>>>J "QQQyQQQ}QQQ4QQRRRk""""NNNNNNUNNNNNOOOj!!! U U,QUU=-A-ABB "3AEE)R(("--y"--crc2 
  UUU7^^4ucrc:ED'CUNNNNNN{NNNNNOOOOD'CWSSS;SSSQx[SSScSSTTTTU x Q&(&;&;DO&L&L#* CdoCCCDDDF(()<== CdoCCCDDDF{{4e{<<tC;#%%J$$T****dk3AAA &Q& & & & & & & & & & & & & & &@4;@@AAAA===<<;#%%% T T
((QU)K)Kd)RSSSST dk3AAA OQ!) O OAGGEKKK$F$F$MNNNNOO O O O O O O O O O O O O O O Oc(mmOO$+OOPPPPx"$"7"7"H"H& ?$/???@@@8 &Z':ZZZ   ,'''F*,,z9L  !4< PP AA*=AAABBBB?$/???@@@@w?D59[H14;1111bJ8 &[D[[z[[[   ,'''F*,,z9L%%d4;3? & A AE/E///0000x"$"7"7"H"H& ?$/???@@@HHTZ((E%''(;UCC EP&9PPPPQQQQCdoCCCDDD % % %mmm$$$$$$$$% xD'3//63ET8T22F&,:dd6(O,,e -  H HHJJJ *+++0::K l### 4{44555444444Hj+.///Fw$$&&E##%%D,U,,---+T++,,,J 4 4$$C$00q552s22a222333jG~~ :'//'22kB88888999 &&(((





sM    
?:?=KK#&K#>3N>>OOAW 
W>!W99W>rv  z!Show usage insights and analyticszVAnalyze session history to show token usage, costs, tool patterns, and activity trendsz--daysr  z'Number of days to analyze (default: 30)z1Filter by platform (cli, telegram, discord, etc.)c                 L   	 ddl m} ddlm}  |            } ||          }|                    | j        | j                  }t          |                    |                     |	                                 d S # t          $ r}t          d|            Y d }~d S d }~ww xY w)Nr   r#  )InsightsEngine)r  r   zError generating insights: )r&  r$  agent.insightsr  generater  r   r   format_terminalr(  r9   )rL  r$  r  r)  enginereportrU  s          r   cmd_insightszmain.<locals>.cmd_insights}&  s    
	5......555555B#^B''F__$)DK_HHF&((00111HHJJJJJ 	5 	5 	5333444444444	5s   A8A< <
B#BB#rh  zOpenClaw migration toolszHMigrate settings, memories, skills, and API keys from OpenClaw to Hermesclaw_actionzMigrate from OpenClaw to Hermesz|Import settings, memories, skills, and API keys from an OpenClaw installation. Always shows a preview before making changes.z1Path to OpenClaw directory (default: ~/.openclaw)u:   Preview only — stop after showing what would be migratedz	user-datafullup   Migration preset (default: full). Neither preset imports secrets — pass --migrate-secrets to include API keys.z--overwritezOOverwrite existing files (default: refuse to apply when the plan has conflicts)z--migrate-secretszdInclude allowlisted secrets (TELEGRAM_BOT_TOKEN, API keys, etc.). Required even under --preset full.z--no-backupzSkip the pre-migration zip snapshot of ~/.hermes/ (by default a single restore-point archive is written to ~/.hermes/backups/ before apply; restorable with 'hermes import').z--workspace-targetz1Absolute path to copy workspace instructions intoz--skill-conflict)r  	overwriter  r  z2How to handle skill name conflicts (default: skip)zSkip confirmation promptscleanupr  z5Archive leftover OpenClaw directories after migrationzQScan for and archive leftover OpenClaw directories to prevent state fragmentation)r  r   r  z1Path to a specific OpenClaw directory to clean upz5Preview what would be archived without making changesc                 (    ddl m}  ||            d S )Nr   )claw_command)hermes_cli.clawr  )rL  r  s     r   cmd_clawzmain.<locals>.cmd_claw&  s*    000000Tr   rM  zShow version informationz)Update Hermes Agent to the latest versionz;Pull the latest changes from git and reinstall dependenciesz	--gatewayFzZGateway mode: use file-based IPC for prompts instead of stdin (used internally by /update)z--checkz@Check whether an update is available without installing anythingzMSkip the pre-update backup for this run (overrides updates.pre_update_backup)z--backupz\Force a pre-update backup for this run (off by default; overrides updates.pre_update_backup)zAssume yes for interactive prompts (config migration, stash restore). API-key entry is skipped; run 'hermes config migrate' separately for those.zUninstall Hermes AgentzJRemove Hermes Agent from your system. Can keep configs/data for reinstall.z=Full uninstall - remove everything including configs and datarf  z9Run Hermes Agent as an ACP (Agent Client Protocol) serverzOStart Hermes Agent in ACP mode for editor integration (VS Code, Zed, JetBrains)c                     	 ddl m}  |             dS # t          $ r6 t          d           t          d           t	          j        d           Y dS w xY w)z%Launch Hermes Agent as an ACP server.r   r=  zACP dependencies not installed.z+Install them with:  pip install -e '.[acp]'r   N)acp_adapter.entryr>  r  r   r   r   )rL  acp_mains     r   cmd_acpzmain.<locals>.cmd_acp0'  st    	::::::HJJJJJ 	 	 	3444?@@@HQKKKKKK	s    <AAr4  u6   Manage profiles — multiple isolated Hermes instancesr  zList all profilesr  zSet sticky default profiler:   zProfile name (or 'default')zCreate a new profilez&Profile name (lowercase, alphanumeric)z--clonez3Copy config.yaml, .env, SOUL.md from active profilez--clone-allz'Full copy of active profile (all state)z--clone-fromSOURCEz.Source profile to clone from (default: active))r  r   z
--no-aliaszSkip wrapper script creationzDelete a profilezProfile to deletezShow profile detailszProfile to showr  zManage wrapper scriptszProfile namez--removezRemove the wrapper scriptr  z)Custom alias name (default: profile name))r  r  r   zRename a profiler  zCurrent profile namer  zNew profile namezExport a profile to archivezProfile to exportz$Output file (default: <name>.tar.gz)zImport a profile from archiver  zPath to .tar.gz archiver  z-Profile name (default: inferred from archive)rx  z2Print shell completion script (bash, zsh, or fish)r  r  )r  r  r  zShell type (default: bash))r  r
   rk  r   c                 $    t          |           S rw   )r  )rL  r   s    r   r  zmain.<locals>.<lambda>'  s    ^D&5Q5Q r   rw  zStart the web UI dashboardzQLaunch the Hermes Agent web dashboard for managing config, API keys, and sessionsz--porti#  zPort (default 9119)z--hostr  zHost (default 127.0.0.1)z	--no-openz Don't open browser automaticallyzKAllow binding to non-localhost (DANGEROUS: exposes API keys on the network)z--tuizuExpose the in-browser Chat tab (embedded `hermes --tui` via PTY/WebSocket). Alternatively set HERMES_DASHBOARD_TUI=1.z--stopz4Stop all running hermes dashboard processes and exitz--statusz0List running hermes dashboard processes and exitr  z View and filter Hermes log filesz;View, tail, and filter agent.log / errors.log / gateway.loga  Examples:
    hermes logs                    Show last 50 lines of agent.log
    hermes logs -f                 Follow agent.log in real time
    hermes logs errors             Show last 50 lines of errors.log
    hermes logs gateway -n 100     Show last 100 lines of gateway.log
    hermes logs --level WARNING    Only show WARNING and above
    hermes logs --session abc123   Filter by session ID
    hermes logs --component tools  Only show tool-related lines
    hermes logs --since 1h         Lines from the last hour
    hermes logs --since 30m -f     Follow, starting from 30 min ago
    hermes logs list               List available log files with sizes
r  rI  zPLog to view: agent (default), errors, gateway, or 'list' to show available filesrA  r  z%Number of lines to show (default: 50)z--followz*Follow the log in real time (like tail -f)z--levelLEVELz7Minimum log level to show (DEBUG, INFO, WARNING, ERROR)rm  r   z1Filter lines containing this session ID substringz--sinceTIMEz,Show lines since TIME ago (e.g. 1h, 30m, 2d)z--componentz5Filter by component: gateway, agent, tools, cli, cron)get_container_exec_infork  c              3   J   K   | ]}|                     d           |v V  dS )r  Nr  )ry   r  _known_cmdss     r   r{   zmain.<locals>.<genexpr>9(  sM        c9J9J	[     r   >   Nrlrf  rg  )ri  r  r  )NNaccept_hooks)discover_pluginsz&plugin discovery failed at CLI startup)exc_info)discover_mcp_toolsz(MCP tool discovery failed at CLI startuprR   )register_from_config)r  z-shell-hook registration failed at CLI startuponeshot)run_oneshotr  )rm   r   r  rg  )r   Nrm   Nr   Nr  NrE  FrA  F)r  r  r  r  r  )r(  N)r'  Nr  r  )]hermes_cli._parserr  set_defaultsrV  
add_parserr   r  r  hermes_cli.fallback_cmdr  add_subparsersr   rZ  rI  r~  r$  r  r  r  r  rc   r  r  r'  r  r(  r,  r0  r5  r   RawDescriptionHelpFormatterr9  rB  rE  r<  add_mutually_exclusive_groupplugins.memoryrF  r/   
__import__r9   r  r  r  r  hermes_cli.curatorrH  r   r  rQ  r  rV  r  r  r  r   r  rZ  r   r(   r   r~  ior  r  rk  keysr   r  r   StringIO
parse_argsr  r#  rM  r  rG  hermes_cli.pluginsr  r  tools.mcp_toolr  rS   agent.shell_hooksr  r  r  r  r(  r'  setattrr  r  )r  
subparserschat_parsermodel_parserr  fallback_parserfallback_subparsersgateway_parsergateway_subparsersgateway_rungateway_startgateway_stopgateway_restartgateway_statusgateway_installgateway_uninstallgateway_migrate_legacysetup_parserwhatsapp_parserslack_parser	slack_subslack_manifestlogin_parserlogout_parserauth_parserauth_subparsersauth_add	auth_listauth_remove
auth_resetauth_statusauth_logoutauth_spotifystatus_parsercron_parsercron_subparsers	cron_listcron_create	cron_edit
cron_pausecron_resumecron_runcron_remove	cron_tickwebhook_parserwebhook_subparserswh_subwh_rmwh_test_build_kanban_parserkanban_parserhooks_parserhooks_subparsers_hk_test
_hk_revokedoctor_parserdump_parserdebug_parser	debug_subshare_parserdelete_parserbackup_parserimport_parserconfig_parserconfig_subparsers
config_setpairing_parserpairing_subpairing_approve_parserpairing_revoke_parserr&  skills_parserskills_subparsersskills_browseskills_searchskills_installskills_inspectskills_listskills_checkskills_updateskills_auditskills_uninstallskills_resetskills_publishskills_snapshotsnapshot_subparserssnap_exportsnap_import
skills_taptap_subparserstap_addtap_rmr>  plugins_parserplugins_subparsersplugins_install_install_enable_groupplugins_updateplugins_removeplugins_enableplugins_disablerE  rF  cmd_infoplugin_parser_exccurator_parser_register_curator_climemory_parser
memory_sub_reset_parserrR  tools_parser	tools_subtools_list_ptools_disable_ptools_enable_prY  
mcp_parsermcp_submcp_serve_p	mcp_add_pmcp_rm_p
mcp_test_p	mcp_cfg_pmcp_login_pr`  sessions_subparserssessions_listsessions_exportsessions_deletesessions_prunesessions_renamesessions_browser  insights_parserr  claw_parserclaw_subparsersclaw_migrateclaw_cleanupr  version_parserupdate_parseruninstall_parser
acp_parserr  profile_parserprofile_subparsersprofile_useprofile_createprofile_deleteprofile_showprofile_aliasprofile_renameprofile_exportprofile_importcompletion_parserdashboard_parserlogs_parserr  r8  _processed_argv_io_has_cmd_token_saved_stderrrL  rA   _AGENT_COMMANDS_AGENT_SUBCOMMANDS	_sub_attr_sub_set_accept_hooksr  r  rS   r  r  r  r
   rg  r  r   r  s                                                                                                                                                                                       @@@@r   r>  r>    seE   999999&<&<&>&>#FJ(+++
 ((0T )  L
 J     X     J    
 4&M     Q    
 K	     R     E    
 9---
 544444 ++M`	 , 	 	O *88>P8QQ""K #   
 ""^ #    ""5 #   
 ""* #      l 333
  **+P +  N
 (66<M6NN %//U 0  K A     i3S     I    
 ;'''>*** '11N 2  M <    
 S     &00>T0UUL<    
 =     )331 4  O   < !   
   O !    (228BW2XXNDWXXXH	      <      )33Q 4  O   <FW XXX  G !   
   B !    +555 6   ""< #    !!'0O!PPP 0::J6	 ; 	 	 '':	 (    ''+ (    [111
 (('V )  L IIIF     ;    
 ,-N     F     I     9---
 !++*= ,  O
   l 333
 ((D; )  L
 +++AAI))GJ *  N ;      3     
 >     
 4      9---
 ((6H )  L
 (<	     K     I     t*X     i<TUUU?    
 <	     M     6    
 9---
 ))=I *  M
 333B	     J///''1 (  K "00m0DDO))%6O)PPHM     ///%	     )*BCCCG     ./EFFF+2KLLL-.?@@@)*@AAA9    
 %&H     7    
 -.PQQQ**68Q*RRI:S7QRRR!,,J -  K Zm<<<C     !++R ,  J J];;;!,,X<],^^KZm<<<!,,X<l,mmKZm<<<"--i>i-jjL.cC`C`C`jqrrrm2klll.5opppi.QRRRn\Hz{{{k<hiii(+++
 )),? *  M
 +T     ,O     J///
 ''*8P (  K "00n0EEO  **68M*NNI7<>UVVV ",,5'(@ -  K J     "V     X,NOOO]     Zc8OPPP=	     X      l      **5 +  I 8*:;;;<n===:,IJJJ8.999;-BCCC:C6HIIIX	     N	     <	     6    
 u      A     !++G:Q+RRJH+<===!,,X<Q,RRKX,>???)): *  H ()<===8$$$!,,4*1I -  K X,>??? x.RSSS  **68T*UUI9%%%;'''(+++
  **3f +  N
 (66<L6MM**eW+J +  F %QRRR
B%W     B%L     :WXXX
B%J     C    
 9    
 B%N          !!%E "    ))4&'> *  E 
v$ABBB ++: ,  G &ABBBR&T     [111
 GFFFFF((44MJ///
 ((4I	 )  L $222GGN     
  **K +  H P     :t8     ~t1     ",,8T*R -  J N    
 6      9---
 ))3= *  M
 +P     J///
 ''7J (  K ^    
 (+++
 ((F+ !< )  L  +++AAI''O (  L I	     0	     <    
 ((> )  M N	     9---
 )):H *  M V    
 ]	     iO     J///
 ))6 *  M y/LMMM<	     J///
 ))*7 *  M
 &44:J4KK   .J KKK   .J KKK #--e:U-VVJSR     G3^DDD   .F GGG   2H III   /R SSS   1Q RRRJ///
  **=E +  N
 !//5E/FFK6(GHHH(330 4   ''M (    ''5N'OOO'228BV2WW&&z&HHH&&y7J&KKK?1JKKK  
 [111
 ))< m *  M
 &44/4JJ%00@ 1  M sA,F     sB-M     
 
 
 /     &000 1  M w^<<<
 
 
     ysB]SSS&11)BS1TTNm      b'H      t     
 ,-S      <	      '11< 2  N 3EFFF#..v<S.TTKE+M+M+M     8     %//> 0  L c H     &004 1  M F     %//4 0  L c H     )338 4   !!&/E!FFF$//^A	 0  L B     K    
 <	     '117 2  N 3LMMM8Y*?FW      "#L      (22= 3  O *88>O8PP%00: 1  K X,VWWW%00> 1  K W+ABBB,-T     #--e:P-QQJ..L.AANf+ABBB''4W'XXG&EFFF&&xn&EEF
%9:::   S !   

! 
! 
! J///
  **?Z +  N
 (66<L6MM(33G 4  O   ] !      3	 !    ,HHJJ&&N '   
 &&l '    (22D 3  N -DEEE'224-4P 3  N -NOOO!!&4&?W!XXX'221 3  N -DEEE(33> 4  O   .F GGG  
 [111S??????4466 	0 	0H&11 f%$LL;; *: 6 6 R	 2  M !HZ ////	0  S S S(##))*KTRRRRRRRRS  **QE	 + 
 
NQLLLLLLn---- Q Q Q(##))*I4PPPPPPPPQ ))1D	 * 
 
M --3C-DDJH     ()NOOO%&QRRR))@ *  M '	     )))I	    <! <! <!| J///
 ((=Z	 ) 	 	L E    
 +++@@I ''? (  L .      **, +  O   F	 !      2 !    ))+ *  N ;	      2     
  
  
  9--- &&AJ	 ' 	 	J ''\'::G$$Q %  K /	     ;'''""A #  I 6(JKKK7)@AAA;-GHHHR.K     8gx-@}UUU:,CDDDB	     !!(TFAW!XXH&'>???vv4QRRR##F1M#NNJF)>???""hZ.E #  I 6(BCCC$$D %  K V*JKKK:&&&  
 )))
 !++K> ,  O
 *88>O8PP'226@V2WWMJ     R.D     *448 5  O   B !      2D EEE  6Q RRR)442 5  O   4J KKK  l1D !    )33GBW3XXN>	      
1WXXXl1D      ""71P"QQQ)448 5  O   4J KKK  :U VVV)44Q 5  O   J !      S/T !        a a a a a aF   l 333
 !++0l ,  O
   sB-V !      L !   5 5 5   l 333
 '''^ (  K
 "00m0DDO #--.8 .  L L     I    
 f%6	     ^    
 -     :     #V     ///A	     l1L    
 #--	Dg	 .  L L     D    
 l1L      
 (+++
  **9;U*VVN[111
 ))8Q *  M
 i	     O	     \	     k	      a     J///
 ",,%` -  
 !!L "   
 !!l1L "    !!}!555
 &&He '  J
 :&&&	 	 	 )))
  **E +  N (66<L6MM!!&/B!CCC$//0 0  K ^2OPPP'22- 3  N E      B     
 6     
 =     
 \0N      (228BT2UUN5HIIIgl1K      &00>T0UULn3DEEE&11. 2  M ~NCCC<.I     8	     (228BT2UUN
1GHHH
1CDDD'224 3  N 5HIIIj$-S      (226 3  N 	0IJJJ<	      [111
 #--A .   ""''') #    ""(Q(Q(Q(Q"RRR
 ",,)g -  
 !!sD/D "    !!+,F "    !!L/Q "    !!Z "   
 !!8	 "    !!C "   
 !!? "   
 !!}!555
 ''/Q < (  K& _	     4     9	     F    
 @    
 ;    
 D    
 (+++ :99999,,..N >38ABB<888 	1#(122,??O  +2*i*H*HSJ##%%&&&cee      "1    N  2"

	6CJ$$_55D&CJJ 
	6 
	6 
	6&CJ x1}} #(J$$_55DDDDDD
	6 $
  11 | D 211O"v7%w/ y1 
 -00|LLIx'' 	(!$	488HDDWT>5AABB	;;;;;; 	 	 	LL84      	
	
 :99999     	 	 	LL:T      		555555>>>>>>  ]KKKKK 	 	 	LL?      	 tY%% 222222L$..T:t44T:t44	
 
 
 	 	 	 	 t) t|/C
 		- 		-MD' 4&& -dG,,, |	
 	- 	-MD' 4&& -dG,,, tV 		$s   x>A7Az6 z6
A{8{ .A{3{3A{8|A|* |*
A},|4.A}'}'A},B?CC C
CDC5CDDCDG CG G(CG=G<CG=HCH H(CH>H=CH>I$CI' I'(CJJCJ__main__)r   N)rP   )Frw   )NFNNNr.  )rn   N)rn   rn   NN)rn   r^  )r  )FN)r  r   r   r-   rJ  r4  r   pathlibr   typingr   r   r   r   ro  r  r  r  rc  r  rC   r   rE   hermes_cli.env_loaderrF   r.   yaml_yaml_early	_cfg_pathr1   re  _f	safe_loadr/   _early_sec_cfgr   r   _early_redactr   r9   hermes_loggingrO   _setup_loggingrS   _load_config_earlyr0   rT   _apply_ipv4
_early_cfg_netr  rb   ra   rX   r  rY   rZ   r[   r\   r  r  r  rh   r  r   r   r!  r*  r7  rZ  rb  rg  rv  r  r  r  r  r  r  r  r  r  objectr   r$  rV  rZ  r~  rI  r  r  r  r  __annotations__r  r$  rc   r+  r  r7  rL  rK  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rL  rO  rb  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r$  r(  r,  r0  r5  r9  r<  rB  rE  rQ  rV  r]  r  rr  rz  CompletedProcessr  r  r  r  r  _warn_stale_dashboard_processesr  r  r  r  r&  r4  r>  rF  r0  r7  r;  r?  rD  rG  rJ  rL  rU  r]  rl  r  r  rw  r  r  r  r  r  r  r  r~  r  r  r  r  r  r>  r   r   r   <module>r{	     s  * * *X   				      



               s t    $ tH~~$+3355 33|$$ % % %@ @ @ @F      . - - - - - 4 4 4 4 4 4  |f4 5 5 5 5	bj00""""#O%%5	 	i'222 Wb"7+"7";";"Ar!F!FzSU!V!VW W W W W W W W W W W W W W Wz.$// U . 2 23C D D ,:=#m:L:L:R:R:T:TBJ67 	 	 	D	
	>>>>>>N 	 	 	D	
	CCCCCCEEEEEE##%%J>>)R((Dz$  $((<"8"8  $DD 	 	 	D	            4 4 4 4 4 4 4 4 E E E E E E E E		8	$	$;# ; ; ; ;$od o o o odpT phsm p p p pf # (3-    ( $      $Z%t Z%t Z% Z% Z% Z%z%s %x} % % % %P (3-    3 3 3HUXM 3ei 3 3 3 3l #N#344 9 9 9 9 9 9x	t 	 	 	 	 	t     4d t    &60 60 60 60rU9D U94 U9E$s)T/4J U9 U9 U9 U9p5f 5c 5 5 5 52 (,"? ?}?? C=? sm	?
 ? ? ? ?DQ Q Qh  JY JY JYZ  ) ) )t' t' t' t'n	
 
 
X
* 
* 
*
DsC}%& 
 
 
$ 3    *   
  	
   
   @C    <3" 3" 3" 3"lH@s H@t H@ H@ H@ H@^ 	.K .K
.K.K .K 	.K
 
.K .K .K .Kb'WC 'W4 'WD 'W 'W 'W 'WT 12 $ $ $ $ $N8 8 8 8v6 6 6 6ri i i iXW W W Wv  ( ( ( (V,5 ,5 ,5 ,5^H H H HVC C CL# #    *
/ 
/ 
/ 
/ ?C4Q 4Q 4Q 4QnB B B BJ=B =B =B@h/ h/ h/X / . . . . .    +# +$ + + + +U U U Up| | | |~nD nD nD nDbl l l l^C C    
 
 
 
 
 
n n n nbU U U Upt t t tnN N N NbZ Z ZzG G G GT              >               	 	 	    D       8/ / /s /% /TW / / / /d"$ "4 " " " "R #%% % %	%	% c3h	%
 %  % % % %P 38 * * *4 *4 *D * * * *ZUDI U U U Up$d $d $d $dP O_4 _4_4	_4 _4 _4 _4H #B J& J& J&Z+DI +D +Xc] + + + +\#Y!.1c]   $ 59
 

$,SM
	
 
 
 
& i i#Yi	i i 	i 
i i i i`    G 3 T#Y T hsm     # 4    "$s) $ 4    $s) $ 4    DI D  3 SV     Dd D D D D  d3i d t    "oX49 oX4 oXD oX oX oX oXd  849    H "&/
 /
 /
S	/
 
c3h$	/
 
	/
 /
 /
 /
d4 4 4 4@F- F- F- F- F- F- F- F-RN NT N N N Nb  ,-E -E -E`OQ OQ OQ OQdW W W Wt2 2 2:^ ^ ^ ^ ^BGd Gt G G G GTi i iX	#    B/ / /d
% 
% 
% 
%  *t# t# t#nG zDFFFFF s\   );E- $'DE- DE- DAE- -E54E59F FFAG4 4G<;G<