+
    jHàjÙ*  ã                  óú   € R t ^ RIHt ^ RIt^ RIt. R%OtR R ltR R ltR R ltR	 R
 lt	R R lt
R R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltRR /R! R" lltR&R# R$ lltR# )'um  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, 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 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).
)ÚannotationsNc               ó    € V ^8„  d   QhRRRR/# )é   ÚpathÚstrÚreturnú
str | None© )Úformats   "Ú=/home/ubuntu/.hermes/hermes-agent/hermes_cli/_startup_fast.pyÚ__annotate__r   .   s   € ÷ ñ �Sð ˜Zñ ó    c                ó¼   €  \        V RR7      ;_uu_ 4       pVP                  4       uuRRR4       #   + '       g   i     R# ; i  \        \        3 d     R# i ; i)z>Read a small text file, or None when it is missing/unreadable.ú	utf-8-sig©ÚencodingN)ÚopenÚreadÚOSErrorÚUnicodeDecodeError)r   Úhandles   & r   Ú
_read_textr   .   sE   € ðÜ�$ ×-Õ-°Ø—;‘;“=÷ .×-×-Ó-ûäÔ'Ð(ô Úðús*   ‚A —2§
A ²A	½A ÁA ÁAÁAc               ó   € V ^8„  d   QhRR/# ©r   r   r   r	   )r
   s   "r   r   r   7   s   € ÷ Pñ P˜#ñ Pr   c                 óÚ   € \         P                  P                  \         P                  P                  \         P                  P	                  \
        4      \         P                  4      4      # )uD   Repo root as a str â€” the single source for main.py's PROJECT_ROOT.)Úosr   ÚrealpathÚjoinÚdirnameÚ__file__Úpardirr	   r   r   Úproject_root_strr!   7   s7   € ä�7‰7×ÑœBŸG™GŸL™L¬¯©¯©¼Ó)BÄBÇIÁIÓNÓOÐOr   c               ó   € V ^8„  d   QhRR/# ©r   r   ÚNoner	   )r
   s   "r   r   r   <   s   € ÷ -ñ - 4ñ -r   c                 ó@  € \         P                  P                  RR4      p V P                  4       '       g   R# \         P                  P                  \         P                  P                  V P                  4       4      4      pW8w  d   V\         P                  R&   R# R# )a¥  Expand ``~``/``$VAR`` in ``HERMES_HOME`` once, at process entry, and write it back.

fish does not expand ``~`` inside ``VAR=~/...`` and every shell passes a quoted value
through verbatim, so a literal tilde reaches the process. ``Path("~/.hermes")`` is
*relative*: the many raw ``os.environ["HERMES_HOME"]`` readers (this fast path, the
active_profile probe, profile re-home, the dotenv loader) would each resolve it against
cwd and scaffold a full home under ``<cwd>/~/.hermes``. One expansion here gives every
reader the same absolute spelling; ``hermes_constants`` expands as well for non-CLI
entry points. A relative value that is not tilde/variable-shaped is left alone.
ÚHERMES_HOMEÚ N)r   ÚenvironÚgetÚstripr   Ú
expanduserÚ
expandvars)ÚrawÚexpandeds     r   Únormalize_hermes_home_envr/   <   sg   € ô �*‰*�.‰.˜¨Ó
+€CØ�9‰9�;Š;ÙÜ�w‰w×!Ñ!¤"§'¡'×"4Ñ"4°S·Y±Y³[Ó"AÓB€HØ„Ø$,Œ�
‰
�=Ó!ñ r   c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   r	   )r
   s   "r   r   r   O   s   € ÷ ñ ˜Cð  Cñ r   c                óh   €  \         P                  P                  V 4      #   \         d    T u # i ; i)aJ  ``os.path.realpath`` that survives a deleted cwd.

A relative ``sys.path`` entry is resolved through ``os.getcwd()``, which raises
``FileNotFoundError`` once the directory the process started in has been removed
(a cron delivery child spawned from a reaped scratch workspace, #102941); the CLI
then dies before it can parse argv.
)r   r   r   r   )r   s   &r   Ú_realpath_or_selfr2   O   s0   € ðÜ�w‰w×Ñ Ó%Ð%øÜô ØŠðús   ‚! ¡1°1c               ó   € V ^8„  d   QhRR/# r#   r	   )r
   s   "r   r   r   ]   s   € ÷ %ñ % Tñ %r   c                 ó„  € \        4       p \        P                  P                  \	        V 4      4      p\
        P                   Uu. uF<  pV'       d0   \        P                  P                  \	        V4      4      V8w  g   K:  VNK>  	  up\
        P                  R&   \
        P                  P                  ^ V 4       R# u upi )zCPut the project root at sys.path[0], deduping realpath-equivalents.:NNNN)r!   r   r   Únormcaser2   ÚsysÚinsert)Úproject_rootÚnormalized_rootÚentrys      r   Úensure_project_root_on_pathr;   ]   s‡   € ä#Ó%€LÜ—g‘g×&Ñ&Ô'8¸Ó'FÓG€OÜ&)§h¢hó b¡h˜Uß¤2§7¡7×#3Ñ#3Ô4EÀeÓ4LÓ#MÐQ`Ñ#`÷ �5¡hñ b„C‡H�HˆQ�Kä‡H�H‡O�O�A�|Ö$ùòbs   ÁB=Á*B=ÂB=c               ó    € V ^8„  d   QhRRRR/# ©r   Úargvz	list[str]r   Úboolr	   )r
   s   "r   r   r   f   s   € ÷ +ñ + ið +°Dñ +r   c                ó   € V R .R.39   # )z	--versionz-Vr	   ©r>   s   &r   Úis_global_fast_version_argvrB   f   s   € Ø�[�M D 6Ð*Ñ*Ð*r   c               ó    € V ^8„  d   QhRRRR/# r=   r	   )r
   s   "r   r   r   j   s   € ÷ .ñ . ið .°Dñ .r   c                ó   € RV 9   # )a¢  Is ``argv`` the Desktop client's SSH backend spawn (``serve --ssh-session-token-file``)?

That child has a fixed identity: Desktop names the remote profile explicitly (or none for
the root home) and hands its session token through a 0600 FILE, never the
``HERMES_DASHBOARD_SESSION_TOKEN`` env var the local pool spawn uses. Every reader of
"is this process Desktop's backend" needs both shapes; this is the argv half.
z--ssh-session-token-filer	   rA   s   &r   Úis_desktop_ssh_backend_argvrE   j   s   € ð &¨Ñ-Ð-r   c               ó   € V ^8„  d   QhRR/# ©r   r   r?   r	   )r
   s   "r   r   r   u   s   € ÷ Iñ I¨$ñ Ir   c                 ó  € \         P                  P                  R4      '       g&   \         P                  P                  R4      '       d   R# \        R4      ;'       g    Rp RV 9   ;'       g    RV 9   ;'       g    RV 9   # )	zDTrue when we're already INSIDE a container (fast path is then safe).z/.dockerenvz/run/.containerenvTz/proc/1/cgroupr'   ÚdockerÚpodmanz/lxc/)r   r   Úexistsr   )Úcgroups    r   Ú is_container_startup_environmentrM   u   sc   € ä	‡w�w‡~�~�m×$Ò$¬¯©¯©Ð7K×(LÒ(LÙÜÐ(Ó)×/Ð/¨R€FØ�vÑ×HÐH ¨VÑ!3×HÐH°wÀ&Ñ7HÐHr   c               ó    € V ^8„  d   QhRRRR/# )r   Úhermes_rootr   r   r?   r	   )r
   s   "r   r   r   }   s   € ÷ 0ñ 0°#ð 0¸$ñ 0r   c                ó´   € \        \        P                  P                  V R4      4      ;'       g    RP	                  4       p\        T;'       d    VR8g  4      # )zECheap probe: does an active non-default profile redirect HERMES_HOME?Úactive_profiler'   Údefault)r   r   r   r   r*   r?   )rO   Úactives   & r   Ú active_profile_may_override_homerT   }   sE   € äœŸ™Ÿ™ kÐ3CÓDÓE×KÐKÈ×RÑRÓT€FÜ�×.Ð.˜6 YÑ.Ó/Ð/r   c               ó   € V ^8„  d   QhRR/# r   r	   )r
   s   "r   r   r   ƒ   s   € ÷ <ñ <�sñ <r   c                 ó|   € \         P                  P                  \         P                  P                  R 4      R4      # )Ú~z.hermes)r   r   r   r+   r	   r   r   Ú_default_homerX   ƒ   s&   € Ü�7‰7�<‰<œŸ™×*Ñ*¨3Ó/°Ó;Ð;r   c               ó   € V ^8„  d   QhRR/# r   r	   )r
   s   "r   r   r   ‡   s   € ÷ Hñ H˜ñ Hr   c                 ó‚   € \         P                  P                  R R4      P                  4       ;'       g    \	        4       # )r&   r'   )r   r(   r)   r*   rX   r	   r   r   Ú_resolved_homer[   ‡   s*   € Ü�:‰:�>‰>˜-¨Ó,×2Ñ2Ó4×GÐG¼»ÐGr   c               ó   € V ^8„  d   QhRR/# rG   r	   )r
   s   "r   r   r   ‹   s   € ÷ 7ñ 7 dñ 7r   c                 óú  € \         P                  P                  R4      R8X  g   \        4       '       d   R# \         P                  P                  RR4      P	                  4       p V '       d·   \         P
                  P                  \         P
                  P                  V R4      4      '       d   R# \         P
                  P                  \         P
                  P                  \         P
                  P                  V 4      4      4      pVR8g  ;'       d    \        V 4      # \        4       p\        V4      ;'       g>    \         P
                  P                  \         P
                  P                  VR4      4      # )	u  Conservative probe for NixOS container-mode routing.

False positives are fine (the slow path does the authoritative check). False negatives are NOT â€”
they'd print the host's version instead of the container's â€” so any profile ambiguity means "may
be active".
Ú
HERMES_DEVÚ1Fr&   r'   z.container-modeTÚprofiles)r   r(   r)   rM   r*   r   rK   r   Úbasenamer   ÚnormpathrT   rX   )Úhermes_homeÚparent_nameÚdefault_homes      r   Úcontainer_mode_may_be_activerf   ‹   sô   € ô 
‡z�z‡~�~�lÓ# sÔ*Ô.N×.PÒ.PÙÜ—*‘*—.‘. °Ó3×9Ñ9Ó;€KßÜ�7‰7�>‰>œ"Ÿ'™'Ÿ,™, {Ð4EÓF×GÒGÙÜ—g‘g×&Ñ&¤r§w¡w§¡´r·w±w×7GÑ7GÈÓ7TÓ'UÓVˆØ˜jÑ(×ZÐZÔ-MÈkÓ-ZÐZÜ “?€LÜ+¨LÓ9÷ 7ð 7¼R¿W¹W¿^¹^Ü
�‰�‰�\Ð#4Ó5ó>7ð 7r   c               ó   € V ^8„  d   QhRR/# ©r   r   r   r	   )r
   s   "r   r   r   Ÿ   s   € ÷ ñ ˜Zñ r   c                 óf  € \         P                   Fô  p \        P                  P                  T ;'       g    \        P                  ! 4       RR4      p \        VRR7      ;_uu_ 4       pV FŽ  pVP                  4       pVP                  R4      '       g   K,  VP                  R4      w  rVpVP                  R^4      ^ ,          P                  4       P                  R4      pT;'       g    R	u uuR	R	R	4       u # 	  R	R	R	4       Kö  	  R	#   + '       g   i     EK  ; i  \         d     EK  i ; i)
zARead OpenAI SDK version without importing ``importlib.metadata``.Úopenaiz_version.pyr   r   Ú__version__Ú=Ú#z"'N)r6   r   r   r   Úgetcwdr   r*   Ú
startswithÚ	partitionÚsplitr   )ÚbaseÚversion_filer   ÚlineÚstrippedÚ_keyÚ_sepÚvalues           r   Úread_openai_versionry   Ÿ   sí   € ä—”ˆÜ—w‘w—|‘| D×$7Ð$7¬B¯IªI«K¸À=ÓQˆð
	Ü�l¨[×9Õ9¸VÛ"�DØ#Ÿz™z›|�HØ#×.Ñ.¨}×=Ò=Ù Ø(0×(:Ñ(:¸3Ó(?Ñ%�D Ø!ŸK™K¨¨QÓ/°Õ2×8Ñ8Ó:×@Ñ@ÀÓG�EØ Ÿ=˜= DÑ(÷ :Ô9Ù"÷ :Ñ9ñ ñ ÷ :×9Ñ9ûô ô 	Ûð	úsC   ÁD Á(BDÃ*DÃ.
D Ã;DÃ=D ÄDÄD ÄD Ä D0Ä/D0c               ó   € V ^8„  d   QhRR/# rh   r	   )r
   s   "r   r   r   ±   s   € ÷ 2ñ 2˜Zñ 2r   c                 óÈ   € \        \        P                  P                  \	        4       R4      4      p T ;'       g    RP                  4       P                  4       ;'       g    R# )uÙ   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.
z.install_methodr'   N)r   r   r   r   r[   r*   Úlower)Úmethods    r   Úread_install_methodr~   ±   sG   € ô œŸ™Ÿ™¤^Ó%5Ð7HÓIÓJ€FØ�LˆL�b×ÑÓ!×'Ñ'Ó)×1Ð1¨TÐ1r   Úcheck_updatesTc               ó    € V ^8„  d   QhRRRR/# )r   r   r?   r   r$   r	   )r
   s   "r   r   r   »   s   € ÷ 6ñ 6¨dð 6¸dñ 6r   c           	     ó  €  ^ RI Hp \        V! 4       4       \        R\        4        24        ^ RI
Hp ^ R	IHp V! V! \        4       4      4      pV'       d   \        R
V 24       \        R\        P                   P#                  4       ^ ,           24       \%        4       p\        V'       d   RV 2MR4       V '       g   R#  ^ RIHpHp	 ^ RIHp
 V	! RR7      pVP/                  R4      pVP/                  R4      '       d)   \        RVP/                  R4       RV
! 4        R24       R# WÈ8X  d   \        RV
! 4        R24       R# V'       d/   V^ 8”  d(   V^8X  d   RMRp\        RV RV RV
! 4        R24       R# V^ 8X  d   \        R 4       R# R#   \         d2    ^ RIHp ^ RIHp \        RT! 4       P                   RT R24        EL·i ; i  \         d    \        4       p ELši ; i  \         d     R# i ; i)!u±   THE canonical ``hermes --version`` output (also used by /version).

Every lazy block degrades gracefully â€” a broken/heavy import can never take the basic version
output down.
)Úformat_banner_version_label)Ú__release_date__)Úget_version_infozHermes Agent vz (Ú)zInstall directory: )ÚPath)Údetect_install_methodzInstall method: zPython: zOpenAI SDK: zOpenAI SDK: Not installedN)ÚUPDATE_AVAILABLE_NO_COUNTÚcheck_for_updates)Úrecommended_update_commandT)ÚpassiveÚbehindÚrollbackzNewer than stable release vÚsourceVersionu    â€” 'z' moves back to itu   Update available â€” run 'Ú'ÚcommitÚcommitszUpdate available: Ú u    behind â€” run 'z
Up to date)Úhermes_cli.bannerr‚   ÚprintÚ	ExceptionÚ
hermes_clirƒ   Úhermes_cli.version_infor„   Úderived_versionr!   Úpathlibr†   Úhermes_cli.configr‡   r~   r6   Úversionrq   ry   Úhermes_cli.source_checkrˆ   r‰   rŠ   r)   )r   r‚   rƒ   r„   r†   r‡   Úinstall_methodÚopenai_versionrˆ   r‰   rŠ   ÚstatusrŒ   Úcommits_words   $             r   Úprint_fast_version_infor¡   »   sá  € ðZÝAäÑ)Ó+Ô,ô 
ÐÔ 0Ó 2Ð3Ð
4Ô5ð/Ý å;á.©tÔ4DÓ4FÓ/GÓHˆ÷ ÜÐ  Ð 0Ð1Ô2Ü	ˆH”S—[‘[×&Ñ&Ó(¨Õ+Ð,Ð
-Ô.Ü(Ó*€NÜ	¯^ˆL˜Ð(Ñ
)ÐA\Ô]ßÙðßXÝ@á"¨4Ô0ˆØ—‘˜HÓ%ˆØ�:‰:�j×!Ò!ÜÐ/°·
±
¸?Ó0KÐ/Lð MÙ0Ó2Ð3Ð3EðGö HàÔ0ÜÐ.Ñ/IÓ/KÐ.LÈAÐNÖOß˜ œ
Ø'-°¤{™8¸	ˆLÜÐ& v h¨a°¨~Ð=NÑOiÓOkÐNlÐlmÐnÖoØ�qŒ[Ü�,Öñ øôO ô ZÝ/Ý<ä�Ñ/Ó1×AÑAÐBÀ"ÐEUÐDVÐVWÐX×Yð	Zûô ô /Ü,Ó.‹ð/ûô6 ô ÚðúsR   ‚F ¯"G Ã>G/ Ä&G/ Ä,G/ ÅG/ Å,G/ Å>G/ Æ8GÇGÇG,Ç+G,Ç/G>Ç=G>c               ó    € V ^8„  d   QhRRRR/# )r   r>   zlist[str] | Noner   r?   r	   )r
   s   "r   r   r   ô   s   € ÷ ñ Ð+ð °tñ r   c                óš   € V f   \         P                  R,          p \        V 4      '       g   R# \        4       '       d   R# \	        4        R# )u  Handle ``hermes --version`` before the heavy import wall.

Only ``--version``/``-V`` (the ``version`` subcommand was removed â€”
``--version`` now carries the full output incl. update status), and
never when container mode may need to route the command into the
container.
:é   NNFT)r6   r>   rB   rf   r¡   rA   s   &r   Útry_fast_versionr¥   ô   s9   € ð ‚|Ü�x‰x˜�|ˆÜ& t×,Ò,ÙÜ#×%Ò%ÙäÔÙr   )rT   rf   r;   rM   rE   rB   r/   r¡   r!   r~   ry   r¥   )N)Ú__doc__Ú
__future__r   r   r6   Ú__all__r   r!   r/   r2   r;   rB   rE   rM   rT   rX   r[   rf   ry   r~   r¡   r¥   r	   r   r   Ú<module>r©      s|   ðñõ0 #ã 	Û 
ò€õ õPõ
-õ&õ%õ+õ.õIõ0õ<õHõ7õ(õ$2ð6°T÷ 6÷rñ r   