
    epj                         d Z ddlmZ ddlZddlZg dZddZdd	ZddZddZ	ddZ
ddZddZddZddZd dZd dZddZd!d"dZdS )#u  Pre-import startup fast paths — THE canonical lightweight helpers.

This module is imported by ``hermes_cli/main.py`` BEFORE its heavy import
wall (config, argparse tree, logging, providers). Everything here must stay
**stdlib-only and cheap** (os/sys file probes; no yaml, no hermes_cli.config,
no argparse). A guard test (``test_startup_fast_import_weight``) subprocess-
imports this module and fails if any heavy module sneaks into sys.modules.

Why this module exists (the bug class it kills): version-printing kept being
reimplemented as ``*_fast()`` copies at the top of main.py (Termux first,
then globally), each duplicating canonical logic — project-root resolution,
container detection, profile detection. The copies drifted: eb4040242
changed the canonical output and referenced ``PROJECT_ROOT`` inside the fast
function, which doesn't exist yet on the fast path → the Termux fast path
NameError'd on --version and nobody noticed. One implementation, imported
by both the fast path and the module constants, makes that drift
structurally impossible; the parity guard test would have caught eb4040242
the day it landed.

``hermes_cli/config.py``'s ``get_container_exec_info()`` reads the same
``.container-mode`` file; keep the file-format assumptions here and there in
sync (this module deliberately only PROBES existence/typos cheaply and errs
toward the slow path, which then does the authoritative parse).
    )annotationsN)project_root_strensure_project_root_on_pathis_termux_envis_termux_fast_version_argvis_global_fast_version_argv is_container_startup_environment active_profile_may_override_homecontainer_mode_may_be_activeread_openai_versionread_install_methodprint_fast_version_infotry_fast_versionreturnstrc                     t           j                            t           j                            t           j                            t
                    t           j                            S )uD   Repo root as a str — the single source for main.py's PROJECT_ROOT.)ospathrealpathjoindirname__file__pardir     >/home/thesage/.hermes/hermes-agent/hermes_cli/_startup_fast.pyr   r   /   s8    7BGLL)B)BBINNOOOr   Nonec                 *   t                      } t          j                            t          j                            |                     fdt
          j        D             t
          j        dd<   t
          j                            d|            dS )zCPut the project root at sys.path[0], deduping realpath-equivalents.c                    g | ]F}|r@t           j                            t           j                            |                    k    D|GS r   )r   r   normcaser   ).0entrynormalized_roots     r   
<listcomp>z/ensure_project_root_on_path.<locals>.<listcomp>8   s[        7BG,,U3344GG 	 HGGr   Nr   )r   r   r   r    r   sysinsert)project_rootr#   s    @r   r   r   4   s    #%%Lg&&rw'7'7'E'EFFO   X  CHQQQK HOOA|$$$$$r   boolc                     t           j                            dd          } t          t           j                            d          pd| v p|                     d                    S )z3Tiny Termux check for pre-import startup shortcuts.PREFIX TERMUX_VERSIONzcom.termux/files/usrz/data/data/com.termux/)r   environgetr(   
startswith)prefixs    r   r   r   A   s_    Z^^Hb))F

'(( 	7!V+	7566  r   argv	list[str]c                    | dgdgdgfv S )N	--version-Vversionr   r1   s    r   r   r   K   s    [MD6I;777r   c                    | dgdgfv S )Nr4   r5   r   r7   s    r   r   r   O   s    [MD6***r   c                 :   t           j                            d          st           j                            d          rdS 	 t          dd          5 } |                                 }ddd           n# 1 swxY w Y   n# t
          $ r Y dS w xY wd	|v pd
|v pd|v S )zDTrue when we're already INSIDE a container (fast path is then safe).z/.dockerenvz/run/.containerenvTz/proc/1/cgrouputf-8encodingNFdockerpodmanz/lxc/)r   r   existsopenreadOSError)handlecgroups     r   r	   r	   S   s    	w~~m$$ 7K(L(L t"W555 	#[[]]F	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#   uuvHV!3Hw&7HHs6   B  A4(B  4A88B  ;A8<B   
BBhermes_rootc                ~   t           j                            | d          }	 t           j                            |          rdt	          |d          5 }|                                                                }ddd           n# 1 swxY w Y   t          |o|dk              S n# t          t          f$ r Y nw xY wdS )zECheap probe: does an active non-default profile redirect HERMES_HOME?active_profiler:   r;   NdefaultF)
r   r   r   r?   r@   rA   stripr(   rB   UnicodeDecodeError)rE   rG   rC   actives       r   r
   r
   _   s    W\\+/?@@N7>>.)) 	8nw777 /6,,../ / / / / / / / / / / / / / /66Y#6777	8 '(   5s5   0B& 'B9B& B		B& B	B& &B:9B:c                     t           j                            dd                                          } | r| S t           j                            t           j                            d          d          S )NHERMES_HOMEr+   ~.hermes)r   r-   r.   rI   r   r   
expanduser)hermes_homes    r   _resolved_homerR   l   sW    *..3399;;K 7<<**3//;;;r   c                 D   t           j                            d          dk    rdS t                      rdS t           j                            dd                                          } | rt           j                            t           j                            | d                    rdS t           j                            t           j        	                    t           j        
                    |                               }|dk    ot          |           S t           j                            t           j                            d	          d
          }t          |          rdS t           j                            t           j                            |d                    S )u  Conservative probe for NixOS container-mode routing.

    False positives are fine (we fall through to the slow path, whose
    ``get_container_exec_info()`` does the authoritative check and routes
    into the container). False negatives are NOT fine — they'd print the
    host's version instead of the container's. Hence: any profile
    ambiguity → assume container mode may be active.
    
HERMES_DEV1FrM   r+   z.container-modeTprofilesrN   rO   )r   r-   r.   r	   rI   r   r?   r   basenamer   normpathr
   rP   )rQ   parent_namedefault_homes      r   r   r   s   s;    
z~~l##s**u')) u*..3399;;K 
7>>"',,{4EFFGG 	4g&&rwrw7G7G7T7T'U'UVV:% >0==	

 7<< 2 23 7 7CCL'55 t7>>"',,|5FGGHHHr   
str | Nonec                 D   t           j        D ]} | st          j                    } t          j                            | dd          }	 t          |d          5 }|D ]}|                                }|                    d          s,|                    d          \  }}}|	                    dd          d	                                                             d
          }|pdc cddd           c S 	 ddd           n# 1 swxY w Y   # t          $ r Y w xY wdS )zARead OpenAI SDK version without importing ``importlib.metadata``.openaiz_version.pyr:   r;   __version__=#   r   z"'N)r%   r   r   getcwdr   r@   rI   r/   	partitionsplitrB   )baseversion_filerC   linestripped_key_sepvalues           r   r   r      s      	9;;Dw||D(MBB
	lW555 )" ) )D#zz||H#..}== ! (0(:(:3(?(?%D$!KKQ//288::@@GGE =D(() ) ) ) ) ) ) ) ) ))) ) ) ) ) ) ) ) ) ) ) ) ) ) )  	 	 	H	4s=   DBD&D6DD	D	D	
D
DDc                 H   t           j                            t                      d          } 	 t	          | d          5 }|                                                                                                }ddd           n# 1 swxY w Y   |pdS # t          $ r Y dS w xY w)u  Read the installer's ``.install_method`` stamp, if present.

    Only the stamp (step 1 of ``config.detect_install_method``'s resolution
    order) — the managed/git/pip fallbacks need heavier imports and stay on
    the slow path. On the fast path home ambiguity is already excluded:
    ``container_mode_may_be_active()`` bails to the slow path whenever a
    non-default profile might redirect HERMES_HOME.
    z.install_methodr:   r;   N)	r   r   r   rR   r@   rA   rI   lowerrB   )stamprC   methods      r   r   r      s     GLL))+<==E%'*** 	3f[[]]((**0022F	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3~   tts4   B 9B8B BB BB 
B! B!c                    ddl m} m} t          d| d|  d           t          dt	                                  t                      }|rt          d|            t          dt          j                                        d                     t                      }t          |rd	| nd
           t          d           d S )Nr   )__release_date__r^   zHermes Agent vz ()zInstall directory: zInstall method: zPython: zOpenAI SDK: zOpenAI SDK: Not installedz'Run 'hermes version' for update status.)

hermes_clirq   r^   printr   r   r%   r6   rd   r   )rq   r^   install_methodopenai_versions       r   r   r      s    88888888	
=;
=
=*:
=
=
=>>>	
4 0 2 2
4
4555(**N 3111222	
-S[&&((+
-
-...(**N	^
\
)
)
)
)A\]]]	
344444r   list[str] | Nonec                "   | t           j        dd         } t                      }|r%t          j                            d          dk    rdS |rt          |           sdS n!t          |           sdS t                      rdS t                       dS )a  Handle ``hermes --version`` before the heavy import wall.

    Termux keeps its historical contract (also accepts the ``version``
    subcommand + the HERMES_TERMUX_DISABLE_FAST_CLI escape hatch). Everywhere
    else: only ``--version``/``-V`` (the ``version`` subcommand stays on the
    slow path for full output incl. update check), and never when container
    mode may need to route the command into the container.
    Nra   HERMES_TERMUX_DISABLE_FAST_CLIrU   FT)
r%   r1   r   r   r-   r.   r   r   r   r   )r1   	is_termuxs     r   r   r      s     |x|I RZ^^$DEELLu *400 	5	(.. u	%	'	' u4r   )r   r   )r   r   )r   r(   )r1   r2   r   r(   )rE   r   r   r(   )r   r[   )N)r1   rw   r   r(   )__doc__
__future__r   r   r%   __all__r   r   r   r   r   r	   r
   rR   r   r   r   r   r   r   r   r   <module>r~      se   2 # " " " " " 				 



   P P P P

% 
% 
% 
%   8 8 8 8+ + + +	I 	I 	I 	I
 
 
 
< < < <I I I I<   (   $5 5 5 5       r   