+
    „WÝj¡%  ã                  óF  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
HtHtHtHt ^ RIHt ^ RIHtHt ^ RIHt ]P,                  ! R4      t]! RR	4      t]! R
R	4      t]! RR4      t]! R4      t]P8                  R R l4       tR R ltR R ltR R lt ]P8                  R3RR/R R lll4       t!R R lt"R R lt#Rt$R R lt%]PL                  ! R 4      t'R! R" lt(R#t)/ t*R$]+R%&   R&R'R(R)/t,R&R*R(R+/t-R&R,R(R-/t.R.]-R/]./t/R0 R1 lt0]P8                  R2 4       t1R# )4uù   Shared plumbing for the extracted dashboard routers â€” thin wrappers over the
late-binding seam in :mod:`hermes_cli.web_deps` (web_server owns helpers/state;
every access resolves at call time so ``monkeypatch.setattr(<owning module>, ...)`` wins).)ÚannotationsN)ÚAnyÚCallableÚDictÚOptional)ÚHTTPException)Ú	LateStateÚlate)Ú_profile_cli_argszhermes_cli.web_serverÚ_profile_scopezhermes_cli.web_server_profilesÚ_config_profile_scopeÚ_spawn_hermes_actionzhermes_cli.web_server_gatewayÚ_CONFIG_MUTATION_LOCKc               ó   € V ^8„  d   QhRR/# )é   ÚprofileúOptional[str]© )Úformats   "ÚRC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_cli\web_routers\_common.pyÚ__annotate__r       s   € ÷ ñ  ñ ó    c           	   #  óÊ   "  € \        V 4      ;_uu_ 4        \        ;_uu_ 4        Rx € RRR4       RRR4       R#   + '       g   i     L; i  + '       g   i     R# ; i5i)uk   Profile scope, then the config mutation lock â€” the write-path nesting
every config-mutating handler uses.N)r   r   )r   s   &r   Úconfig_write_scoper      s:   é € ô 
˜×	 Õ	 ß"Ö"Û÷ #÷ 
!Ñ	 ß"×"ú÷ 
!×	 Ð	 üs/   ‚A#–A¥<	ªA²
A#¼AÁAÁA 	Á	A#c               ó$   € V ^8„  d   QhRRRRRR/# ©r   r   r   ÚfnzCallable[[], Any]Úreturnr   r   )r   s   "r   r   r   (   s"   € ÷ )ñ ) Mð )Ð7Hð )ÈSñ )r   c              ƒ  ó\   a a"  € VV 3R lp\         P                  ! V4      G Rj  x€L
 #  L5i)zCRun ``fn()`` inside ``_profile_scope(profile)`` on a worker thread.c                 óv   <€ \        S4      ;_uu_ 4        S ! 4       uuR R R 4       #   + '       g   i     R # ; i©N)r   ©r   r   s   €€r   Ú_runÚscoped_to_thread.<locals>._run+   s"   ø€ Ü˜G×$Õ$Ù“4÷ %×$×$Ó$úó   •'§8	N©ÚasyncioÚ	to_thread©r   r   r"   s   ff r   Úscoped_to_threadr)   (   s$   ùé € öô ×"Ò" 4Ó(×(Ð(Ñ(ùó   „!,¥*¦,c               ó$   € V ^8„  d   QhRRRRRR/# r   r   )r   s   "r   r   r   2   s#   € ÷ )ñ )¨=ð )Ð>Oð )ÐTWñ )r   c              ƒ  ó\   a a"  € VV 3R lp\         P                  ! V4      G Rj  x€L
 #  L5i)u�   Run ``fn()`` inside ``_config_profile_scope(profile)`` on a worker thread â€”
home + secret scope without the process-global skills-module swap.c                 óv   <€ \        S4      ;_uu_ 4        S ! 4       uuR R R 4       #   + '       g   i     R # ; ir    )r   r!   s   €€r   r"   Ú%config_scoped_to_thread.<locals>._run6   s"   ø€ Ü" 7×+Õ+Ù“4÷ ,×+×+Ó+úr$   Nr%   r(   s   ff r   Úconfig_scoped_to_threadr/   2   s$   ùé € öô ×"Ò" 4Ó(×(Ð(Ñ(ùr*   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   ÚrouteÚstrr   r   )r   s   "r   r   r   =   s!   € ÷ ñ  ð °sð ¸}ñ r   c                ó�   € T ;'       g    RP                  4       '       d   V # ^ RIHp V! 4       '       d   \        RV R2R7      hV # )u.  The profile a DESTRUCTIVE or PRIVILEGED route acts on, or 400 when it is ambiguous.

One backend serves every profile, so an omitted ``profile`` on a route that deletes,
overwrites or privileges profile-owned data is not a default â€” it silently meant
"whichever home this process launched with". Named profile: honoured. Omitted:
rejected as soon as the process hosts more than one profile
(``is_multiplex_active()``, decided once at boot by
``activate_multi_profile_hosting_eagerly``). A genuinely single-profile host has
nothing to confuse, so there an omitted profile keeps meaning the launch profile
and `curl` against a plain ``hermes serve`` is unchanged.

"Privileged" is the same class as "destructive": arming an auto-approved shell hook
in the wrong profile is at least as bad as removing one from it.
Ú )Úis_multiplex_activeé�  z€ requires an explicit profile: this backend serves several profiles, so an unnamed target would act on the wrong profile's data.©Ústatus_codeÚdetail)ÚstripÚagent.secret_scoper5   r   )r   r1   r5   s   && r   Údestructive_profiler<   =   sT   € ð 	�ˆ�2×Ñ×ÒØˆÝ6Ù×ÒÜØØ�Wð Qð QôRð 	Rð €Nr   r9   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úlog_msgr2   ÚstatusÚintÚprefixr   r9   r   )r   s   "r   r   r   X   s/   € ÷ mñ m˜#ð m sð m°Mð mÐUbñ mr   c             #  ó¶   "  €  Rx € R#   \          d    h \         d7   p\        P                  T 4       \        Ye   TR7      hT RT 2R7      hRp?ii ; i5i)u  Map unexpected exceptions to an ``HTTPException``.

``HTTPException`` passes through; anything else is logged with ``log_msg`` (traceback),
then re-raised as ``HTTPException(status, f"{prefix}: {exc}")`` â€” or ``detail`` when given
(fixed message, exception text only in the log).
Nz: r7   )r   Ú	ExceptionÚlogÚ	exception)r>   r?   rA   r9   Úexcs   &&&$ r   Úhttp_failurerG   W   s^   é € ðmÝøÜô ØÜô mÜ�‰�gÔÜ¨ÒAS°vÔlÐlÐ\bÐ[cÐceÐfiÐejÐYkÔlÐlûðmüs)   ‚A„
 ˆAŠAŸA 1AÁAÁAc               ó0   € V ^8„  d   QhRRRRRRRRRRR	R
/# )r   r   r   ÚargvÚlistÚnamer2   r>   rA   r   Údictr   )r   s   "r   r   r   h   s<   € ÷ 7ñ 7Øð7Ø"&ð7Ø.1ð7Ø?Bð7ØLOð7à	ñ7r   c               óÀ   € \        VRV4      ;_uu_ 4        \        \        V 4      V,           V4      pRRR4       RRRXP                  RV/#   + '       g   i     L"; i)zzSpawn a background ``hermes -p <profile> <argv>`` action; a spawn
failure is logged and becomes ``500 "<prefix>: <exc>"``.iô  NÚokTÚpidrK   )rG   r   r
   rO   )r   rI   rK   r>   rA   Úprocs   &&&$$ r   Úspawn_profile_actionrQ   h   sO   € ô
 
�g˜s F×	+Õ	+Ü#Ô$5°gÓ$>ÀÕ$EÀtÓLˆ÷ 
,à�$˜˜tŸx™x¨°Ð6Ð6÷ 
,×	+ús   –AÁA	c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úvaluer   r9   r2   r   r   )r   s   "r   r   r   r   s!   € ÷ ñ �=ð ¨#ð °#ñ r   c                ód   € T ;'       g    RP                  4       pV'       g   \        RVR7      hV# )z0Strip ``value``; 400 with ``detail`` when empty.r4   r6   r7   )r:   r   )rS   r9   Ústrippeds   && r   ÚrequirerV   r   s+   € à—�˜×"Ñ"Ó$€HßÜ¨°FÔ;Ð;Ø€Or   zWRefusing to save a redacted credential preview; re-enter the full secret to replace it.c               ó    € V ^8„  d   QhRRRR/# )r   rS   r   r   r   r   )r   s   "r   r   r      s   € ÷ 4ñ 4 sð 4¨}ñ 4r   c                óL   € V '       g   R# ^ RI Hp RV! \        V 4      4       R2# )zNReturn a display-only credential sentinel that can never gain write authority.N)Ú
redact_keyu   Â«redacted:ô   Â»)Úhermes_cli.configrY   r2   )rS   rY   s   & r   Úredacted_credential_previewr\      s$   € çÙÝ,Ø™¤C¨£JÓ/Ð0°Ð3Ð3r   z.{4}\.\.\..{4}c               ó    € V ^8„  d   QhRRRR/# )r   Ú	submittedr   r   Úboolr   )r   s   "r   r   r   �   s   € ÷ Jñ J¨cð J°dñ Jr   c                ó¦   € \        T ;'       g    R4      pVP                  R4      '       d   R# VR8H  ;'       g    \        P                  V4      RJ# )zFRecognize current, stale and legacy dashboard previews by shape alone.r4   u
   Â«redactedTz***N)r2   Ú
startswithÚ_LEGACY_MASK_REÚ	fullmatch)r^   rS   s   & r   Úis_redacted_credential_previewrd   �   sJ   € ä�	—�˜RÓ €Eð ×Ñ˜×%Ò%ÙØ�E‰>×IÐIœ_×6Ñ6°uÓ=ÀTÐIÐIr   g     Àr@zdict[str, float]Ú_corrupt_store_warned_atÚerrorÚstate_db_corruptÚmessageub   state.db corrupt â€” run `hermes doctor` (then `hermes doctor --fix` or `hermes sessions repair`).Ústate_db_deleted_waluý   another Hermes process still holds an old copy of the session database's write-ahead log â€” quit every Hermes process on this profile, run `hermes doctor` (it names the holders), then start Hermes again. Do not run `hermes doctor --fix` while they run.Ústate_db_replacedu·   state.db was replaced while Hermes was running â€” stop Hermes, run `hermes doctor`, then start it again. Do not run `hermes doctor --fix`, which would repair the wrong file in place.Údeleted_walÚreplacedc               ó   € V ^8„  d   QhRR/# )r   r   r   r   )r   s   "r   r   r   ¶   s   € ÷ Jñ J¨-ñ Jr   c                ór  € ^ RI Hp \        V 4      \        P                  ! 4       rC\
        P                  V4      p\        P                  V! V4      \        4      pVe   WE,
          \        8¼  d!   V\
        V&   \        P                  RW4       M\        P                  RW4       \        R/ VCRV/CR7      # )z´The structured ``state_db_corrupt`` 503 for a malformed store, warning once per store per
:data:`_CORRUPT_STORE_WARN_INTERVAL_S` (debug afterwards). Callers ``raise ... from exc``.)Úclassify_persistence_erroruw   state.db at %s is unreadable (%s); dashboard reads return a status payload until it is repaired â€” run `hermes doctor`z"state.db at %s still has error: %si÷  Úpathr7   )Úhermes_state_errorsro   r2   ÚtimeÚ	monotonicre   ÚgetÚ_STORE_STATUS_DETAIL_BY_CAUSEÚCORRUPT_STORE_DETAILÚ_CORRUPT_STORE_WARN_INTERVAL_SrD   ÚwarningÚdebugr   )Údb_pathrF   ro   ÚkeyÚnowÚlastr9   s   &&     r   Úcorrupt_store_statusr~   ¶   sœ   € õ ?Ü�7‹|œTŸ^š^Ó-ˆÜ#×'Ñ'¨Ó,€DÜ*×.Ñ.Ñ/IÈ#Ó/NÔPdÓe€FØ‚|�s•zÔ%CÔCØ(+Ô  Ñ%Ü�‰ð 7Ø8?õ	Fô 	�	‰	Ð6¸ÔEÜ SÐ1H°FÐ1H¸FÀCÑ1HÔIÐIr   c              #  óÂ   "  € ^ RI HpHpHp  Rx € R#   \        P
                  T3 d2   p\        YA4      '       g   T! T4      '       g   h \        Y4      ThRp?ii ; i5i)zñMap a corrupt-image ``sqlite3.DatabaseError`` or ``StateDbReplacedError`` from a state.db read to a 503 status
payload, warning once per store per :data:`_CORRUPT_STORE_WARN_INTERVAL_S`.
Busy/locked and every other error propagate unchanged.)ÚStateDbReplacedErrorro   Úis_malformed_db_errorN)rq   r€   ro   r�   Úsqlite3ÚDatabaseErrorÚ
isinstancer~   )rz   r€   ro   r�   rF   s   &    r   Úcorrupt_store_as_statusr…   Æ   sX   é € ÷
 lÑkð:ÝøÜ×!Ñ!Ð#7Ð8ô :Ü˜#×4Ò4Ñ=RÐSV×=WÒ=WØÜ" 7Ó0°cÐ9ûð:üs*   ‚AŽ ’A”A«AÁ
AÁAÁAr    )2Ú__conditional_annotations__Ú__doc__Ú
__future__r   r&   Ú
contextlibÚloggingÚrer‚   rr   Útypingr   r   r   r   Úfastapir   Úhermes_cli.web_depsr   r	   Úhermes_cli.web_server_profilesr
   Ú	getLoggerrD   r   r   r   r   Úcontextmanagerr   r)   r/   r<   rG   rQ   rV   Ú REDACTED_CREDENTIAL_WRITE_DETAILr\   Úcompilerb   rd   rw   re   Ú__annotations__rv   ÚDELETED_WAL_DETAILÚSTATE_DB_REPLACED_DETAILru   r~   r…   )r†   s   @r   Ú<module>r—      s�  øðô^õ #ã Û Û Û 	Û Û ß 0Ó 0å !ç /Ý <ð ×ÒÐ/Ó0€áÐ&Ð(HÓI€ÙÐ4Ð6VÓWÐ ÙÐ2Ð4SÓTÐ ñ "Ð"9Ó:Ð ð ×Ñôó ðõ)õ)õð4 ×ÑñmÐei÷ mó ðmõ 7õð ^ð !õ
4ð —*’*Ð.Ó/€õJð "'Ð Ø-/Ð Ð*Ó /ð ÐØÐsðÐ ð Ð#Øð [ðÐ ð Ð Øð tðÐ ð "/Ð0BÀJÐPhÐ iÐ õJð  ×Ññ:ó ò:r   