+
    „WÝjÎ ã                   óx  a € R„ t÷0 t R t^ RIHt ^ RI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t^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIHtHtHtH t  ]! ]!4      PD                  PD                  PG                  4       t$]%! ]$4      ]PL                  9  d#   ]PL                  PO                  ^ ]%! ]$4      4       ^ R	I(H)t) ^ R
I*H+t+  ^ RI,H-t-H.t.H/t/ ^ RI0H1t1 ^ RI2H3t3 R]	Pr                  9   d   ]! ]	Pr                  R,          4      M]! ]!4      PD                  R,          t:]Pv                  ! ]<4      t=^ RI>H?t?H@t@HAtAHBtBHCtCHDtDHEtEHFtFHGtGHHtHHItIHJtJ R R ltKR…R R lltLRtM^ RINHOtO R R ltPR R ltQR R ltR]-! R ]+! 4       P¦                  ]OR!7      tT^ R"IUHVtV ]TP¯                  ]V4       ^ R#IXHYtZ ]TP·                  ]Z4       R$ R% lt\]\! 4       s]R&t^Rs_] ^ k Rs`] ^k Rsa] ^k R' R( ltbR) R* ltcR+ R, ltdR-te^ R.IfHgth R/ R0 lti]j! R104      tk] ^k R2 R3 ltlR4 R5 ltm^ R6InHotoHptpHqtqHrtrHstsHtttHutuHvtv R†R7 R8 lltw]TPñ                  R94      R: R; l4       ty^ R<IzH{t{H|t|H}t} ^ R=I~HtH€t€ ]TPñ                  R94      R> R? l4       t�]TP¯                  ]{4       ]TPñ                  R94      R@ RA l4       t‚]TPñ                  R94      RB RC l4       tƒ]TPñ                  R94      RD RE l4       t„RFt… ! RG RH4      t†]†! 4       t‡]TPñ                  R94      RI RJ l4       tˆ]TP¯                  ]1RKRL.RL.RM7       RNt‰ROtŠRP RQ lt‹RR RS ltŒ^ RTI�HŽt� ^ RUI�H‘t‘H’t’ ^ RVI“H”t” ^ RWI•H–t– ^ RXIzH—t—H˜t˜H™t™ ]	EP4                  ! RY4      t›Rtœ ]�! ]	EP4                  ! RZR[4      4      tž]ž^ 8:  d   ]=EPC                  R]]ž4       RtžM]ž]œ8”  d   ]=EPC                  R^]ž]œ4       ]œtžR‡t¢Rˆt£R‰t¤R_RR`R/t¥] ^k Ra Rb lt]EPL                  ! 4       t§Rct¨Rs©] ^k R†RdRe/Rf Rg llltªRs«] ^k Rh Ri lt¬]‘EPZ                  ! RjRk4       Rs®] ^k RŠRl Rm llt¯^ RnI°H±t²H³t´Hµt¶H·t¸H¹tºH»t¼H½t¾H¿tÀHÁtÂHÃtÄHÅtÆHÇtÈHÉtÊHËtÌHÍtÎHÏtÐHÑtÒHÓtÔHÕtÖH×tØHÙtÚHÛtÜHÝtÞHßtàHátâ ]TP·                  ]²P²                  4       ]TP·                  ]´P²                  4       ]TP·                  ]¶P²                  4       ]TP·                  ]¸P²                  4       ]TP·                  ]ºP²                  4       ]TP·                  ]¼P²                  4       ]TP·                  ]¾P²                  4       ]TP·                  ]ºEPÆ                  4       ]TP·                  ]ÀEPÈ                  4       ]TP·                  ]ÂEPÊ                  4       ]TP·                  ]ÀEPÌ                  4       ]TP·                  ]ÄP²                  4       ]TP·                  ]ÆEPÎ                  4       ]TP·                  ]ÈP²                  4       ]TP·                  ]ÆP²                  4       ]TP·                  ]ÊP²                  4       ]TP·                  ]ÌP²                  4       ]TP·                  ]ÀEPÐ                  4       ]TP·                  ]¸EPÒ                  4       ]TP·                  ]ÎP²                  4       ]TP·                  ]ÐP²                  4       ]TP·                  ]ÒP²                  4       ]TP·                  ]ÔEPÔ                  4       ]TP·                  ]ÂP²                  4       ]TP·                  ]ÔP²                  4       ]TP·                  ]ÖP²                  4       ]TP·                  ]ØP²                  4       ]TP·                  ]ÚP²                  4       ]TP·                  ]ÜP²                  4       ]TP·                  ]ÞP²                  4       ]TP·                  ]àP²                  4       ]TP·                  ]âP²                  4       ]˜! 4        ^ R#IëHYtì ]TP·                  ]ì4       ]™! ]T4       Ro Rp ltíRq Rr ltîRsRe/Rt Ru lltïRv Rw ltðRx Ry ltñRz R{ ltòR|R/R} R~ lltóR tôR€ R� ltõR‹R‚ Rƒ lltöR#   ]4 d=     ^ RI5H6t6 ]6! R4       ^ RI,H-t-H.t.H/t/ ^ RI0H1t1 ^ RI2H3t3  EL€  ]7 d
    ]8! R4      hi ; ii ; i  ]Ÿ] 3 d+    ]=EPC                  R\]	EP4                  ! RZ4      4       Rtž EL%i ; i)Œu  Hermes Agent â€” Web UI server: FastAPI app assembly, auth/host middleware, ``start_server``.

Route handlers live in ``web_routers/``; their helpers live in the sibling
``web_server_<concern>`` modules and are re-imported here so ``web_server.<name>``
stays the single late-binding seam tests monkeypatch (``web_deps.late``).
Usage: ``python -m hermes_cli.main web [--port 8080]``.
)ÚasynccontextmanagerN)Údeque)Úget_install_id)Úis_desktop_owned_backend)Ú
run_reaper)ÚPath)ÚAnyÚDictÚOptionalÚTuple©Úload_config)Úget_version_info)ÚFastAPIÚHTTPExceptionÚRequest)ÚCORSMiddleware)ÚJSONResponse)Úensure_importÚwebzOWeb UI requires fastapi and uvicorn.
Run hermes pm repair, then restart Hermes.ÚHERMES_WEB_DISTÚweb_dist)ÚPORT_IN_USE_EXIT_CODEÚ_dashboard_forwarded_allow_ipsÚ_eager_reconcile_own_session_dbÚ_maybe_open_browserÚ_port_bind_conflictÚ_read_bound_portÚ_report_port_in_useÚ_start_parent_death_watchdogÚ_uvicorn_console_loggingÚ_warm_gateway_moduleÚ_write_dashboard_ready_fileÚ_write_machine_sentinel_linec                ó0   € V ^8„  d   QhR\         R\        /# )é   ÚnameÚreturn©ÚstrÚbool)Úformats   "ÚIC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_cli\web_server.pyÚ__annotate__r-   Q   s   € ÷ Dñ DœSð D¬4ñ Dó    c                ón   € ^ RI HpHp V! \        V4      4      ;'       g    V R8g  ;'       d	    V! V 4      # )a  A gateway already ticks this profile's store with live adapters: its OWN process, or the
live default multiplexer (a served satellite has no gateway.pid of its own). Winning the
tick-lock race here would deliver through the standalone path (#52202, #100489, #107485).)Ú_check_gateway_runningÚ_served_by_running_multiplexerÚdefault)Úhermes_cli.profilesr0   r1   r   )r&   Úhomer0   r1   s   &&  r,   Ú_gateway_owns_cronr5   Q   s<   € ÷ [á!¤$ t£*Ó-÷ Dð DØ�	Ñ×BÐBÑ<¸TÓBðDr.   c                óH   € V ^8„  d   QhR\         P                  R\        RR/# )r%   Ú
stop_eventÚintervalr'   N)Ú	threadingÚEventÚint)r+   s   "r,   r-   r-   [   s+   € ÷ Q/ñ Q/¬9¯?©?ð Q/Äcð Q/ÐSWñ Q/r.   c           
     ó  aaa€ ^ RI HpHp ^ RIHpHp V! 4       p\        V! 4       4      oV! S4      ;'       g    RoR pRV/p\        Wb4      '       d}    ^ RIH	o V3R lp	V	! 4       p
V
'       dK   Y˜R&   WxR	&   ^ R
I
Hp V! V
4       \        P                  R\        V
4      V
 UUu. uF  w  rÍVNK	  	  upp4       RT9  d   TT3R lTR&   YxR	&   MWR VV3R llpV! 4       '       dA   \        P                  RV4        V P#                  V4      '       d   R# V! 4       '       d   K)   \        P                  RVP$                  V4       VP&                  ! V 3/ VB  R# u uppi   \         d    \        P!                  R4        LËi ; i)uÁ  Tick the cron scheduler from inside the desktop dashboard backend.

The desktop spawns a ``hermes dashboard`` backend, not a gateway, so without
this a cron created in the app would never fire (no live adapters; delivery
falls back to the per-platform send path). The primary backend outlives the
per-profile pool (reaped after ~10 idle minutes), so it ticks EVERY local
profile's store like a multiplex gateway; external providers keep the
single-store behavior (registries are not profile-scoped). Cross-process
safe: the built-in tick takes the per-store ``cron/.tick.lock``.

Every local profile's store is ticked, not just this backend's own (#69377's desktop sibling): the
desktop pools per-profile backends and reaps them after ~10 idle minutes, so a secondary profile's
ticker dies with its backend and that profile's jobs silently stop firing until the user next opens it
("tasks on the sleeping profile could be idle" â€” community report, Aug 2026).
)ÚInProcessCronSchedulerÚresolve_cron_scheduler)Úget_hermes_homeÚprofile_name_for_homer2   c                 ó"   € \        W4      '       * # ©N)r5   )r&   r4   s   &&r,   Ú<lambda>Ú,_start_desktop_cron_ticker.<locals>.<lambda>s   s   € Ô*<¸TÓ*HÕ&Hr.   r8   ©Úprofiles_to_servec                  ó(   <€ \        S ! R R7      4      # )T)Ú	multiplex)ÚlistrE   s   €r,   rC   rD      s   ø€ ¤DÑ):ÀTÔ)JÔ$Kr.   Úprofile_homesÚprofile_gate)Úenable_profile_log_routingz2Desktop cron scheduler will tick %d profile(s): %szEDesktop cron: profile enumeration failed; ticking active profile onlyc                  ó   <€ SS 3.# rB   © ©Úown_homeÚown_names   €€r,   rC   rD   ”   s   ø€ °hÀÐ5IÑ4Jr.   c                ó$   € V ^8„  d   QhR\         /# ©r%   r'   ©r*   )r+   s   "r,   r-   Ú0_start_desktop_cron_ticker.<locals>.__annotate__˜   s   € ÷ 	ñ 	œñ 	r.   c                  óp   <€  \        SS 4      #   \         d    \        P                  R RR7        R# i ; i)zADesktop cron: gateway-ownership probe failed; starting the tickerT©Úexc_infoF)r5   Ú	ExceptionÚ_logÚwarningrO   s   €€r,   Ú_ownedÚ*_start_desktop_cron_ticker.<locals>._owned˜   s9   ø€ ðÜ)¨(°HÓ=Ð=øÜô ä—‘Ð`Ðko�ÔpÚðús   ƒ �"5´5z‡Desktop cron scheduler waiting: live gateway owns cron on this HERMES_HOME; the gateway ticks with live adapters (re-probing every %ds)Nz:Desktop cron scheduler started (provider=%s, interval=%ds))Úcron.scheduler_providerr=   r>   Úhermes_constantsr?   r@   r   Ú
isinstancer3   rF   Úhermes_loggingrL   rZ   ÚinfoÚlenrY   Ú	exceptionÚwaitr&   Ústart)r7   r8   r=   r>   r?   r@   ÚproviderrK   Ústart_kwargsrJ   Úinitial_profile_homesrL   r&   Ú_homer\   rP   rQ   rF   s   &&             @@@r,   Ú_start_desktop_cron_tickerrk   [   sm  ú€ ÷  WßGá%Ó'€HÜ‘OÓ%Ó&€HÙ$ XÓ.×;Ð;°)€Hñ I€Là$ hÐ/€LÜ�(×3Ò3ð	dÝ=ô LˆMÙ$1£OÐ!ß$ð 1>˜_Ñ-Ø/;˜^Ñ,ÝEá*Ð+@ÔAÜ—	‘	ØHÜÐ-Ó.Ù-BÔCÑ-B™k˜d“TÑ-BÒCôð  ,Ô.õ -KˆL˜Ñ)Ø+7˜Ñ(ø÷	ñ 	ñ �8Š8Ü�I‰IðNØOWôð Ø—?‘? 8×,Ò,ÙÙ—x”xØä‡I�IÐJÈHÏMÉMÐ[cÔdØ‡N‚N�:Ñ. Ô.ùóA Døäô 	dä�N‰NÐbÖcð	dús*   ÁE$ Á15E$ Â&EÂ3E$ ÅE$ Å$ FÆFg      ð?)Úapp_lifespanc                ó0   € V ^8„  d   QhR\         R\        /# )r%   Úappr&   )r   r)   )r+   s   "r,   r-   r-   ·   s   € ÷ ñ œGð ¬3ñ r.   c                ó�   €  \        V P                  V4      #   \         d#    T! 4       p\        T P                  Y4       Tu # i ; i)zèReturn ``app.state.<name>``, lazily creating it for non-``with`` TestClient usages.

The lifespan normally initialises these on the running event loop (an
asyncio.Lock created at import time binds to whatever loop was active then).
)ÚgetattrÚstateÚAttributeErrorÚsetattr)rn   r&   ÚfactoryÚvalues   &&& r,   Ú_app_state_defaultrv   ·   sA   € ðÜ�s—y‘y $Ó'Ð'øÜô Ù“	ˆÜ�—	‘	˜4Ô'ØŠðús   ‚ ˜*AÁAc                óD   € V ^8„  d   QhR\         R\        P                  /# ©r%   rn   r'   )r   ÚasyncioÚLock)r+   s   "r,   r-   r-   Å   s"   € ÷ Cñ CœWð C¬¯©ñ Cr.   c                 ó8   € \        V R \        P                  4      # )Úchat_argv_lock)rv   ry   rz   ©rn   s   &r,   Ú_get_chat_argv_lockr~   Å   s   € Ü˜cÐ#3´W·\±\ÓBÐBr.   c                óR   € V ^8„  d   QhR\         R\        \        \        3,          /# rx   )r   Údictr)   r   )r+   s   "r,   r-   r-   É   s&   € ÷ Eñ E¤wð E´4¼¼T¸	µ?ñ Er.   c                 ó$   € \        V R \        4      # )Úpty_active_session_files)rv   r€   r}   s   &r,   Ú_get_pty_active_session_filesrƒ   É   s   € Ü˜cÐ#=¼tÓDÐDr.   zHermes Agent)ÚtitleÚversionÚlifespan)ÚAuthBodyLimitMiddleware)Úrouterc                ó$   € V ^8„  d   QhR\         /# rS   ©r)   )r+   s   "r,   r-   r-   Ý   s   € ÷ Yñ Y¤ñ Yr.   c                  ó|   € \         P                  P                  R 4      ;'       g    \        P                  ! ^ 4      # )ÚHERMES_DASHBOARD_SESSION_TOKEN)ÚosÚenvironÚgetÚsecretsÚtoken_urlsaferN   r.   r,   Ú_resolve_session_tokenr’   Ý   s*   € Ü�:‰:�>‰>Ð:Ó;×XÐX¼w×?TÒ?TÐUWÓ?XÐXr.   zX-Hermes-Session-Tokenc                ó(   € V ^8„  d   QhR\         RR/# )r%   Útokenr'   NrŠ   )r+   s   "r,   r-   r-   è   s   € ÷ ñ ¤Cð ¨Dñ r.   c                 ó   € V '       d   V s R # R # rB   )Ú_SESSION_TOKEN)r”   s   &r,   Ú_apply_ssh_session_tokenr—   è   s   € çØŠñ r.   c                ó>   € V ^8„  d   QhR\         \        ,          RR/# )r%   Únoncer'   N©r
   r)   )r+   s   "r,   r-   r-   î   s   € ÷ ñ ¤(¬3¥-ð °Dñ r.   c                 ó4  € V s R sR sV '       d¼    \        P                  ! 4       R,          p \        P                  P                  TRT  24      p\        TRRR7      ;_uu_ 4       pTP                  R\        P                  ! 4        R24       R R R 4       Ts \        P                  ! T4      pYP                  TP                  3sR # R #   \
        \        3 d     R # i ; i  + '       g   i     L]; i  \         d     Lki ; i  \         d     R # i ; i)NÚpurelibz.hermes-ssh-runtime-Úwzutf-8)Úencodingzpid=Ú
)Ú_SSH_OWNER_NONCEÚ_SSH_RUNTIME_PURELIBÚ_SSH_RUNTIME_MARKERÚ	sysconfigÚ	get_pathsÚKeyErrorÚOSErrorr�   ÚpathÚjoinÚopenÚwriteÚgetpidÚstatÚst_devÚst_ino)r™   rœ   ÚmarkerÚfhÚsts   &    r,   Ú_apply_ssh_owner_noncer²   î   sú   € àÐØÐØÐßð	Ü×)Ò)Ó+¨IÕ6ˆGð	Ü—W‘W—\‘\ 'Ð-AÀ%ÀÐ+IÓJˆFÜ�f˜c¨G×4Õ4¸Ø—‘˜4¤§	¢	£˜}¨BÐ/Ô0÷ 5à"(Ðð	Ü—’˜Ó!ˆBØ$+¯Y©Y¸¿	¹	Ð#BÒ ñ% øô œ'Ð"ô 	Úð	ú÷ 5×4ûô ô 	Ùð	ûô
 ô 	Úð	úsL   �C ­9C7 Á&)C$Â
C7 Â.D ÃC!Ã C!Ã$C4	Ã/C7 Ã7DÄDÄDÄDc                ó$   € V ^8„  d   QhR\         /# rS   rT   )r+   s   "r,   r-   r-   
  s   € ÷ 5ñ 5œTñ 5r.   c                  ó  € \         e$   \        P                  P                  \         4      # \        f   R# \        w  rp \        P
                  ! V 4      pTP                  TP                  3Y38H  #   \         d     R# i ; i)NTF)	r¢   r�   r§   Úisfiler¡   r¬   r¦   r­   r®   )rœ   ÚdeviceÚinoder±   s       r,   Ú_ssh_runtime_intactr¸   
  st   € ÜÒ&Ü�w‰w�~‰~Ô1Ó2Ð2ô Ò#ÙÜ1Ñ€G�UðÜ�WŠW�WÓˆð �I‰I�r—y‘yÐ! f _Ñ4Ð4øô ô Úðús   Á A2 Á2BÂ BT)ÚPUBLIC_API_PATHSc                ó0   € V ^8„  d   QhR\         R\        /# )r%   Úrequestr'   )r   r*   )r+   s   "r,   r-   r-   $  s   € ÷ Sñ S¤gð S´$ñ Sr.   c                ó|  € V P                   P                  \        R4      pV'       d@   \        P                  ! VP                  4       \        P                  4       4      '       d   R# V P                   P                  RR4      p\        P                  ! VP                  4       R\         2P                  4       4      # )zïTrue if the request carries a valid dashboard session token.

The dedicated header avoids collisions with reverse proxies that already use
``Authorization`` (Caddy ``basic_auth``); the legacy Bearer path stays for
older dashboard bundles.
Ú TÚauthorizationzBearer )Úheadersr�   Ú_SESSION_HEADER_NAMEÚhmacÚcompare_digestÚencoder–   )r»   Úsession_headerÚauths   &  r,   Ú_has_valid_session_tokenrÆ   $  s…   € ð —_‘_×(Ñ(Ô)=¸rÓB€Nßœ$×-Ò-¨n×.CÑ.CÓ.EÄ~×G\ÑG\ÓG^×_Ò_ÙØ�?‰?×Ñ˜°Ó3€DÜ×Ò˜tŸ{™{›}°¼Ð7GÐ.H×.OÑ.OÓ.QÓRÐRr.   z/api/files/downloadc                ó<   € V ^8„  d   QhR\         R\        R\        /# )r%   r»   r§   r'   )r   r)   r*   )r+   s   "r,   r-   r-   7  s&   € ÷ Xñ X¤Gð X´3ð X¼4ñ Xr.   c                 óè   € V\         9  d   R # V P                  P                  RR4      p\        V4      ;'       d8    \        P
                  ! VP                  4       \        P                  4       4      # )Fr”   r½   )Ú_QUERY_TOKEN_API_PATHSÚquery_paramsr�   r*   rÁ   rÂ   rÃ   r–   )r»   r§   r”   s   && r,   Ú_has_valid_query_tokenrË   7  sT   € ØÔ)Ô)ÙØ× Ñ ×$Ñ$ W¨bÓ1€EÜ�‹;×WÐWœ4×.Ò.¨u¯|©|«~¼~×?TÑ?TÓ?VÓWÐWr.   c                ó(   € V ^8„  d   QhR\         RR/# )r%   r»   r'   N©r   )r+   s   "r,   r-   r-   >  s   € ÷ Dñ DœGð D¨ñ Dr.   c                ó<  € \        V P                  RR4      '       g   \        V P                  RR4      RJ d   R# \        V P                  P                  RR4      '       d   \        V P                  RR4      RJpM\        V 4      pV'       g   \	        RR	R
7      hR# )u!  Authorize a sensitive endpoint, raising 401 if the caller isn't allowed.

Loopback mode (``auth_required`` False): validate the SPA-injected
``_SESSION_TOKEN``. Gated mode: the token is NOT injected (cookie auth), and
``gated_auth_middleware`` already 401'd anything without a verified
``request.state.session`` â€” requiring the absent token here would make every
``_require_token`` endpoint unreachable behind the gate, so defer to it.
A verified native owner (``authenticate_native_http``) is the same-user
principal the outer seams already accepted; local Desktop runs with no
static token, so that principal must satisfy route-local policy too.
Hosted plugins receive this guard's decision via private IPC and request-local
state, not via a forwarded gateway credential or a process-wide bypass.
Únative_http_principalNÚhosted_http_authenticatedTÚauth_requiredFÚsessioné‘  ÚUnauthorized)Ústatus_codeÚdetail)rp   rq   rn   rÆ   r   )r»   Úoks   & r,   Ú_require_tokenrØ   >  s€   € ô 	�—‘Ð6¸×=Ò=Ü�w—}‘}Ð&AÀ4ÓHÈDÓPÙÜˆw�{‰{× Ñ  /°5×9Ò9Ü�W—]‘] I¨tÓ4¸DÐ@‰ä% gÓ.ˆßÜ¨°NÔCÐCñ r.   )Ú _DESKTOP_ATTACHMENT_WS_MAX_BYTESÚ_LOOPBACK_HOST_VALUESÚ_dashboard_public_hostsÚ_desktop_loopback_auth_exemptÚ_host_header_hostnameÚ_is_accepted_hostÚpublic_hosts_engage_gateÚshould_require_authc                óh   € V ^8„  d   QhR\         R\        \        \         ,          ,          R\        /# )r%   ÚhostÚtrusted_public_hostsr'   )r)   r
   Ú	frozensetr*   )r+   s   "r,   r-   r-   c  s4   € ÷ Wñ WÜ
ðWä"¤9¬S¥>Õ2ðWô 
ñWr.   c                óZ   € Vf   \        4       p\        V 4      ;'       g    \        V4      # )z¸Gate required for a non-loopback bind OR a non-loopback ``dashboard.public_url``.

Callers may pass the already-resolved host set so startup and request
validation share one snapshot.
)rÛ   rà   rß   )râ   rã   s   &&r,   Úshould_require_dashboard_authræ   c  s-   € ð Ò#Ü6Ó8ÐÜ˜tÓ$×VÐVÔ(@ÐAUÓ(VÐVr.   Úhttpc                ó$   € V ^8„  d   QhR\         /# ©r%   r»   rÍ   )r+   s   "r,   r-   r-   r  s   € ÷ $ñ $¬'ñ $r.   c           
   ƒ  ó.  "  € \        \        P                  RR4      pV'       d^   \        V P                  P                  RR4      V\        \        P                  R\        4       4      4      '       g   \        RRR/R	7      # V! V 4      G Rj  x€L
 #  L5i)
ziReject requests whose Host header doesn't match the bound interface (DNS rebinding, GHSA-ppp5-vxwm-4cf7).Ú
bound_hostNrâ   r½   rã   i�  rÖ   zfInvalid Host header. Dashboard requests must use the bound hostname or the configured public hostname.©rÕ   Úcontent)rp   rn   rq   rÞ   r¿   r�   rä   r   )r»   Ú	call_nextrë   s   && r,   Úhost_header_middlewarerï   q  s†   é € ô œŸ™ L°$Ó7€JßÔ+Ø�‰×Ñ˜F BÓ'¨´W¼S¿Y¹YÐH^Ô`iÓ`kÓ5l÷ò ô ØàðHðô
ð 	
ñ ˜7Ó#×#Ð#Ñ#ùs   ‚BBÂBÂB)ÚPluginApiWebSocketGateÚ_plugin_api_nameÚ_plugin_api_request_refused)Ú forward_secondary_plugin_requestÚplugin_request_scopec                ó$   € V ^8„  d   QhR\         /# ré   rÍ   )r+   s   "r,   r-   r-   �  s   € ÷ $ñ $¬Gñ $r.   c              ƒ  óª  "  € V P                   P                  p\        V P                  4      pV'       dõ   \	        V P
                  RR4      '       gg   \	        V P
                  RR4      '       gJ   \	        V P                  P
                  RR4      '       g#   \        V 4      '       g   \        W4      '       dr   \        V P                  4      ;_uu_ 4        \        V4      G Rj  x€L
 '       d   \        RRR/R	7      uuRRR4       # \        W4      G Rj  x€L
 pRRR4       Xe   V# V! V 4      G Rj  x€L
 #  LT L$  + '       g   i     L*; i L5i)
a  Block requests to disabled plugin API routes at request time
(:func:`_plugin_api_request_refused`).

Registered BEFORE the auth middlewares (runs AFTER them): an unauthenticated
caller must get auth's 401, never this 404, or the status code becomes a
plugin-name oracle.
Útoken_authenticatedFrÏ   NrÑ   i”  rÖ   zPlugin not foundrì   )Úurlr§   rñ   Úscoperp   rq   rn   rÆ   rË   rô   rò   r   ró   )r»   rî   r§   Úplugin_nameÚhosteds   &&   r,   Ú_plugin_api_runtime_gaterü   �  sú   é € ð �;‰;×Ñ€DÜ" 7§=¡=Ó1€K÷ Ü�—‘Ð4°e×<Ò<Ü�7—=‘=Ð"9¸4×@Ò@Ü�7—;‘;×$Ñ$ o°u×=Ò=Ü# G×,Ò,Ü! '×0Ò0ä! '§-¡-×0Õ0Ü0°Ó=×=Ö=Ü#°¸hÐHZÐ=[Ô\÷ 1Ò0ô <¸GÓQ×QˆF÷ 1ð ÒØˆMÙ˜7Ó#×#Ð#ñ >áQ÷ 1×0úñ $ùs`   ‚CEÃD>Ã%D:Ã&	D>Ã0D>Ã>EÄ	D>ÄD<ÄD>ÄEÄ5EÄ6EÄ:D>Ä<D>Ä>E	Å		Ec                ó$   € V ^8„  d   QhR\         /# ré   rÍ   )r+   s   "r,   r-   r-   ²  s   € ÷ ;ñ ;¬ñ ;r.   c              ƒ  ó:   "  € ^ RI Hp V! W4      G Rj  x€L
 #  L5i)uÀ   OAuth gate â€” active only when start_server flags ``auth_required``; pass-through on loopback.

Registered between host_header and auth_middleware: host check â†’ cookie auth â†’ token auth.
)Úgated_auth_middlewareN)Ú$hermes_cli.dashboard_auth.middlewarerÿ   )r»   rî   rÿ   s   && r,   Ú_dashboard_auth_gater  ±  s   é € õ KÙ& wÓ:×:Ð:Ñ:ùs   ‚”•c                ó$   € V ^8„  d   QhR\         /# ré   rÍ   )r+   s   "r,   r-   r-   ¼  s   € ÷ $ñ $¤7ñ $r.   c              ƒ  óð  "  € V P                   P                  p\        V P                  RR4      '       g¯   \        V P                  RR4      '       g’   \        V P                  P                  RR4      '       gk   VP                  R4      '       dT   V\        9  dI   VP                  R4      '       g2   \        V 4      '       g!   \        W4      '       g   \        RR	R
/R7      # V! V 4      G Rj  x€L
 #  L5i)u  Require the session token on all /api/ routes except the public list.

Skipped for requests the token-auth seam already authenticated
(``token_authenticated``) and when the OAuth gate is active â€” cookie auth is
then authoritative and the loopback-only token path must not override it.
r÷   FrÏ   NrÑ   z/api/z/api/mcp/oauth/callback/rÓ   rÖ   rÔ   rì   )
rø   r§   rp   rq   rn   Ú
startswithÚ_PUBLIC_API_PATHSrÆ   rË   r   )r»   rî   r§   s   && r,   Úauth_middlewarer  »  s¸   é € ð �;‰;×Ñ€Dä�G—M‘MÐ#8¸%×@Ò@Ü˜Ÿ™Ð'>À×EÒEÜ˜Ÿ™×)Ñ)¨?¸E×BÒBØ�O‰O˜G×$Ò$ØÔ)Ô)Ø—‘Ð :×;Ò;Ü(¨×1Ò1Ü& w×5Ò5ä¨°hÀÐ5OÔPÐPÙ˜7Ó#×#Ð#Ñ#ùs   ‚BC6Â!C6Â3<C6Ã/C4Ã0C6c                ó$   € V ^8„  d   QhR\         /# ré   rÍ   )r+   s   "r,   r-   r-   Ó  s   € ÷ ?ñ ?¤Gñ ?r.   c              ƒ  óØ   "  € ^ RI HpHp ^ RIHp V! V 4      G Rj  x€L
 pVe   V# V! V 4      ;_uu_ 4        V! W4      G Rj  x€L
 uuRRR4       #  L5 L  + '       g   i     R# ; i5i)u  Outermost auth seam: bearer-token auth for opted-in routes (registered LAST = runs FIRST).

A registered token route is owned here â€” authenticate, attach the principal
+ ``token_authenticated`` so downstream gates skip enforcement. Non-token
routes pass through untouched.
)Úauthenticate_native_httpÚnative_profile_scope)Útoken_auth_middlewareN)Ú%hermes_cli.dashboard_auth.native_httpr	  r
  Ú$hermes_cli.dashboard_auth.token_authr  )r»   rî   r	  r
  r  Ú	rejections   &&    r,   Ú_token_auth_seamr  Ò  sZ   é € ÷ eÝJÙ.¨wÓ7×7€IØÒØÐÙ	˜g×	&Õ	&Ù*¨7Ó>×>÷ 
'Ò	&ñ 8ñ ?÷ 
'×	&Ð	&üs8   ‚A*œA�A*·AÁAÁAÁA*ÁAÁA'	Á!	A*g     Àr@c                   ó„   a € ] tR tRt o Rt]3V 3R lR lltV 3R lR ltV 3R lR ltV 3R	 lR
 lt	V 3R lR lt
RtV tR# )ÚDashboardHealthiæ  uô   Dashboard-process health: rolling unhandled-error/5xx window + periodic self-test result.

Feeds ``components`` on the PUBLIC ``/api/status``, so :meth:`snapshot`
exports counts and enums only â€” never ``last_error_type``/``last_error_path``.
c                ó$   <€ V ^8„  d   QhRS[ RR/# )r%   Úwindow_secondsr'   N©Úfloat)r+   Ú__classdict__s   "€r,   r-   ÚDashboardHealth.__annotate__í  s   ø€ ÷ 1ñ 1¡uð 1ÐTXñ 1r.   c                óˆ   € Wn         \        R R7      V n        RV n        RV n        RV n        RV n        RV n        RV n        R# )é   )ÚmaxlenNÚunknown)	r  r   Ú_error_timesÚlast_error_typeÚlast_error_pathÚlast_error_atÚselftest_statusÚselftest_http_statusÚselftest_at)Úselfr  s   &&r,   Ú__init__ÚDashboardHealth.__init__í  sE   € Ø,ÔÜ*/°sÔ*;ˆÔØ.2ˆÔØ.2ˆÔØ.2ˆÔØ$-ˆÔØ37ˆÔ!Ø,0ˆÖr.   c                ó*   <€ V ^8„  d   QhRS[ RS[ RR/# )r%   Úexc_typer§   r'   NrŠ   )r+   r  s   "€r,   r-   r  ÷  s"   ø€ ÷ !ñ !¡Sð !±ð !¸ñ !r.   c                óŠ   € \         P                   ! 4       pV P                  P                  V4       Wn        W n        W0n        R # rB   )Útimer  Úappendr  r  r  )r#  r'  r§   Únows   &&& r,   Úrecord_errorÚDashboardHealth.record_error÷  s3   € Ü�iŠi‹kˆØ×Ñ× Ñ  Ô%Ø'ÔØ#ÔØ Ör.   c                ó:   <€ V ^8„  d   QhRS[ RS[S[,          RR/# )r%   ÚpassedÚhttp_statusr'   N)r*   r
   r;   )r+   r  s   "€r,   r-   r  þ  s&   ø€ ÷ 'ñ '¡dð '¹Á#½ð 'È4ñ 'r.   c                óh   € V'       d   R MRV n         W n        \        P                  ! 4       V n        R# )r×   ÚfailingN)r   r!  r)  r"  )r#  r/  r0  s   &&&r,   Úrecord_selftestÚDashboardHealth.record_selftestþ  s"   € ß'-™t°9ˆÔØ$/Ô!ÜŸ9š9›;ˆÖr.   c                ó    <€ V ^8„  d   QhRS[ /# rS   )r;   )r+   r  s   "€r,   r-   r    s   ø€ ÷ &ñ &¡Cñ &r.   c                ó  € \         P                   ! 4       V P                  ,
          pV P                  '       d5   V P                  ^ ,          V8  d   V P                  P                  4        KF  \	        V P                  4      # )é    )r)  r  r  Úpopleftrc   )r#  Úcutoffs   & r,   Úrecent_error_countÚ"DashboardHealth.recent_error_count  sY   € Ü—’“˜t×2Ñ2Õ2ˆØ××Ð D×$5Ñ$5°aÕ$8¸6Ô$AØ×Ñ×%Ñ%Ö'Ü�4×$Ñ$Ó%Ð%r.   c                ó6   <€ V ^8„  d   QhRS[ S[S[3,          /# rS   )r€   r)   r   )r+   r  s   "€r,   r-   r  	  s   ø€ ÷ 	
ñ 	
™$™s¡C˜x�.ñ 	
r.   c                ó˜   € V P                  4       pV'       g   V P                  R8X  d   RMRpRVRVRV P                  RV P                  /# )zAPublic component payload: status enum + counts + timestamps only.r2  Údegradedr×   ÚstatusÚrecent_unhandled_errorsr  Úselftest)r:  r   r  )r#  Úerrorsr?  s   &  r,   ÚsnapshotÚDashboardHealth.snapshot	  sQ   € à×(Ñ(Ó*ˆß &¨$×*>Ñ*>À)Ô*K‘ÐRVˆà�fØ% vØ˜T×/Ñ/Ø˜×,Ñ,ð	
ð 	
r.   )r  r  r  r  r"  r!  r   r  N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú _DASHBOARD_HEALTH_WINDOW_SECONDSr$  r,  r3  r:  rC  Ú__static_attributes__Ú__classdictcell__)r  s   @r,   r  r  æ  sB   ø‡ € ñð 0P÷ 1ò 1÷!ð !÷'ð '÷
&ð &÷	
ö 	
r.   r  c                ó$   € V ^8„  d   QhR\         /# ré   rÍ   )r+   s   "r,   r-   r-     s   € ÷ 	ñ 	´ñ 	r.   c              ƒ  óf  "  €  V! V 4      G Rj  x€L
 pTP                  R8¼  d8   \        P                  RTP                   2T P
                  P                  4       T#  LN  \          dD   p\        P                  \        T4      P                  T P
                  P                  4       h Rp?ii ; i5i)z[Outermost non-CORS middleware: count unhandled exceptions and 5xx; re-raises, never alters.Niô  Úhttp_)rY   ÚDASHBOARD_HEALTHr,  ÚtyperE  rø   r§   rÕ   )r»   rî   ÚresponseÚexcs   &&  r,   Ú_dashboard_health_middlewarerT    s�   é € ðÙ" 7Ó+×+ˆð ×Ñ˜sÔ"Ü×%Ñ%¨¨h×.BÑ.BÐ-CÐ&DÀgÇkÁk×FVÑFVÔWØ€Oñ ,øÜô Ü×%Ñ%¤d¨3£i×&8Ñ&8¸'¿+¹+×:JÑ:JÔKØûðüs8   ‚B1„A  �A�A  ”A
B1ÁA  Á B.Á+>B)Â)B.Â.B1z*^https?://(localhost|127\.0\.0\.1)(:\d+)?$Ú*)Úallow_origin_regexÚallow_methodsÚallow_headersg      N@z/api/sessions?limit=1c                ó   € V ^8„  d   QhRR/# ©r%   r'   NrN   )r+   s   "r,   r-   r-   ;  s   € ÷ 6ñ 6¨ñ 6r.   c               ƒ  ó  "  €  ^ RI p  T P                  T P                  \        R7      RR7      ;_uu_4       GRj  x€L
 pTP                  \        \        \        /R7      G Rj  x€L
 pRRR4      GRj  x€L
  \        P                  XP                  ^È8H  TP                  4       R#   \         d     R# i ; i L~ LW LI  + GRj  x€L 
 '       g   i     L`; i  \         d    \        P                  RR4        R# i ; i5i)zARun one authenticated in-process self-test request and record it.Nr}   zhttp://127.0.0.1)Ú	transportÚbase_url)r¿   F)ÚhttpxÚImportErrorÚAsyncClientÚASGITransportrn   r�   Ú_DASHBOARD_SELFTEST_ROUTErÀ   r–   rP  r3  rÕ   rY   )r^  ÚclientÚresps      r,   Ú_dashboard_selftest_oncere  ;  sÐ   é € ðÛð6à×$Ñ$¨u×/BÑ/BÄsÐ/BÓ/KÐVhÐ$×i×iÔiÐmsØŸ™Ô$=ÔH\Ô^lÐGm˜Ón×nˆD÷ j×iä×(Ñ(¨×)9Ñ)9¸SÑ)@À$×BRÑBRÖSøô ô Úðúñ jÙn÷ j×i×iÒiûô ô 6Ü×(Ñ(¨°×5ð6üs£   ‚D„B) ‰3C ¼B;½C Á %CÁ%B=Á&CÁ*C Á5B?Á61C Â'DÂ)B8Â4DÂ7B8Â8DÂ;C Â=CÂ?C ÃC	ÃC
Ã
C	ÃC	ÃC Ã!DÃ>DÄDÄDc                ó   € V ^8„  d   QhRR/# rZ  rN   )r+   s   "r,   r-   r-   J  s   € ÷ )ñ )¨ñ )r.   c               ƒ  ó  "  €  ^ RI p  \        P
                  ! \        4      G Rj  x€L
  \        \        P                  RR4      '       d   KF  \        4       G Rj  x€L
  KZ    \         d    \        P                  R4        R# i ; i Lb L/5i)z4Periodic self-test driver started from the lifespan.Nu2   httpx unavailable â€” dashboard self-test disabledrÑ   F)r^  r_  rZ   Údebugry   ÚsleepÚ$_DASHBOARD_SELFTEST_INTERVAL_SECONDSrp   rn   rq   re  )r^  s    r,   Ú_dashboard_selftest_looprk  J  ss   é € ðÛð Ü�mŠmÔ@ÓA×AÐAä”3—9‘9˜o¨u×5Ò5ÙÜ&Ó(×(Ò(øô ô Ü�
‰
ÐGÔHÚðúñ 	Bñ 	)ùsC   ‚B„A" ˆB¦B	§4BÁBÁBÁ" BÂBÂBÂBÂB)Úweb_server_gateway)Ú_ACTION_LOG_FILESÚ"_terminate_desktop_managed_gateway)Ú_auto_archive_ticker_loop)ÚPTY_REGISTRY)Ú_discover_dashboard_pluginsÚ_mount_plugin_api_routesÚ	mount_spaÚGATEWAY_HEALTH_URLÚGATEWAY_HEALTH_TIMEOUTÚ1u>   Invalid GATEWAY_HEALTH_TIMEOUT value %r â€” using default 1.0suN   Invalid non-positive GATEWAY_HEALTH_TIMEOUT value %.3fs â€” using default 1.0szKCapping GATEWAY_HEALTH_TIMEOUT %.3fs to %.3fs for dashboard liveness probesÚrootru   c                ó:   € V ^8„  d   QhR\         \        ,          /# rS   rš   )r+   s   "r,   r-   r-   Œ  s   € ÷ ;ñ ;œ¤�ñ ;r.   c                 ó"   € \        \        R7      # )z*Process-lifetime-cached stable install id.)Úcache)Ú_shared_get_install_idÚ_INSTALL_ID_CACHErN   r.   r,   r   r   Œ  s   € ä!Ô(9Ô:Ð:r.   g      $@Ú	interruptFc                óˆ   € V ^8„  d   QhR\         \        ,          R\        R\        \        P
                  \        3,          /# )r%   Úprofiler}  r'   )r
   r)   r*   ÚtupleÚ
subprocessÚPopen)r+   s   "r,   r-   r-   ¤  s8   € ÷ (ñ (¤H¬S¥Mð (Ìð (ÔY^Ô_i×_oÑ_oÔquÐ_uÕYvñ (r.   c          	     ó˜  € \         P                  ! V R4      R.V,          ,           p\         P                  P                  R4      pVeU   VP	                  4       fC   \         P
                  P                  R4      pVe   V\        V4      8X  d   VR3# \        R4      h\        pVei   Vw  rgpV\        V4      8X  d   \        P                  ! 4       V,
          MRp	V	e2   V	\        8  d'   \        P                  RV	\        VRR	4      4       VR3# \         P                  ! VR4      p
\        P                  ! 4       V
\        V4      3sV
R
3# )u\  Spawn ``hermes gateway restart``, reusing an in-flight or recent restart.

Concurrent children race each other on the kill-and-start path, so a live
child is reused; requests within ``GATEWAY_RESTART_COOLDOWN_SECONDS`` for the
same profile coalesce onto the last spawn too (#89034). This process stops
nothing itself: the child decides whether the restart is even allowed
(``_cmd_restart``'s multiplexer guard), so the orphan reap (#77276) runs
there, after that guard â€” reaping here killed the profile's gateway and then
the child refused to start a replacement (#125394). Returns ``(proc, reused)``.
Úrestartz--interruptzgateway-restartNTz7gateway restart already in progress for another profilez‡Coalescing gateway restart: one was started %.1fs ago (pid %s) and the gateway may still be coming back; not spawning another (#89034).ÚpidÚ?F)Ú_gateway_modÚ_gateway_subcommandÚ_ACTION_PROCSr�   ÚpollÚ_ACTION_COMMANDSr€  ÚRuntimeErrorÚ_LAST_GATEWAY_RESTARTr)  Ú	monotonicÚ GATEWAY_RESTART_COOLDOWN_SECONDSrZ   rb   rp   Ú_spawn_hermes_action)r  r}  Ú
subcommandÚexistingÚexisting_commandÚrecentÚ
spawned_atÚrecent_procÚrecent_commandÚageÚprocs   &$         r,   Ú_spawn_gateway_restartrš  ¤  s3  € ô  ×1Ò1°'¸9ÓEÈÈÐZcÕHcÕc€JÜ×)Ñ)×-Ñ-Ð.?Ó@€HØÒ §¡£Ò 7Ü'×8Ñ8×<Ñ<Ð=NÓOÐØÒ#Ð'7¼5ÀÓ;LÔ'LØ˜T�>Ð!ÜÐTÓUÐUä"€FØÒØ28Ñ/ˆ
 Ø/=ÄÀzÓARÔ/RŒd�nŠnÓ Ö+ÐX\ˆØŠ?˜sÔ%EÔEÜ�I‰Ið-ð Ü˜ U¨CÓ0ôð  Ð$Ð$ä×,Ò,¨ZÐ9JÓK€DÜ!Ÿ^š^Ó-¨t´U¸:Ó5FÐGÐØ�ˆ;Ðr.   c                óF   € V ^8„  d   QhR\         \        ,          R\        /# )r%   Ú	signaturer'   )r
   r)   r*   )r+   s   "r,   r-   r-   Õ  s   € ÷ 	ñ 	¬X´c­]ð 	¼tñ 	r.   c                ó4   € V f   Rs R# V \         8X  d   R# V s R# )zQTrue if ``signature`` is new and should be logged now; ``None`` clears the latch.NFT)Ú_voice_list_last_error)rœ  s   &r,   Ú_voice_list_error_logged_oncerŸ  Õ  s(   € ð ÒØ!%ÐÙØÔ*Ô*ÙØ&ÐÙr.   zcomputer-use-grantzaction-computer-use-grant.logc                ó0   € V ^8„  d   QhR\         R\        /# )r%   Úforce_rescanr'   )r*   rI   )r+   s   "r,   r-   r-   ç  s   € ÷ $ñ $¬ð $¼$ñ $r.   c                ó  € ^ RI HpHp V! 4       pVe	   V! W04      # \        RJ ;'       gG    T ;'       g=    \        ;QJ d     R \         4       F  '       g   K   RM	  RM! R \         4       4      pV'       d   \        4       s\        # )zPThe active scope's dashboard plugins: a secondary profile's are its own (PLG-3).)Úprofile_dashboard_pluginsÚsecondary_profile_homeNc              3   ól   "  € T F*  p\        VR ,          4      P                  4       '       * x € K,  	  R# 5i)Ú_dirN)r   Úis_dir©Ú.0Úps   & r,   Ú	<genexpr>Ú)_get_dashboard_plugins.<locals>.<genexpr>î  s,   é € ð DÙ.F¨ŒD��6•‹O×"Ñ"Ó$×$Ñ$Ó.Fùs   ‚24TF)Ú%hermes_cli.web_server_plugin_profilesr£  r¤  Ú_dashboard_plugins_cacheÚanyrq  )r¡  r£  r¤  r4   Ústales   &    r,   Ú_get_dashboard_pluginsr±  ç  sƒ   € ÷ hÙ!Ó#€DØÒÙ(¨Ó<Ð<Ü$¨Ð,÷ ð °÷ ð ÇÃñ DÝ.FóDÇÇÂñ DÝ.FóDó A€E÷ Ü#>Ó#@Ð Ü#Ð#r.   )ÚfilesÚgitÚlocal_modelsr?  ÚactionsÚaudioÚdisplayÚsessionsÚprofilesÚmemory_providersÚ
config_envÚmodelsÚ	messagingÚoauthÚcronÚmcpÚopsÚskillsÚtoolsÚ	analyticsÚchat_wsÚchat_workspacesÚdashboard_uiÚshared_metricsÚ
delegationc                ó0   € V ^8„  d   QhR\         R\         /# )r%   râ   r'   rŠ   )r+   s   "r,   r-   r-   ?  s   € ÷ Rñ R¤Cð R¬Cñ Rr.   c                óÎ  € . p ^ RI Hp VP                  '       d   VP                  RVP                   24       T \
        9   d$   Rp ^ RIHp T! 4       pRT;'       g    R R2pRpMR	T  R
2pRpTR,          p ^ RIH	p ^ RI
Hp T! 4       p	T	P                  R4      ;'       g    / P                  R4      ;'       g    / p
T	P                  R4      ;'       g    / P                  R4      ;'       g    . p\        T
P                  R4      4      ;'       d4    \        T
P                  R4      ;'       g    T
P                  R4      4      pT'       d"   \        T4      T,          '       d
   RT,           pRT  RT R2pT'       d'   TRRP                  T4      ,           R,           ,          pYÖ,           #   \         d     EL†i ; i  \         d     EL}i ; i  \         d     Lpi ; i)a[  Actionable SystemExit text for a gated bind with no registered auth provider.

Names the exact trigger: on a loopback bind the ONLY trigger is
dashboard.public_url, so print the offending URL and the remove-it exit.
Bundled providers expose ``LAST_SKIP_REASON`` so an installed-but-
unconfigured provider is not reported as merely "no providers".
)Únousu     â€¢ nous: r½   )Úresolve_public_urlzdashboard.public_url is set to z<a non-loopback URL>uT    â€” an operator-declared external URL engages the auth gate even on a loopback bindz¾If this dashboard should be LOCAL-ONLY (no reverse proxy), remove dashboard.public_url from config.yaml (and unset HERMES_DASHBOARD_PUBLIC_URL) to restore the unauthenticated loopback mode.
z-the auth gate engages on non-loopback binds (Ú)uT  Configure an auth provider before exposing the dashboard:
  â€¢ Password: set dashboard.basic_auth.username + password_hash in config.yaml
    (hash with: python -c "from plugins.dashboard_auth.basic import hash_password; print(hash_password('your-password'))")
  â€¢ OAuth: run `hermes dashboard register` (Nous Portal) or install a DashboardAuthProvider plugin.
There is no unauthenticated public-dashboard option. For local-only use, bind 127.0.0.1 and leave dashboard.public_url unset; a configured external public URL requires auth even when a local reverse proxy reaches a loopback backend.r   )Ú_BASIC_AUTH_PLUGIN_KEYSÚ	dashboardÚ
basic_authÚpluginsÚdisabledÚusernameÚpassword_hashÚpasswordzËThe 'basic' dashboard-auth plugin is in plugins.disabled but dashboard.basic_auth is configured.
Remove 'basic' from plugins.disabled (or run `hermes plugins enable basic`), then restart the dashboard.

zRefusing to bind dashboard to u    â€” z), but no auth providers are registered.

z)Bundled providers reported these issues:
rŸ   z

)Úplugins.dashboard_authrÌ  ÚLAST_SKIP_REASONr*  rY   rÚ   Ú hermes_cli.dashboard_auth.prefixrÍ  Úhermes_cli.configr   Úhermes_cli.plugins_cmdrÏ  r�   r*   Úsetr¨   )râ   Úskip_reasonsÚ_nous_pluginÚ
public_urlrÍ  Úgate_reasonÚfix_hintÚ	_load_cfgrÏ  ÚcfgÚbarÓ  Ú	has_credsÚmsgs   &             r,   Ú_no_auth_provider_messagerç  ?  sø  € ð !€LðÝ?à×(×(Ð(Ø×Ñ ,¨|×/LÑ/LÐ.MÐ NÔOð Ô$Ô$Øˆ
ð	ÝKá+Ó-ˆJð .Ø×3Ð3Ð3Ð4ð 5&ð'ð 	ð/ñ 	ð FÀdÀVÈ1ÐMˆØˆàð	Aõ€Hð Ý>ÝBá‹kˆØ�g‰g�kÓ"×(Ð( b×-Ñ-¨lÓ;×AÐA¸rˆØ—G‘G˜IÓ&×,Ð,¨"×1Ñ1°*Ó=×CÐCÀˆÜ˜Ÿ™ 
Ó+Ó,×dÐd´°b·f±f¸_Ó6M×6cÐ6cÐQS×QWÑQWÐXbÓQcÓ1dˆ	ßœ#˜h›-Ð*A×AÔAð!ð õˆHð )¨¨¨e°K°=ð A4ð 	5ð ÷ ØÐ;¸d¿i¹iÈÓ>UÕUÐX^Õ^Õ^ˆØ�>ÐøôI ô Úðûô ô 	Úð	ûôf ô Ùðúsd   „F2 œF2 ÁG Á:*G Â%G Â>G ÃG Ã2#G ÄG Ä4G Å!G Æ2GÇ GÇGÇGÇG$Ç#G$c          
      óx   € V ^8„  d   QhR\         R\        R\        \         ,          R\        \         ,          RR/# )r%   râ   Úallow_publicÚssh_session_tokenÚssh_owner_noncer'   N)r)   r*   r
   )r+   s   "r,   r-   r-   ”  sB   € ÷ 3
ñ 3
Ü
ð3
äð3
ô  ¤•}ð3
ô œc•]ð	3
ð
 
ñ3
r.   c           	     ó‚  € \        4       \        P                  n        \	        WV4      '       d5   \        V 4      \        P                  n        \        P                  R4       M7\        V \        P                  P                  4      \        P                  n        V'       d"   V \        9  d   \        P                  RV 4       \        P                  P                  '       d\   ^ RIHp V! 4       '       g   \        \        V 4      4      h\        P                  RV RP!                  R V! 4        4       4      4       R# R# )zÄResolve the trusted public hosts + auth-gate flag onto ``app.state``.

Fails closed (``SystemExit`` with an actionable message) when the gate
engages but no dashboard auth provider is registered.
z�Desktop-owned loopback backend: dashboard.public_url does not engage the ticket gate for this process; the public deployment keeps its own gate.u  --insecure no longer bypasses dashboard authentication. A non-loopback bind (%s) now ALWAYS requires an auth provider (OAuth or the bundled password provider). Configure one â€” see below â€” or bind to 127.0.0.1 and reach it over an SSH tunnel / Tailscale.)Úlist_providersz=Dashboard binding to %s with auth gate enabled. Providers: %sz, c              3   ó8   "  € T F  qP                   x € K  	  R # 5irB   )r&   r¨  s   & r,   r«  Ú'_configure_auth_gate.<locals>.<genexpr>Æ  s   é € Ð7Ñ&6 —f–fÓ&6ùs   ‚N)rÛ   rn   rq   rã   rÜ   rà   rÑ   rZ   rb   ræ   rÚ   r[   Úhermes_cli.dashboard_authrí  Ú
SystemExitrç  r¨   )râ   ré  rê  rë  rí  s   &&&& r,   Ú_configure_auth_gaterò  ”  sä   € ô &=Ó%>„C‡I�IÔ"ô % T¸o×NÒNô #6°dÓ";Œ�	‰	ÔÜ�	‰	ð"õ	
ô #@ÀÄcÇiÁi×FdÑFdÓ"eŒ�	‰	Ô÷ ˜Ô$9Ô9Ü�‰ðð ô	
ô ‡y�y××Ðå<Ù×ÒÜÔ6°tÓ<Ó=Ð=Ü�	‰	ØKØØ�I‰IÑ7¡nÔ&6Ó7Ó7ö	
ñ r.   Ússh_isolatedc                ó<   € V ^8„  d   QhR\         R\        R\        /# )r%   râ   Úportró  )r)   r;   r*   )r+   s   "r,   r-   r-   Ê  s&   € ÷ @*ñ @*¤ð @*¬3ð @*Äñ @*r.   c               óZ  a€ ^ RI pV \        9   p \        4       P                  R4      ;'       g    / oR
R V3R lllp\
        pV'       d   RMV! R4      V! R4      3w  rxV'       dN   ^ RIHp	Hp
H	pH
p V! 4       \
        P                  n        V! \
        \
        P                  P                  4      pYšr‡\        4        VP                  W`VRR\        \
        P                  P                   4      \#        S4      VV\$        ^R	7      pWÓP'                  V4      3#   \         d    / o Löi ; i)a±  Build the uvicorn ``Config`` + ``Server`` for this bind (reads ``app.state.auth_required``).

uvicorn.Server is driven directly (not uvicorn.run) so startup is split from
the main loop: after startup() the socket is bound and held by uvicorn, so the
OS-assigned port can be read with no pre-bind-then-close TOCTOU. Explicit
taken ports are caught by the #93608 preflight probe; uvicorn's own bind
error stays the fallback for races.
NrÐ  c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r%   Úkeyr2   r'   )r)   r  )r+   s   "r,   r-   Ú+_build_uvicorn_server.<locals>.__annotate__ã  s!   € ÷ ñ œcð ¬Eð ¼Uñ r.   c                 ól   <€  \        SP                  W4      4      #   \        \        3 d    Tu # i ; irB   )r  r�   Ú	TypeErrorÚ
ValueError)rø  r2   Ú	_dash_cfgs   &&€r,   Ú_ws_ping_settingÚ/_build_uvicorn_server.<locals>._ws_ping_settingã  s5   ø€ ð	Ü˜Ÿ™ sÓ4Ó5Ð5øÜœ:Ð&ô 	ØŠNð	ús   ƒ �3²3Úws_ping_intervalÚws_ping_timeout)ÚTUNNEL_WS_PING_INTERVAL_SÚTUNNEL_WS_PING_TIMEOUT_SÚIdleClientTrackerÚwrap_asgi_with_ws_trackingr[   )
râ   rõ  Ú	log_levelÚ
log_configÚproxy_headersÚforwarded_allow_ipsr   r  Úws_max_sizeÚtimeout_graceful_shutdown)g      4@)NN)ÚuvicornrÚ   r   r�   rY   rn   Úhermes_cli.web_server_idle_exitr  r  r  r  rq   Ússh_isolated_clientsr    ÚConfigr*   rÑ   r   rÙ   ÚServer)râ   rõ  ró  r  Ú_is_loopbackrþ  Ú
served_appÚping_intervalÚping_timeoutr  r  r  r  Úconfigrý  s   &&$           @r,   Ú_build_uvicorn_serverr  Ê  s  ø€ ó ð Ô0Ñ0€LðÜ“M×%Ñ% kÓ2×8Ð8°bˆ	÷ò ô €Jß2>¡,ÙÐ+Ó,Ñ.>Ð?PÓ.QðESÑ€Mç÷	pó 	pá):Ó)<Œ�	‰	Ô&Ù/´´S·Y±Y×5SÑ5SÓTˆ
Ø&?�|äÔØ�^‰^Ø D°IÈ$ô œ3Ÿ9™9×2Ñ2Ó3ô ;¸9ÓEØ&Ø$Ü4ð
 #$ð! ó €Fð$ —>‘> &Ó)Ð)Ð)øôU ô ØŠ	ðús   �D °D ÄD*Ä)D*c                ó(   € V ^8„  d   QhR\         RR/# )r%   Úwhatr'   NrŠ   )r+   s   "r,   r-   r-     s   € ÷ 0ñ 0”sð 0 4ñ 0r.   c                ót   €  V! 4        R#   \          d"   p\        P                  RY4        Rp?R# Rp?ii ; i)zNRun a best-effort startup step; any failure (import included) is a debug line.z%s skipped: %sN)rY   rZ   rh  )r  ÚfnrS  s   && r,   Ú_best_effortr    s.   € ð0Ù
ŽøÜô 0Ü�
‰
Ð# T×/Ò/ûð0ús   ‚ ‹7–2²7c                ó0   € V ^8„  d   QhR\         R\        /# )r%   Úroler'   r(   )r+   s   "r,   r-   r-     s   € ÷ ñ ¬Cð ´Dñ r.   c                óÆ  € ^ RI Hp ^ RIHp  VP	                  V 4      pTf    \        TP                  T 4      4      # TP                  \        P                  ! 4       8X  d   R#  T! TP                  TP                  4      f   R#   TP                  T 4       R#   \
         d     R# i ; i  \
         d     R# i ; i  \
         d     R# i ; i  \
         d     R# i ; i)a—  True when the conflicting host owner was reaped/cleared and the claim is worth retrying.

HELD_BY_OTHER helper for #121964. A stale record with no live owner is retracted via
``discard_dead_record`` (which only removes provably-gone owners); a live owner is reaped
only when the spawn ledger proves it is a dead session's orphan. Anything else returns
False and the caller stays observe-only. Never raises.
©Úhost_rendezvous)Úreap_orphaned_backend_ownerFT)Úgatewayr   Úhermes_cli.process_identityr!  Úread_recordrY   r*   Údiscard_dead_recordr…  r�   r«   Úcreate_time)r  Úhrr!  Úowners   &   r,   Ú!_reclaim_host_from_orphaned_ownerr)    sã   € õ .ÝGðØ—‘˜tÓ$ˆð ‚}ð	Ü˜×.Ñ.¨tÓ4Ó5Ð5ð ‡y�y”B—I’I“KÔÙðÙ& u§y¡y°%×2CÑ2CÓDÒLÙð MðØ
×Ñ˜tÔ$ñ øô% ô Úðûô
 ô 	Úð	ûô ô Úðûô ô ØÙðúsF   ŽB ¤B- Á%B? ÂC ÂB*Â)B*Â-B<Â;B<Â?CÃCÃC ÃC c                ó4   € V ^8„  d   QhR\         R\        RR/# ©r%   râ   rõ  r'   N©r)   r;   )r+   s   "r,   r-   r-   7  s!   € ÷ 3ñ 3¤3ð 3¬cð 3°dñ 3r.   c                ó>  € ^ RI Hp \        4       pV'       d   VP                  MVP                  pVP                  V4      w  rVWRP                  P                  J d   \        P                  RV4       R# WRP                  P                  J d-   V'       g%   \        V4      '       d   VP                  V4      w  rVWRP                  P                  J d}   VP                  V4      pV'       d3   \        P                  RTV'       d   VP                  V4      MR4       R# \        P                  RV'       d   VP                  V4      MR4       R# V\        P                   n        VP%                  VV VVP'                  4       \(        R7       VP+                  V4       R# )z�Publish this backend's host record: ``ROLE_SERVE`` for the machine-level owner,
``ROLE_DESKTOP_SERVE`` for a Desktop-owned child.r  zuHost backend lock could not be opened (%s); this backend is not discoverable. This is NOT another backend holding it.Nz0another Desktop backend holds the %s record (%s)zowner unknownz‡Another backend already owns this host (%s); this one bound anyway (observe-only). Multiplex-only expects exactly one backend per host.)râ   rõ  r¹  r”   )r"  r   r   ÚROLE_DESKTOP_SERVEÚ
ROLE_SERVEÚclaim_host_lockÚHostLockOutcomeÚCOULD_NOT_OPENrZ   r[   ÚHELD_BY_OTHERr)  r$  rh  Údescribern   rq   Ú	host_roleÚpublish_recordÚserved_profilesr–   Úcleanup_on_exit)râ   rõ  r'  Údesktop_childr  ÚoutcomeÚerrorr(  s   &&      r,   Ú_publish_host_rendezvousr<  7  sJ  € õ .ä,Ó.€Mß$1ˆ2× Ò °r·}±}€Dà×'Ñ'¨Ó-�N€GØ×$Ñ$×3Ñ3Ó3Ü�‰ð6Ø7<ô	>ñ 	Ø×$Ñ$×2Ñ2Ó2¿=ô
 -¨T×2Ò2Ø×/Ñ/°Ó5‰NˆGØ×$Ñ$×2Ñ2Ó2Ø—‘˜tÓ$ˆßä�J‰JÐIÈ4ß-2�r—{‘{ 5Ô)¸ôIáÜ�‰ðSç"'ˆB�K‰K˜Ô¨_ô	
ñ
 	Ø„C‡I�IÔØ×ÑØØØØ×#Ñ#Ó%ô ð ô ð ×Ñ�tÖr.   Ússh_lock_pathc                ó’   € V ^8„  d   QhR\         R\        R\        R\        R\        R\         R\        R\        \        ,          R	R
/	# )r%   râ   rõ  ÚheadlessÚisolatedÚopen_browserÚinitial_profileÚstart_mcp_discovery_after_bindr=  r'   N©r)   r;   r*   r
   r   )r+   s   "r,   r-   r-   m  s€   € ÷ [Wñ [Wô ð[Wô ð	[Wô
 ð[Wô ð[Wô ð[Wô ð[Wô %)ð[Wô œD•>ð[Wð 
ñ[Wr.   c               óø  aaaaaaaaa€ R R lp	R R lp
\        4       '       d   \        RV	4       \        RV
4       \        4        \        \        P
                  RR4      ei   ^ R	IHpHp  \        \        4       P                  R
4      ;'       g    / P                  RV4      4      pV! V \        P
                  P                  VR7       \        \        P
                  RR4      f   \        4       '       d   ^ RIHp V! V 4       \        \        P
                  RR4      e)   V'       d!   \"        '       d   ^ RIHp V! W\"        R7       \)        WR7      oS\        P
                  n        S'       * \        P
                  n        R VVVVV3R llp\        RV4       \        RVV3R l4       \/        S4       S'       d   \1        RS 24       \1        RS 24       M\1        RS 24       S'       d   \3        RS RS 2RR7       M^ RIHp \3        RV! S4       RS 24       \9        SSVS4       V'       d    ^ RIHp V! \>        R\@        R 7       R# R$ lp\        R%V4       R&oR'o\F        PH                  ! 4       oR( VVVV3R) lloSPK                  SSSPM                  4       S,           4       R#   \        \        3 d    Tp EL&i ; i  \B         d    \>        PE                  R!RR"7        LŸi ; i)*zâPost-bind arming on the serving loop right after ``server.startup()``.

Reap prior corpses, parent-death watchdog, process identity, READY
announcement, browser open, deferred MCP discovery, loop-noise filter,
loop heartbeat.
c                ó   € V ^8„  d   QhRR/# rZ  rN   )r+   s   "r,   r-   Ú(_on_server_started.<locals>.__annotate__ƒ  s   € ÷ .ñ . $ñ .r.   c                  ó    € ^ RI Hp  V ! 4        R# )r7  ©Ú#_reap_orphaned_desktop_local_servesN)Úhermes_cli.dashboard_procsrJ  rI  s    r,   Ú_reap_desktop_servesÚ0_on_server_started.<locals>._reap_desktop_servesƒ  s   € ÝRá+Ö-r.   c                ó   € V ^8„  d   QhRR/# rZ  rN   )r+   s   "r,   r-   rG  ˆ  s   € ÷ $ñ $˜tñ $r.   c                  ó    € ^ RI Hp  V ! 4        R# )r7  ©Úreap_orphaned_mcp_helpersN)r#  rQ  rP  s    r,   Ú_reap_mcp_helpersÚ-_on_server_started.<locals>._reap_mcp_helpersˆ  s   € ÝIá!Ö#r.   zorphan desktop-local serve reapzorphan MCP helper reapr  N)ÚDEFAULT_IDLE_GRACE_SÚstart_idle_watchdogrÐ  Ússh_isolated_idle_grace_s)Úgrace_s)Ústart_code_skew_watchdog)Ústart_owner_watchdog)Ú	lock_pathr™   )Úfallbackc                ó   € V ^8„  d   QhRR/# rZ  rN   )r+   s   "r,   r-   rG  ¹  s   € ÷ +ñ + ñ +r.   c                  ór   <€ ^ RI Hp Hp T! S'       d   RMRRSRSRS;'       g    RRS/R	7       V ! 4        R
# )r7  )Ú attach_self_to_kill_on_close_jobÚregister_selfÚserverÐ  râ   rõ  r  r½   r@  )rÖ   N)r#  r^  r_  )r^  r_  Úactual_portr?  râ   rB  r@  s     €€€€€r,   Ú_register_identityÚ._on_server_started.<locals>._register_identity¹  s<   ø€ ß_áß‰G [Ø˜D &¨+°yÀ/×BWÐBWÐUWÐYcÐemÐnõ	
ñ 	)Ö*r.   zprocess-identity registrationzhost rendezvous publishc                  ó   <€ \        SS 4      # rB   )r<  )ra  râ   s   €€r,   rC   Ú$_on_server_started.<locals>.<lambda>È  s   ø€ Ô4LÈTÐS^Ô4_r.   zHERMES_BACKEND_READY port=zHERMES_DASHBOARD_READY port=z  Hermes backend listening on Ú:T)Úflush)Úformat_url_hostu     Hermes Web UI â†’ http://)Údefer_background_mcp_discoveryzdashboard-mcp-discovery)ÚloggerÚthread_nameÚdelayz!Deferred MCP discovery arm failedrW   c                ó   € V ^8„  d   QhRR/# rZ  rN   )r+   s   "r,   r-   rG  ó  s   € ÷ >ñ > 4ñ >r.   c                  óH   € ^ RI Hp  V ! \        P                  ! 4       4       R# )r7  ©Úinstall_loop_noise_filterN)Útui_gateway.loop_noiserp  ry   Úget_running_loopro  s    r,   Ú_install_noise_filterÚ1_on_server_started.<locals>._install_noise_filteró  s   € ÝDá!¤'×":Ò":Ó"<Ö=r.   zloop noise filter installg       @g      @c                ó(   € V ^8„  d   QhR\         RR/# )r%   Úexpectedr'   Nr  )r+   s   "r,   r-   rG    s   € ÷ Oñ O¤%ð O¨Dñ Or.   c                 ó¦   <€ SP                  4       pW,
          pVS8”  d   \        P                  R V4       SP                  SSVS,           4       R# )z1event loop stalled %.1fs (GIL pressure suspected)N)r)  rZ   r[   Ú
call_later)rv  r+  ÚdriftÚ_hb_intervalÚ_hb_loopÚ_hb_stall_thresholdÚ_loop_heartbeats   &  €€€€r,   r}  Ú+_on_server_started.<locals>._loop_heartbeat  sD   ø€ Ø�m‰m‹oˆØ•ˆØÐ&Ô&Ü�L‰LÐLÈeÔTØ×Ñ˜L¨/¸3ÀÕ;MÖNr.   )'r   r  r   rp   rn   rq   r  rT  rU  r  r   r�   rû  rü  r  Úhermes_cli.web_server_skew_exitrX  r    Ú hermes_cli.web_server_owner_exitrY  r   Ú
bound_portÚ
serves_spar"   r#   ÚprintÚhermes_cli.url_utilsrh  r   Úhermes_cli.mcp_startupri  rZ   Ú_DESKTOP_MCP_DISCOVERY_DELAY_SrY   rh  ry   rr  rx  r)  )Úserverrâ   rõ  r?  r@  rA  rB  rC  r=  rL  rR  rT  rU  ÚgracerX  rY  rb  rh  ri  rs  rz  r{  r|  r}  ra  s   &d$dd$d$$           @@@@@r,   Ú_on_server_startedr‰  m  s€  ÿø€ õ,.õ
$ô
  ×!Ò!ÜÐ6Ð8LÔMô Ð)Ð+<Ô=ô !Ô"ô Œs�y‰yÐ0°$Ó7ÒCß]ð	)Üœ;›=×,Ñ,¨[Ó9×?Ð?¸R×DÑDÐE`ÐbvÓwÓxˆEñ 	˜F¤C§I¡I×$BÑ$BÈEÕRÜŒs�y‰yÐ0°$Ó7ÒCÔG_×GaÒGaõ 	Má  Ô(ÜŒs�y‰yÐ0°$Ó7ÒCÏ×ZjÓZjõ 	Já˜VÔDTÕUä" 6Ô9€KØ&„C‡I�IÔð  (œ<„C‡I�IÔ÷+ô +ô Ð0Ð2DÔEô Ð*Õ,_Ô`ä Ô,÷ Ü$Ð'AÀ+ÀÐ%OÔPÜ$Ð'CÀKÀ=Ð%QÕRä$Ð'CÀKÀ=Ð%QÔRßô 	Ð.¨t¨f°A°k°]ÐCÈ4ÖPå8äÐ+©O¸DÓ,AÐ+BÀ!ÀKÀ=ÐQÔRÜ˜˜k¨<¸ÔIç%ð
		KÝMá*ÜØ5Ü4õõ>ô
 Ð,Ð.CÔDð
 €LØÐÜ×'Ò'Ó)€H÷Oó Oð ×Ñ˜ o°x·}±}³ÈÕ7UÖVøô[ œ:Ð&ô 	)Ø(‹Eð	)ûôf ô 	KÜ�J‰JÐ:ÀTˆJÖJð	Kús*   Á.$J: ÂJ: É K Ê:KËKË"K9Ë8K9c                óv   € V P                  4       pVe   V\        P                  J d   \        P                  # V# )u—  Loop factory for serve on Windows: always a selector loop.

uvicorn 0.41's ``asyncio_loop_factory`` returns ProactorEventLoop on
win32, on which uvicorn's socket stack binds-but-never-accepts (READY
prints, then WinError 10014 accept failures, exit 1, desktop
ECONNREFUSED â€” #120164, regression of #50641). A factory that already
yields selector loops (older uvicorn, explicit ``--loop``) passes through.
)Úget_loop_factoryry   ÚProactorEventLoopÚSelectorEventLoop)r  rt   s   & r,   Ú_windows_serve_loop_factoryrŽ    s5   € ð ×%Ñ%Ó'€GØ‚˜'¤W×%>Ñ%>Ó>Ü×(Ñ(Ð(Ø€Nr.   c                ó4   € V ^8„  d   QhR\         R\        RR/# r+  r,  )r+   s   "r,   r-   r-     s!   € ÷ )ñ )¤Cð )¬sð )°tñ )r.   c                ó  € \         P                  p/ p\        P                  R8X  d    ^ RIHp R\        V4      /p V! V ! 4       3/ VB  R#   \         dR    \         P                  p/ p \         P                  ! \         P                  ! 4       4        LZ  \         d      Lhi ; ii ; i  \         d     R# \         dD   pTP                  ^8X  d-   \        Y#4      '       d   \        Y#4       \        \        4      Rhh Rp?ii ; i)aŸ  Drive ``serve()`` on the loop uvicorn expects.

POSIX keeps ``asyncio.run`` (already a SelectorEventLoop / uvloop). On
Windows ``asyncio.run`` defaults to a ProactorEventLoop, on which uvicorn
binds a socket that never accepts (#50641), so mirror uvicorn's own runner +
loop factory there (hand-installed selector policy for uvicorn < 0.36).
Ctrl+C -> clean return; probe-to-bind port race -> sentinel + exit code.
Úwin32)Úasyncio_runÚloop_factoryN)ry   ÚrunÚsysÚplatformÚuvicorn._compatr’  rŽ  rY   Úset_event_loop_policyÚWindowsSelectorEventLoopPolicyÚKeyboardInterruptrñ  Úcoder   r   r   )r`  r  râ   rõ  ÚrunnerÚrunner_kwargsrS  s   &&&&   r,   Ú
_run_serverž    sé   € ô �[‰[€FØ€MÜ
‡|�|�wÔð	Ý=à+Ô-HÈÓ-PÐQˆMð
Ù‰u‹wÑ(˜-Ô(øô ô 	Ü—[‘[ˆFØˆMðÜ×-Ò-Ü×:Ò:Ó<öøô ô Úðúð	ûô ô ÚÜô ð �8‰8�qŒ=Ô0°×<Ò<Ü Ô+ÜÔ2Ó3¸Ð=ØûðúsL   ©A ½B, ÁB)Á+)BÂB%Â!B)Â$B%Â%B)Â,DÂ:DÃDÃ>DÄDc                óÞ   € V ^8„  d   QhR\         R\        R\        R\        R\         R\        R\        R\        \         ,          R	\        \         ,          R
\        R\        \        ,          /# )r%   râ   rõ  rA  ré  rB  r?  r@  rê  rë  rC  r=  rD  )r+   s   "r,   r-   r-   F  s�   € ÷ x+ñ x+Ü
ðx+ä
ðx+ô ðx+ô ð	x+ô
 ðx+ô ðx+ô ðx+ô  ¤•}ðx+ô œc•]ðx+ô %)ðx+ô œD•>ñx+r.   c           
     ó4  a aaaaaa	a
aa€ \        T;'       g    R4       \        V4       ^ RIHp V! 4        ^ RIp ^ RIHp V! 4        \        S W7V4       S \        P                  n        \        S;'       g    R4      \        P                  n        \!        S S\#        V4      R7      w  oo ^ RIHp V! 4        \)        S S4      '       d   \+        S S4       \-        \.        4      h ^ R	IHp V! 4        VVV VVVVVV
V	3
R lp\7        VSS S4       R#   \         d!   p\        P                  RT4        Rp?LòRp?ii ; i  \         d!   p\        P                  RT4        Rp?L®Rp?ii ; i  \         d    \        P5                  R
RR7        LŸi ; i)a  Start the web UI server.

``initial_profile`` is appended to the auto-opened URL as ``?profile=<name>``
(profile alias ``<profile> dashboard``). ``headless`` is the ``serve`` path:
JSON-RPC/WS backend, no UI build, no SPA mount (``HERMES_SERVE_HEADLESS``).
``isolated`` (``--isolated``) is recorded in the spawn ledger so attach-first
discovery never adopts this process.
``ssh_session_token``/``ssh_owner_nonce`` are process-local Desktop SSH
bootstrap state, never persisted or exported to children; ``ssh_lock_path`` is the
Desktop's ``backend.lock.json`` for that ownership slot (supersession watchdog).
``start_mcp_discovery_after_bind`` (Desktop ``serve``) defers MCP discovery
until the ready sentinel is written so its SDK import can't hold the GIL
against the pre-bind path.
r½   )Úapply_nofile_soft_limitN)Ústart_nous_auth_keepalivez%Nous auth keepalive did not start: %s)ró  )Ú"install_exit_flush_signal_handlersz,exit-flush signal handlers not installed: %s)Ú&activate_multi_profile_hosting_eagerlyz%eager multi-profile activation failedTrW   c               “   ó<  <
"  € SP                   '       g   SP                  4        SP                  S4      Sn        SP	                  4       ;_uu_ 4        SP                  4       G R j  x€L
  SP                  '       d    R R R 4       R # \        SSSSSSSS
S	R7	       S'       d   ^ RIH	p  V ! RRR7       SP                  4       G R j  x€L
  SP                  '       d   SP                  4       G R j  x€L
  R R R 4       R #  L™ L: L  + '       g   i     R # ; i5i)N)râ   rõ  r?  r@  rA  rB  rC  r=  )Úrecord_process_readyÚ
serve_bootT)Ú
background)ÚloadedÚloadÚlifespan_classr†   Úcapture_signalsÚstartupÚshould_exitr‰  Ú/hermes_cli.observability.shared_metrics_startupr¦  Ú	main_loopÚstartedÚshutdown)r¦  r  r?  râ   rB  r@  rA  rõ  r‡  r=  rC  s    €€€€€€€€€€r,   Ú_serveÚstart_server.<locals>._serve¡  sà   øé € à�}�}ˆ}Ø�K‰KŒMØ ×/Ñ/°Ó7ˆŒØ×#Ñ#×%Õ%Ø—.‘.Ó"×"Ð"Ø×!×!Ð!Ø÷ &Ñ%ô
 ØØØØ!Ø!Ø)Ø /Ø/MØ+õ
÷ Ý`Ù$ \¸dÕCà×"Ñ"Ó$×$Ð$Ø�~�~ˆ~Ø—o‘oÓ'×'Ð'÷- &Ñ%Ù"ñ& %á'÷- &×%Ð%üsl   ƒADÁDÁ(DÁ)DÁ?DÂ 
DÂ
?DÃ	DÃ
DÃ DÃ3DÃ4DÃ8
DÄDÄDÄDÄD	Ä	D)r—   r²   Úhermes_cli.resource_limitsr¡  r  Úhermes_cli.nous_auth_keepaliver¢  rY   rZ   rh  rò  rn   rq   rë   r)   rB  r  r*   Útui_gateway.serverr£  r   r   rñ  r   Ú!tui_gateway.launch_profile_policyr¤  r[   rž  )râ   rõ  rA  ré  rB  r?  r@  rê  rë  rC  r=  r¡  r  r¢  rS  r£  r¤  r³  r  r‡  s   fff&fff&&ff       @@r,   Ústart_serverr¹  F  sX  ÿù€ ô6 Ð.×4Ð4°"Ô5Ü˜?Ô+õ CáÔãðAÝLá!Ô#ô ˜˜|ÀÔPð  „C‡I�IÔô !$ O×$9Ð$9°rÓ :„C‡I�IÔä*¨4°ÄDÐIZÓD[Ô\�N€FˆFðHÝIá*Ô,ô ˜4 ×&Ò&Ü˜D $Ô'ÜÔ.Ó/Ð/ðMÝ\á.Ô0÷(ö (ô: ˆv�v˜t TÖ*øô] ô AÜ�
‰
Ð:¸C×@Ñ@ûðAûô, ô HÜ�
‰
ÐAÀ3×GÑGûðHûô0 ô MÜ�‰Ð<ÀtˆÖLðMúsA   ½D Â/E Ã*E2 ÄEÄ!D<Ä<EÅE/ÅE*Å*E/Å2"FÆFc                ó°  € V ^8„  d   Qh/ ^ \         9   d   \        \        ,          ;R&   ^\         9   d+   \        \        \        \        \        3,          ,          ;R&   ^\         9   d   \        \        ,          ;R&   ^\         9   d   \
        \        ,          ;R&   ^\         9   d&   \        \        \        \        ,          3,          ;R&   ^\         9   dB   \        \        \        \        P                  \        \        R3,          3,          ,          ;R&   ^\         9   d   \        \        ,          ;R&   ^\         9   d   \        \        ,          ;R	&   # )
r%   r    r¡   r¢   rÉ   r|  .r�  rž  r®  )Ú__conditional_annotations__r
   r)   r€  r;   rä   r€   r  r�  r‚  rI   )r+   s   "r,   r-   r-      s   € ÷ ñ ÷D 'Ò &”(œ3•-Ñ &ñE÷F <Ò ;”hœu¤S¬#¬s ]Õ3Õ4Ñ ;ñG÷H *Ò )”Xœc•]Ñ )ñI÷f	 LÒ Kœ	¤#�Ñ Kñg	÷P LÒ K”4œœX¤c�]Ð*Õ+Ñ KñQ÷@ XÒ W”x¤¤e¬Z×-=Ñ-=¼uÄSÈ#ÀX½Ð&NÕ OÕPÑ WñA÷b -Ò ,œ¤�Ñ ,ñc÷F 0Ò /œ(¤4�.Ñ /òGr.   )é<   rB   i  @i   i   )F)z	127.0.0.1iŸ#  TFr½   FFNNFN)ør»  rI  Ú
contextlibr   ry   Úcollectionsr   rÁ   Úloggingr�   Úrer�   r�  r•  r£   r9   r)  Úurllib.parseÚurllibÚhermes_cli.install_identityr   r{  r#  r   Úhermes_cli.pty_sessionr   Úpathlibr   Útypingr   r	   r
   r   Ú__file__ÚparentÚresolveÚPROJECT_ROOTr)   r§   ÚinsertrÚ  r   Úhermes_cli.version_infor   Úfastapir   r   r   Úfastapi.middleware.corsr   Úfastapi.responsesr   r_  Úpmr   rY   rñ  rŽ   ÚWEB_DISTÚ	getLoggerrE  rZ   Úhermes_cli.web_server_lifecycler   r   r   r   r   r   r   r   r    r!   r"   r#   r5   rk   r†  Úhermes_cli.web_server_apprl   rv   r~   rƒ   Úbase_versionrn   Ú$hermes_cli.dashboard_auth.body_limitr‡   Úadd_middlewareÚhermes_cli.memory_oauthrˆ   Ú_memory_oauth_routerÚinclude_routerr’   r–   rÀ   r    r¡   r¢   r—   r²   r¸   Ú _DASHBOARD_EMBEDDED_CHAT_ENABLEDÚ&hermes_cli.dashboard_auth.public_pathsr¹   r  rÆ   rä   rÉ   rË   rØ   Úhermes_cli.web_server_boundaryrÙ   rÚ   rÛ   rÜ   rÝ   rÞ   rß   rà   ræ   Ú
middlewarerï   Úhermes_cli.web_server_dashboardrð   rñ   rò   r­  ró   rô   rü   r  r  r  rJ  r  rP  rT  rj  rb  re  rk  Ú
hermes_clirl  r‡  Úhermes_cli.web_server_gatewayrm  rn  Úhermes_cli.web_server_sessionsro  Úhermes_cli.web_server_chatrp  rq  rr  rs  ÚgetenvÚ_GATEWAY_HEALTH_URLÚ_GATEWAY_HEALTH_TIMEOUT_MAXr  Ú_GATEWAY_HEALTH_TIMEOUTrü  rû  r[   Ú_MANAGED_FILE_MAX_BYTESÚ_FS_DATA_URL_MAX_BYTESÚ_UPLOAD_CHUNK_BYTESr|  ÚRLockÚ_CONFIG_MUTATION_LOCKr�  r�  rš  rž  rŸ  Ú
setdefaultr®  r±  Úhermes_cli.web_routersr²  Ú_files_routesr³  Ú_git_routesr´  Ú_local_models_routesr?  Ú_status_routesrµ  Ú_actions_routesr¶  Ú_audio_routesr·  Ú_display_routesr¸  Ú_sessions_routesr¹  Ú_profiles_routesrº  Ú_memory_providers_routesr»  Ú_config_env_routesr¼  Ú_models_routesr½  Ú_messaging_routesr¾  Ú_oauth_routesr¿  Ú_cron_routesrÀ  Ú_mcp_routesrÁ  Ú_ops_routesrÂ  Ú_skills_routesrÃ  Ú_tools_routesrÄ  Ú_analytics_routesrÅ  Ú_chat_ws_routesrÆ  Ú_chat_workspaces_routesrÇ  Ú_dashboard_ui_routesrÈ  Ú_shared_metrics_routesrÉ  Ú_delegation_routesÚstatus_routerÚlist_routerÚsessions_routerÚsearch_routerÚconfig_routerÚmanage_routerÚlogs_routerÚ
hub_routerÚ hermes_cli.dashboard_auth.routesÚ_dashboard_auth_routerrç  rò  r  r  r)  r<  r‰  rŽ  rž  r¹  r-   )r»  s   @r,   Ú<module>r     s  øðöõ +ã Ý Û Û Û 	Û 	Û Û Û 
Û Û Û Û å PÝ @Ý -Ý ß -Ó -ñ �H‹~×$Ñ$×+Ñ+×3Ñ3Ó5€Ù€|Ó˜CŸH™HÔ$Ø‡H�H‡O�O�A‘s˜<Ó(Ô)å )Ý 4ð
ß7Ñ7Ý6Ý.ð& 3DÀrÇzÁzÔ2Q‰4�—
‘
Ð,Õ-Ô.ÑW[Ð\dÓWe×WlÑWlÐoyÕWy€Ø×Ò˜Ó"€÷÷ ÷ ó õ D÷Q/ðl "%Ð õ 3õõCõEñ �NÑ,<Ó,>×,KÑ,KÐVbÔc€å Hð × Ñ Ð*Ô +õ Cà × Ñ Ð'Ô (õ
Yñ (Ó)€Ø/Ð Ø"&Ð Ó &Ø7;Ð Ó ;Ø%)Ð Ó )õõõ85ð$ $(Ð  õ
 YõSñ  *3Ð4IÐ3JÓ)KÐ Ó KõXõD÷2	÷ 	ó 	÷Wð ‡��Óô$ó ð$÷.ñ ÷ ið ‡��Óô$ó ð$ð< × Ñ Ð)Ô *ð ‡��Óô;ó ð;ð ‡��Óô$ó ð$ð, ‡��Óô?ó ð?ð  $)Ð  ÷,
ñ ,
ñ^ #Ó$Ð ð ‡��Óô	ó ð	ð( × Ñ ØØDØ�%Ø�%ð	 ô ð (,Ð $Ø3Ð õ6õ)õ& :ß _Ý DÝ 3÷ñ ð
 —i“iÐ 4Ó5Ð Ø!Ð ð"Ù# B§I£IÐ.FÈÓ$LÓMÐð ˜aÔØ‡L‚LØXØôð "ÑØÐ:Ô:Ø‡L‚LØUØØ#ôð
 :Ðð ,Ð Ø)Ð ð "Ð ð 06°t¸WÀdÐ.KÐ Ó Kõ;ð "Ÿ›Ó)Ð ð $(Ð  ð TXÐ Ó Wñ(Èu÷ (ð (ð\ )-Ð Ó ,õ	ð × Ó Ð1Ð3RÔ Sð ,0Ð Ó /÷$÷"÷ ÷ ÷ ÷ ÷ õ ð8 × Ñ �=×'Ñ'Ô (Ø × Ñ �;×%Ñ%Ô &Ø × Ñ Ð'×.Ñ.Ô /Ø × Ñ �>×(Ñ(Ô )Ø × Ñ �?×)Ñ)Ô *Ø × Ñ �=×'Ñ'Ô (Ø × Ñ �?×)Ñ)Ô *Ø × Ñ �?×0Ò0Ô 1Ø × Ñ Ð#×/Ò/Ô 0Ø × Ñ Ð#×3Ò3Ô 4Ø × Ñ Ð#×1Ò1Ô 2Ø × Ñ Ð+×2Ñ2Ô 3Ø × Ñ Ð%×3Ò3Ô 4Ø × Ñ �>×(Ñ(Ô )Ø × Ñ Ð%×,Ñ,Ô -Ø × Ñ Ð$×+Ñ+Ô ,Ø × Ñ �=×'Ñ'Ô (Ø × Ñ Ð#×1Ò1Ô 2Ø × Ñ �>×-Ò-Ô .Ø × Ñ �<×&Ñ&Ô 'Ø × Ñ �;×%Ñ%Ô &Ø × Ñ �;×%Ñ%Ô &Ø × Ñ �>×,Ò,Ô -Ø × Ñ Ð#×*Ñ*Ô +Ø × Ñ �>×(Ñ(Ô )Ø × Ñ �=×'Ñ'Ô (Ø × Ñ Ð$×+Ñ+Ô ,Ø × Ñ �?×)Ñ)Ô *Ø × Ñ Ð*×1Ñ1Ô 2Ø × Ñ Ð'×.Ñ.Ô /Ø × Ñ Ð)×0Ñ0Ô 1Ø × Ñ Ð%×,Ñ,Ô -ñ
 Ô Ý Mà × Ñ Ð)Ô *Ù 	ˆ#„õRõj3
ðl@*È÷ @*õF0õõD3ðl[Wð %)÷[Wò|õ)÷Xx+ñ x+øðw( ô 
ð
Ý$Ù�eÔ÷	
ñ 	
õ 	;ß2Ð2øØô 
Ùð9ó
ð 	
ð
úð
ûð~ 	�IÐô "Ø‡L‚LØHØ
�	‹	Ð*Ó+ôð "Óð"ús0   Ãa  Í9b á bá$a/á/a?á?bâ/b9â8b9