+
    jHàjõÞ  ã                   ó	  a € RŸ t›0 t R t^ RIt^ RIt^ RI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Ht ^ RIHt ^ RIHtHtHtHtHtHt ^ RIHtHtH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* ^ RI+H,t, ^ RI-H.t. ^ RI/H0t0H1t1H2t2 ^ RI3H4t4 ^ RI5H6t6H7t7H8t8 ^ RI9H:t: ^ RI;H<t<H=t=H>t>H?t?H@t@HAtAHBtBHCtCHDtDHEtE ^ RI/HFtFHGtG ]
P�                  ! R4      tI]J! 4       tK] ^ k R R ltL]! 4       tM]! 4       tN]"! RR4      tO]"! RR4      tP]"! RR4      tQR R ltRR R  ltSR! R" ltTR R# R$ lltUR% R& ltV]W! 4       tX]P²                  R']Z3R(][3/R) R* ll4       t\R+ R, lt]R-R/R. R/ llt^R0 R1 lt_R2 R3 lt`R4 R5 ltaR6 R7 ltbR8 R9 ltcR: R; ltdR< R= lteR>tf^ tgR?th]! 4       ti]PÔ                  ! 4       tkR@ RA ltlRB RC ltmRD tnRE toRF tpRG RH ltqRI RJ ltrRK RL ltsRM RN lttRO RP ltuRQ tvRR RS ltw]MPñ                  RT4      ]! ^^ RURV7      ]! ^ ^ RW7      ^ RXRYRZRRRR[3
R\ R] ll4       ty]MPñ                  R^4      ]vR¡R_ R` ll4       4       tzRa Rb lt{Rc Rd lt|]MPñ                  Re4      ]vR¢Rf Rg ll4       4       t}]Pü                  ! Rh4      tRi Rj lt€]MEP                  Rk4      R£Rl Rm ll4       t‚]EP                  ! ]Rn Ro7      Rp 4       t„]NPñ                  Rq4      Rr 4       t…]NEP                  Rq4      Rs Rt l4       t†]NPñ                  Ru4      Rv 4       t‡]NEP                  Ru4      Rw Rx l4       tˆ]NPñ                  Ry4      Rz R{ l4       t‰R¤tŠR| R} lt‹]NEP                  R~4      R R€ l4       tŒ]NEP                  R�4      R‚ Rƒ l4       tŽ]NEP                  R�4      R„ R… l4       t�]NPñ                  R†4      R‡ Rˆ l4       t‘]NEP%                  R†4      R‰ RŠ l4       t“]NEP%                  R‹4      RŒ R� l4       t”]NEP%                  RŽ4      R� R� l4       t•]NEP                  R‘4      R’ R“ l4       t–R” R• lt—]NEP                  R–4      R— R˜ l4       t˜]NEP                  R™4      Rš R› l4       t™]NPñ                  Rœ4      R� Rž l4       tšR# )¥a  Profiles dashboard routes.

Two routers because route order matters: ``sessions_router`` (/api/profiles/sessions*,
projects/tree, pull-requests) was registered long before the generic
``/api/profiles/{name}`` routes on ``router``; the original global registration order is
preserved rather than relying on Starlette's literal-before-param matching.

Shared helpers are reached via the late-binding seam in :mod:`hermes_cli.web_deps`
so a test's ``monkeypatch.setattr(<owning module>, "_helper", ...)`` keeps working.
N)Úcoalesced_read)ÚOrderedDict©ÚPath)ÚAnyÚCallableÚDictÚListÚOptionalÚTuple)Ú	APIRouterÚHTTPExceptionÚQuery)Úsubagent_listing_scope)Úlate)Úget_process_hermes_home)Ú ProfileIdentitySettlementPending)Ú_apply_main_model_assignmentÚ _normalize_main_model_assignmentÚ_validated_main_model_selection)Ú_strip_session_list_rows)Ú_CONFIG_MUTATION_LOCK)Ú_fallback_profile_dictsÚ_hub_action_nameÚ_write_profile_mcp_servers)Ú_open_session_db_at_path)ÚSTORAGE_CORRUPTÚnote_storage_errorÚstorage_state©Úrun_in_threadpool)
ÚProfileCreateÚProfileActiveUpdateÚProfileExportÚProfileImportÚProfileRenameÚProfileSoulUpdateÚProfileDescriptionUpdateÚProfileModelUpdateÚProfileDescribeAutoÚSessionPrScanBody)Ú_config_profile_scopeÚ_hermes_home_scopezhermes_cli.web_serverc                ó4   € V ^8„  d   QhR\         R\        RR/# )é   ÚprofileÚexcÚreturnN)ÚstrÚ	Exception)Úformats   "ÚD/home/ubuntu/.hermes/hermes-agent/hermes_cli/web_routers/profiles.pyÚ__annotate__r6   ?   s!   € ÷ 4ñ 4¤cð 4´	ð 4¸dñ 4ó    c                 ó�   € V \        V4      3pV\        9   d   R # \        P                  V4       \        P	                  RW4       R # )NzSprofile session read failed for %r (reported only in the response errors array): %s)r2   Ú_profile_read_warnedÚaddÚ_logÚwarning)r/   r0   Úkeys   && r5   Ú_warn_profile_read_errorr>   ?   s>   € Ø”C˜“HÐ
€CØ
Ô"Ô"ÙÜ×Ñ˜SÔ!Ü‡L�Lð %Ø&-ö4r7   Ú_cron_profile_homezhermes_cli.web_server_cronÚ_resolve_profile_dirzhermes_cli.web_server_profilesÚ_spawn_hermes_actionzhermes_cli.web_server_gatewayc                óF   € V ^8„  d   QhR\         \        \        3,          /# ©r.   r1   ©Údictr2   r   )r4   s   "r5   r6   r6   T   s   € ÷ ;ñ ;œd¤3¬ 8�nñ ;r7   c                 ó<  € \         P                  ! \        V 4      p/ R V! R R4      bR\        V! RR4      4      bR\	        V! RR4      4      bRV! RR4      bRV! RR4      bR\	        V! RR4      4      bR	\        V! R	^ 4      ;'       g    ^ 4      bR
\	        V! R
R4      4      bRV! RR4      ;'       g    RbR\	        V! RR4      4      bRV! RR4      ;'       g    RbRV! RR4      ;'       g    RbRV! RR4      bRV! RR4      bRV! RR4      bRV! RR4      RJb# )ÚnameÚ ÚpathÚ
is_defaultFÚmodelNÚproviderÚhas_envÚskill_countÚgateway_runningÚdescriptionÚdescription_autoÚdisplay_nameÚ	bot_titleÚdistribution_nameÚdistribution_versionÚdistribution_sourceÚ	has_aliasÚ
alias_path)Ú	functoolsÚpartialÚgetattrr2   ÚboolÚint)ÚinfoÚattrs   & r5   Ú_profile_to_dictr`   T   s�  € Ü×ÒœW dÓ+€Dð;Ø‘�V˜RÓ ð;Ø"(¬#©d°6¸2Ó.>Ó*?ð;à”d™4 ¨eÓ4Ó5ð;ð 	‘�g˜tÓ$ð;ð '1±$°zÀ4Ó2Hð;ð 	”4™˜Y¨Ó.Ó/ð	;ð
 	”s™4 ¨qÓ1×6Ð6°QÓ7ð;ð 	œ4¡Ð%6¸Ó >Ó?ð;ð 	‘t˜M¨2Ó.×4Ð4°"ð;ð 	œD¡Ð&8¸%Ó!@ÓAð;ð 	™˜^¨RÓ0×6Ð6°Bð;ð 	‘T˜+ rÓ*×0Ð0¨bð;ð 	™TÐ"5°tÓ<ð;ð 	¡Ð%;¸TÓ Bð;ð 	™tÐ$9¸4Ó@ð;ð 	‘T˜,¨Ó-°TÐ9ð;ð ;r7   c                ó0   € V ^8„  d   QhR\         R\         /# )r.   rG   r1   ©r2   )r4   s   "r5   r6   r6   g   s   € ÷ Dñ D¤ð D¬ñ Dr7   c                ó4   € \        V 4       V R8X  d   R# V  R2# )z@Return the shell command used to configure a profile in the CLI.Údefaultzhermes setupz setup)r@   ©rG   s   &r5   Ú_profile_setup_commandrf   g   s"   € ä˜ÔØ! YÔ.ˆ>ÐC°t°f¸F°OÐCr7   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r.   rI   r1   )r   r
   r2   )r4   s   "r5   r6   r6   m   s   € ÷ ñ œdð ¤x´¥}ñ r7   c                óº   € ^ RI Hp V P                  4       pV\        4       P                  4       8X  d   R# W!! 4       P                  4       8X  d   R# V P                  # )a‰  Map a profile directory onto the query name ``_config_profile_scope`` expects: None for
the process home (current-profile semantics: launch secret scope, no home override),
``"default"`` for the default root (its basename -- ``.hermes`` or a custom root -- is not a
profile name; launched from ``profiles/<name>`` the root is a *different* profile), the
directory name for ``profiles/<name>``.)Úget_default_hermes_rootNrd   )Úhermes_constantsri   Úresolver   rG   )rI   ri   Úresolveds   &  r5   Ú_scope_profile_namerm   m   sL   € õ 9Ø�|‰|‹~€HØÔ*Ó,×4Ñ4Ó6Ô6ÙØÐ*Ó,×4Ñ4Ó6Ô6ÙØ�9‰9Ðr7   c                ón   € V ^8„  d   QhR\         R\        R\        R\        \         ,          R\        RR/# )r.   Úprofile_dirrL   rK   Úvalidate_inÚbase_urlr1   N)r   r2   r
   )r4   s   "r5   r6   r6   |   s?   € ÷ ñ ¤dð ´cð Ä#ð ÔT\Ô]aÕTbð Ü#&ðØ04ñr7   c           
     óú  € ^ RI HpHp \        \	        T;'       g    T 4      4      ;_uu_ 4        \        W4      w  r\        V! 4       WV4      pRRR4       \        \	        V 4      4      ;_uu_ 4        \        ;_uu_ 4        V! 4       p\        VP                  R/ 4      X4      VR&   V! V4       RRR4       RRR4       R#   + '       g   i     L|; i  + '       g   i     L-; i  + '       g   i     R# ; i)aÜ  Write the main model assignment into ``profile_dir``'s config.yaml (HERMES_HOME-scoped)
through the same validated /model shape as ``POST /api/model/set``.

``validate_in`` is the home whose ``providers:``/``.env``/catalog vouch for the pick (default:
``profile_dir`` itself). Profile-create passes the dashboard's own home: the picker that offered
the model read THAT catalog, and a just-created profile has no credentials yet, so validating
in the empty profile rejected every non-env provider (anthropic, ollama, custom).

Both spans enter ``_config_profile_scope`` (home + secret scope), matching ``/api/model/set``:
once the dashboard has served a secondary profile, ``switch_model``'s ``key_env`` probe goes
through ``get_secret``, which fails closed without a scope and reports the provider as
unconnected (UnscopedSecretError class, #114676).

``base_url`` is the endpoint a bare ``custom``/``local`` pick binds to (a fresh profile's config
names none); other providers ignore it.)Úload_configÚsave_configNrK   )
Úhermes_cli.configrs   rt   r+   rm   r   r   r   r   Úget)	ro   rL   rK   rp   rq   rs   rt   ÚresultÚcfgs	   &&&&&    r5   Ú_write_profile_modelry   |   s²   € ÷" ;Ü	Ô2°;×3MÐ3MÀ+ÓN×	OÕ	OÜ:¸8ÓK‰ˆÜ0±³ÀÐQYÓZˆ÷ 
Pô 
Ô2°;Ó?×	@Õ	@×BWÖBWÙ‹mˆÜ3°C·G±G¸GÀRÓ4HÈ&ÓQˆˆG‰Ù�CÔ÷ CX×	@Ñ	@÷ 
P×	Oú÷ CX×BWú×	@×	@Ð	@ús/   ¯ CÁ3C)Â/C	Â1C)ÃC	ÃC&Ã!C)Ã)C:	c                óR   € V ^8„  d   QhR\         R\        \        ,          R\        /# )r.   ro   Úkeepr1   )r   Úlistr2   r]   )r4   s   "r5   r6   r6   —   s%   € ÷ ñ ¬Dð ¼¼S½	ð Äcñ r7   c           	     ó¼  € ^ RI Hp ^ RIHpHp V Uu0 uF4  qU'       g   K  VP                  4       '       g   K$  VP                  4       kK6  	  pp\        V 4      ;_uu_ 4        \        ;_uu_ 4        V R,          pVP                  4       '       d5   VP                  R4       Uu. uF  qˆP                  P                  NK  	  upM. p	V! 4       p
V! V
4      p^ pV	 F-  pWÖ9  g   K  WÛ9  g   K  VP                  V4       V^,          pK/  	  V'       d	   V! W«4       RRR4       RRR4       X# u upi u upi   + '       g   i     L$; i  + '       g   i     X# ; i)aE  Disable every installed skill in ``profile_dir`` not in ``keep``; returns how many were
newly disabled. Profiles manage activation via a *disabled* list (everything installed is
active by default); the builder's skill step has "replace" semantics. Hub skills are
installed separately via subprocess and are active on install.)rs   )Úget_disabled_skillsÚsave_disabled_skillsÚskillszSKILL.mdN)ru   rs   Úhermes_cli.skills_configr~   r   Ústripr,   r   Úis_dirÚrglobÚparentrG   r:   )ro   r{   rs   r~   r   ÚsÚkeep_setÚskills_rootÚmdÚ	installedrx   ÚdisabledÚnewlyrG   s   &&            r5   Ú_disable_unselected_skillsr�   —   s  € õ
 .ßRÙ#'Ó;¡4˜a«1”	°·±·”	�—‘–	¡4€HÐ;Ü	˜K×	(Õ	(×*?Ö*?Ø! HÕ,ˆà#×*Ñ*×,Ò,ð 0;×/@Ñ/@ÀÔ/LÓMÑ/L¨—i‘i—n”nÑ/LÒMØ24ð 	á‹mˆÙ& sÓ+ˆØˆÛˆDØÖ#¨Ö(<Ø—‘˜TÔ"Ø˜•
’ñ ÷ Ù  Ô/÷ +@×	(ð €Lùò <ùò N÷ +@×*?ú×	(Ö	(ð €LúsW   “	D-¡D-¹D-Á"E
Á13D7	Â$D2ÃD7	Ã%D7	Ã-%D7	ÄD7	ÄE
Ä2D7	Ä7EÅE
Å
E	Ú	not_foundÚbad_requestc                ó$   € V ^8„  d   QhR\         /# ©r.   Úlog_msgrb   )r4   s   "r5   r6   r6   ´   s   € ÷ <ñ <œSñ <r7   c             '  óF  "  €  Rx € R#   \          d    h T d   p\        R\        T4      R7      hRp?iT d   p\        R\        T4      R7      hRp?i\         d    h \         d4   p\        P
                  ! T .TO5!   \        R\        T4      R7      hRp?ii ; i5i)uU  Map hermes_cli.profiles exceptions to HTTP: ``not_found`` -> 404, ``bad_request`` -> 400
(in that order), anything else is logged with ``log_msg`` -> 500. HTTPException passes, and so
does ``ProfileIdentitySettlementPending`` â€” a typed partial success the calling endpoint (the
delete route) owns; it must not flatten into the generic 500.Ni”  ©Ústatus_codeÚdetailé�  éô  )r   r2   r   r3   r;   Ú	exception)r’   rŽ   r�   ÚargsÚes   &$$* r5   Ú_profile_errorsrœ   ³   sˆ   é € ð<ÝøÜô ØØô <Ü¨´C¸³FÔ;Ð;ûØô <Ü¨´C¸³FÔ;Ð;ûÜ+ô ØÜô <Ü�Š�wÐ& Ô&Ü¨´C¸³FÔ;Ð;ûð<üsO   ‚B!„
 ˆB!ŠB›Bœ2²B»B¼AÁBÁ
BÁ*BÁ+.BÂBÂB!c                ó$   € V ^8„  d   QhR\         /# )r.   Úlabelrb   )r4   s   "r5   r6   r6   É   s   € ÷ Tñ T¤cñ Tr7   c              ƒ  óz   "  €  \        V 4      G Rj  x€L
 #  L  T d   p\        RRT RT 2R7      hRp?ii ; i5i)zU``read()`` on a worker thread; ``errors`` become ``500 "Could not read <label>: e"``.Nr˜   zCould not read z: r”   )r    r   )Úreadrž   Úerrorsr›   s   &&& r5   Ú_read_off_loopr¢   É   sG   é € ðTÜ& tÓ,×,Ð,Ñ,øØô TÜ¨°oÀeÀWÈBÈqÈcÐ4RÔSÐSûðTüs(   ‚;„ ’“ –;— ™8 3³8¸;rd   c                ó$   € V ^8„  d   QhR\         /# r‘   rb   )r4   s   "r5   r6   r6   Ñ   s   € ÷ ñ œ#ñ r7   c               óh   €  V! 4       #   \          d    \        P                  ! T .TO5!   Tu # i ; i)z†Run ``fn()``; on failure log ``log_msg`` with traceback and return ``default`` (the
parent operation already succeeded, so never 500).)r3   r;   r™   )r’   Úfnrd   rš   s   &$$*r5   Ú_best_effortr¦   Ñ   s3   € ðÙ‹tˆøÜô Ü�Š�wÐ& Ô&ØŠðús   ‚	 ‰%1°1c                óh   € V ^8„  d   QhR\         R\        \        \         \        3,          ,          /# )r.   Ú	log_labelr1   )r2   r|   Útupler   )r4   s   "r5   r6   r6   Û   s(   € ÷ ñ ¤ð ¬¬U´3¼°9Õ-=Õ(>ñ r7   c                óô   € ^ RI Hp  \        VP                  RRRR7      4      pV'       g#   VP                  RVP                  R4      34       V#   \         d    \
        P                  RT 4       . p LQi ; i)u!  (name, home) for every profile, falling back to ``default`` alone. Uses
``profiles_to_serve`` (pure directory read) instead of ``list_profiles``, which parses
config/meta and probes gateways per profile â€” every caller here is a polled sidebar
fan-out that only needs name/path (#114041).©ÚprofilesT)Ú	multiplexÚinclude_standaloneÚinclude_parkedz%s: profile enumeration failedrd   )	Ú
hermes_clir¬   r|   Úprofiles_to_server3   r;   r™   ÚappendÚget_profile_dir)r¨   Úprofiles_modÚtargetss   &  r5   Ú_profile_targetsr¶   Û   su   € õ
 4ðÜ�|×5Ñ5ÀÐY]ÐnrÐ5ÓsÓtˆ÷ Ø�‰˜	 <×#?Ñ#?À	Ó#JÐKÔLØ€Nøô ô Ü�‰Ð7¸ÔCØŠðús   ˆA Á#A7Á6A7c          	      óŠ   € V ^8„  d   QhR\         R\        \         ,          R\        \        \         \        3,          ,          /# )r.   r¨   r/   r1   )r2   r
   r|   r©   r   )r4   s   "r5   r6   r6   ë   s;   € ÷ dñ d¤sð d´X¼cµ]ð dÄtÌEÔRUÔW[ÐR[ÕL\ÕG]ñ dr7   c                ó¼   € T;'       g    RP                  4       ;'       g    Rp\        V 4      pVR8X  d   V# V UUu. uF  w  rEWB8X  g   K  WE3NK  	  upp# u uppi )z§Every profile, or only ``profile``: a native grant may read just the profile it names,
so the Desktop assembles the all-profiles view from one scoped read per profile.Úall)r‚   r¶   )r¨   r/   Úscoperµ   rG   Úhomes   &&    r5   Ú_scoped_profile_targetsr¼   ë   s[   € ð ×Ð˜×$Ñ$Ó&×/Ð/¨%€EÜ˜yÓ)€GØ˜u”nˆ7ÐcÉ'Ô*cÉ'¹J¸DÐUYÑUb¬<¨D«<É'Ò*cÐcùÓ*cs   ¾
AÁAc                ó¸   € V ^8„  d   QhR\         \        \        \        3,          ,          R\        R\        R\         \        \        \        3,          ,          /# )r.   ÚrowsrG   Únowr1   )r|   rE   r2   r   Úfloat)r4   s   "r5   r6   r6   ó   sC   € ÷ ñ ”Dœœc¤3˜h�Õ(ð ´ð ¼%ð ÄDÌÌcÔSVÈhÍÕDXñ r7   c           	     ó6  € V  F’  pWR&   VR8H  VR&   VP                  R4      RJ ;'       d,    W#P                  RVP                  R^ 4      4      ,
          R8  VR	&   \        VP                  R
4      4      VR
&   \        VP                  R4      4      VR&   K”  	  V # )z†Stamp session rows with their owning profile and the 300s active heuristic; SQLite
stores flags as 0/1 and the sidebar needs booleans.r/   rd   Úis_default_profileÚended_atNÚlast_activeÚ
started_ati,  Ú	is_activeÚarchivedÚpinned)rv   r\   )r¾   rG   r¿   r†   s   &&& r5   Ú	_tag_rowsrÉ   ó   s�   € ó ˆØˆ)‰Ø"&¨)Ñ"3ˆÐ
Ñà�E‰E�*Ó Ð%×dÐd¨3·±°}ÀaÇeÁeÈLÐZ[ÓF\Ó1]Õ+]ÐadÑ*dð 	
ˆ+‰ô ˜QŸU™U :Ó.Ó/ˆˆ*‰Ü˜1Ÿ5™5 ›?Ó+ˆˆ(‹ñ ð €Kr7   c                ó¸   € V ^8„  d   QhR\         \        \        \        3,          ,          R\        R\        R\         \        \        \        3,          ,          /# )r.   r¾   ÚoffsetÚcapr1   )r|   rE   r2   r   r]   )r4   s   "r5   r6   r6     sE   € ÷ ñ œœd¤3¬ 8�nÕ-ð ´sð Äð ÌÌdÔSVÔX[ÐS[ÍnÕI]ñ r7   c                óÐ   a€ WW,            p\        V 4      W,           8”  d@   V Uu0 uF  p\        V4      kK  	  upoVP                  V3R lWV,           R  4       4       V# u upi )zª``rows[offset:offset+cap]`` plus every pinned row past it: the per-profile queries
back-fill pinned rows past their LIMIT, so truncating on recency alone would drop them.c              3   ó|   <"  € T F1  qP                  R 4      '       g   K  \        V4      S9  g   K-  Vx € K3  	  R# 5i)rÈ   N)rv   Úid)Ú.0r†   Úseens   & €r5   Ú	<genexpr>Ú!_pinned_window.<locals>.<genexpr>  s+   øé € Ð^Ñ!4˜A¿¹¸h¿”aÌBÈqËEÐY]ÑL]—a’aÓ!4ùs   ƒ< <²
<N)ÚlenrÏ   Úextend)r¾   rË   rÌ   Úwindowr†   rÑ   s   &&&  @r5   Ú_pinned_windowr×     s\   ø€ ð ˜�Ð&€FÜ
ˆ4ƒy�6•<ÔÙ%Ó&™v˜!”�1–™vÑ&ˆØ�‰Ô^ ¨s¥l mÑ!4Ó^Ô^Ø€Mùò 's   ¦A#c                óR   € V ^8„  d   QhR\         \        \        3,          R\        /# )r.   r†   r1   rD   )r4   s   "r5   r6   r6     s"   € ÷ <ñ <””Sœ#�X•ð <¤3ñ <r7   c                 ój   € V P                  R 4      ;'       g    V P                  R4      ;'       g    ^ # )rÄ   rÅ   ©rv   )r†   s   &r5   Ú_recencyrÛ     s*   € Ø�5‰5�Ó×;Ð; 1§5¡5¨Ó#6×;Ð;¸!Ð;r7   c                óº   € V ^8„  d   QhR\         R\        \        \        \         \         3,          ,          ,          R\        \
        .\
        3,          R\
        /# )r.   rG   r¡   r¥   r1   )r2   r
   r|   rE   r   r   )r4   s   "r5   r6   r6     sG   € ÷ ñ œ3ð ¬h´t¼DÄÄcÀ½NÕ7KÕ.Lð Ü!¤3 %¬ *Õ-ðÜ25ñr7   c           	     ó²  € \        V4      R,          pVP                  4       '       g   R# Rp \        VRR7      pV! V4      Ve   VP                  4        # #   \         dZ   p\        YF4       \        Y4       Te   TP                  RT R\        T4      /4        Rp?Te   TP                  4        R# R# Rp?ii ; i  Te   TP                  4        i i ; i)a  ``fn(db)`` against the profile's read-only state.db; None when the file is missing,
the open fails or ``fn`` raises (warned once, recorded in ``errors`` when given).

Read-only on the healthy path: this runs on every sidebar refresh, so it must not
routinely DDL/write-lock another profile's live DB. A store that predates a schema addition
gets the missing declared tables/columns ONCE from the open helper, and only while no gateway
owns it; an owned store is reported in ``errors`` with the restart remedy (#140315).ústate.dbNT)Ú	read_onlyr/   Úerror)	r   Úexistsr   Úcloser3   r   r>   r²   r2   )rG   r»   r¡   r¥   Údb_pathÚdbr0   s   &&&&   r5   Ú_read_profile_dbrå     sÁ   € ô �4‹j˜:Õ%€GØ�>‰>×ÒÙØ	€BðÜ% g¸Ô>ˆÙ�"‹vð Š>Ø�H‰H�Jð øô ô ä˜7Ô(Ü  Ô+ØÒØ�M‰M˜9 d¨G´S¸³XÐ>Ô?ÛàŠ>Ø�H‰HŽJñ ûðûð Š>Ø�H‰H�Jð ús/   ®A ÁB<Á#8B7ÂB? Â"B? Â7B<Â<B? Â?Cc                óF   € V ^8„  d   QhR\         \        \        3,          /# rC   )rE   r2   )r4   s   "r5   r6   r6   +  s   € ÷ Jñ J¬¬S´#¨X­ñ Jr7   c           	     ó�   € V  UUu/ uF2  w  r\        \        V4      R,          4      \        8X  g   K+  V\        bK4  	  upp# u uppi )a   ``{profile: "corrupt"}`` for every scanned profile whose state.db this process has latched
as structurally corrupt (``hermes_state_health``). Lets Desktop tell an empty or partial list
from a damaged store, including when some reads still succeed (#72046).rÞ   )r   r   r   )rµ   rG   r»   s   &  r5   Ú_corrupt_profile_storesrè   +  sJ   € ñ 5<ô J±G¡j dÜœT $›Z¨*Õ4Ó5¼ÑHô "ˆD”/Ò!±Gò Jð Jùó Js
   †(A³Ag      @é   c                ó$   € V ^8„  d   QhR\         /# )r.   rI   r   )r4   s   "r5   r6   r6   <  s   € ÷ Fñ FœDñ Fr7   c                ó¤   €  V P                  4       pTP                  TP                  TP                  TP
                  3#   \         d     R# i ; i)z=Return identity + mutation metadata without opening the file.N)ÚstatÚOSErrorÚst_devÚst_inoÚst_sizeÚst_mtime_ns)rI   rì   s   & r5   Ú_stat_fingerprintrò   <  sI   € ðØ�y‰y‹{ˆð �K‰K˜Ÿ™ d§l¡l°D×4DÑ4DÐEÐEøô ô Úðús   ‚A  Á AÁAc                ó$   € V ^8„  d   QhR\         /# )r.   rã   r   )r4   s   "r5   r6   r6   E  s   € ÷ Sñ S¤Tñ Sr7   c                óF   € \        V 4      \        \        V  R24      4      3# )z=Track SQLite content changes through the main DB and its WAL.z-wal)rò   r   )rã   s   &r5   Ú_sidebar_db_fingerprintrõ   E  s$   € ä˜gÓ&Ô(9¼$À'ÀÈ$Ð?OÓ:PÓ(QÐRÐRr7   c                 óú   € \         ;_uu_ 4        \        P                  V 4      pVf    R R R 4       R # \        P                  V 4       \        P
                  ! V4      uuR R R 4       #   + '       g   i     R # ; i©N)Ú_SIDEBAR_PROFILE_CACHE_LOCKÚ_SIDEBAR_PROFILE_CACHErv   Úmove_to_endÚcopyÚdeepcopy)r=   Úvalues   & r5   Ú_sidebar_profile_cache_getrþ   J  sS   € ß	$Ö	$Ü&×*Ñ*¨3Ó/ˆØŠ=Ø÷ 
%Ñ	$ô 	×*Ñ*¨3Ô/Ü�}Š}˜UÓ#÷ 
%×	$×	$Ó	$ús   �A)´*A)Á)A:	c                 óì  € V R ,          w  r#\         P                  ! V4      p\        ;_uu_ 4        \         Uu. uF%  pV^ ,          V8X  g   K  V^,          V8w  g   K#  VNK'  	  up F  p\        P	                  VR4       K  	  V\        V &   \        P                  V 4       \        \        4      \        8”  d   \        P                  RR7       K0   RRR4       R# u upi   + '       g   i     R# ; i):Nr.   NNF©Úlast)	rû   rü   rø   rù   Úpoprú   rÔ   Ú"_SIDEBAR_PROFILE_CACHE_MAX_ENTRIESÚpopitem)r=   rý   rã   ÚfingerprintÚsnapshotÚkÚexistings   &&     r5   Ú_sidebar_profile_cache_putr	  S  sÒ   € Ø˜r�7Ñ€GÜ�}Š}˜UÓ#€Hß	$Ö	$õ %;ó EÑ$:˜qØ˜a�D G™Oô Ø01°!µ¸Ñ0C÷ ˜Ñ$:ô EˆHä"×&Ñ& x°Ö6ñEð '/Ô˜sÑ#Ü×*Ñ*¨3Ô/ÜÔ(Ó)Ô,NÔNÜ"×*Ñ*°Ð*Ö6ð O÷ 
%Ñ	$ùòE÷ 
%×	$Ð	$ús)   °	C"¹CÁCÁCÁ$A.C"ÃC"Ã"C3	c                  ó„   € \         ;_uu_ 4        \        P                  4        R R R 4       R #   + '       g   i     R # ; ir÷   )rø   rù   Úclear© r7   r5   Ú_sidebar_profile_cache_clearr  b  s#   € ß	$Ö	$Ü×$Ñ$Ô&÷ 
%×	$×	$Ò	$ús   �.®?	c                ó$   € V ^8„  d   QhR\         /# rC   r   )r4   s   "r5   r6   r6   g  s   € ÷ #ñ #œtñ #r7   c                 ó&   € \        V 4      R ,          # )rÞ   r   )r»   s   &r5   Ú_profile_state_dbr  g  s   € Ü�‹:˜
Õ"Ð"r7   c                óR   € V ^8„  d   QhR\         \        \        3,          R\        /# )r.   Úslicesr1   )rE   r2   r   r\   )r4   s   "r5   r6   r6   k  s&   € ÷ Lñ LœD¤¤c �Nð L¬tñ Lr7   c                 óx   a € \         ;QJ d    V 3R  lR 4       F  '       g   K   R# 	  R# ! V 3R  lR 4       4      # )c              3   óF   <"  € T F  pSP                  V4      x € K  	  R # 5ir÷   rÚ   )rÐ   r=   r  s   & €r5   rÒ   Ú"_slice_has_rows.<locals>.<genexpr>l  s   øé € ÐKÑ*J 3ˆv�z‰z˜#�ˆÓ*Jùs   ƒ!TF©ÚrecentsÚcronÚ	messaging)Úany)r  s   fr5   Ú_slice_has_rowsr  k  s.   ø€ ß‹3ÔKÑ*JÓK�3Œ3ÐKŠ3ÐKˆ3ÔKÑ*JÓKÓKÐKr7   c                ó    € V ^8„  d   QhR\         \        \        \        3,          ,          R\         \        \        \        3,          ,          /# ©r.   r¡   r1   )r|   rE   r2   )r4   s   "r5   r6   r6   o  s;   € ÷ Nñ N¤d¬4´´S°­>Õ&:ð NÌÌTÔRUÔWZÐRZÍ^ÕH\ñ Nr7   c                ó˜   € \        \        V4      4      pV  Uu. uF%  q3P                  R4      V9  g   K  \        V4      NK'  	  up# u upi )zOScan failures Retry can re-attempt. A latched corrupt store has its own notice.r/   )Úsetrè   rv   rE   )r¡   ÚscannedÚcorruptÚerrs   &&  r5   Ú_retryable_profile_errorsr#  o  s>   € äÔ)¨'Ó2Ó3€GÙ!'ÓM¡˜#¯7©7°9Ó+=ÀWÑ+LŒIŒD�ŽI¡ÑMÐMùÒMs
   ™AµAc                óŠ   € V ^8„  d   QhR\         \        \        \        3,          ,          R\        \        \        3,          /# r  ©r|   rE   r2   r   )r4   s   "r5   r6   r6   u  s3   € ÷ ]ñ ]œt¤D¬¬c¨¥NÕ3ð ]ÄÄcÌ3ÀhÅñ ]r7   c                óR   € RRRRRV  Uu. uF  p\        V4      NK  	  up/VC# u upi )zHFailed load: no ``sessions`` key. An empty list would read as data loss.ÚfailedTÚretryr¡   )rE   )r¡   Úextrar"  s   &, r5   Ú_failed_load_slicer*  u  s1   € à�d˜G T¨8É6Ó5RÉ6ÀC´d¸3¶iÉ6Ñ5RÐ\ÐV[Ð\Ð\ùÒ5Rs   Š$c                ó¬   € V ^8„  d   QhR\         \        \        \        3,          ,          R\        \        \        \        \        3,          3,          /# r  r%  )r4   s   "r5   r6   r6   z  s9   € ÷ ñ œT¤$¤s¬C x¥.Õ1ð ´d¼3ÄÄSÌ#ÀXÅÐ;NÕ6Oñ r7   c                 óœ   € V  Uu/ uF;  qP                  R 4      '       g   K  VR ,          RRRRRVP                  RR4      /bK=  	  up# u upi )r/   r'  Tr(  rà   rH   rÚ   )r¡   r"  s   & r5   Ú_profiles_failedr-  z  sW   € ñ óáˆCŸW™W Y×/ô 	WˆˆI�˜ 4¨°$¸ÀÇÁÈÐRTÓAUÐVÒVÙñð ùò s
   …A	¢$A	c                ó  a aaaaaa€ \         P                  ! S 4      o\        4       o\        P                  ! 4       o\        P                  ! 4       o\        4       oVVV3R lo\        P                  ! S 4      VVVV VVV3R l4       pV# )a¦  Coalesce concurrent sidebar scans and briefly reuse their response.

Every uncached refresh opens every profile database; desktop poll bursts overlap identical
scans in AnyIO worker threads, starving the uvicorn loop for the GIL. The TTL bounds UI
staleness; the single-flight lock guarantees one expensive scan at a time. Cached values
are copied on store and hit so serialization or a caller cannot mutate shared state.
c                 ó\  <€ \         P                  ! 4       pS;_uu_ 4        SP                  V 4      pVe   W^ ,          8¼  d   SP                  V R 4       SuuR R R 4       # SP	                  V 4       \
        P                  ! V^,          4      uuR R R 4       #   + '       g   i     R # ; ir÷   )ÚtimeÚ	monotonicrv   r  rú   rû   rü   )r=   r¿   ÚitemÚcacheÚ
cache_lockÚmisss   &  €€€r5   Ú_lookupÚ,_sidebar_singleflight_cache.<locals>._lookup�  sr   ø€ Ü�nŠnÓˆßŠZØ—9‘9˜S“>ˆDØŠ|˜s¨1¥gœ~Ø—	‘	˜#˜tÔ$Ø÷	 ŠZð
 ×Ñ˜cÔ"Ü—=’=  a¥Ó)÷ �Z�Z‹Zús   ¡6BÁ"-BÂB+	c            	      óx  <€ \         pV^ 8:  d	   S! V / VB # SP                  ! V / VB pVP                  4        \        VP                  P                  4       4      pS! V4      pVSJd   V# S;_uu_ 4        S! V4      pVSJd   VuuRRR4       # S! V / VB p\        V\        4      '       d$   VP                  R4      '       d   VuuRRR4       #  \        P                  ! V4      pS
;_uu_ 4        \        P                  ! 4       T,           T3S	T&   S	P!                  T4       \#        S	4      \$        8”  d   S	P'                  RR7       K(   RRR4       TuuRRR4       #   \         d%    \        P                  R4       Tu uuRRR4       # i ; i  + '       g   i     LN; i  + '       g   i     R# ; i)é    Nr¡   z$sidebar response could not be cachedFr   )Ú_SIDEBAR_CACHE_TTL_SECONDSÚbindÚapply_defaultsr©   Ú	argumentsÚitemsÚ
isinstancerE   rv   rû   rü   r3   r;   r™   r0  r1  rú   rÔ   Ú_SIDEBAR_CACHE_MAX_ENTRIESr  )rš   ÚkwargsÚttlÚboundr=   Úcachedrw   r  r6  r3  r4  Úfuncr5  Úrefresh_lockÚ	signatures   *,      €€€€€€€r5   ÚwrappedÚ,_sidebar_singleflight_cache.<locals>.wrapped™  st  ø€ ä(ˆØ�!Œ8Ù˜Ð( Ñ(Ð(à—’ Ð/¨Ñ/ˆØ×ÑÔÜ�E—O‘O×)Ñ)Ó+Ó,ˆÙ˜“ˆØ˜ÓØˆM÷ Š\Ù˜S“\ˆFØ˜TÓ!Ø÷ Š\ñ ˜4Ð* 6Ñ*ˆFô ˜&¤$×'Ò'¨F¯J©J°x×,@Ò,@Ø÷ Š\ðÜŸ=š=¨Ó0�÷ ’Ü"ŸnšnÓ.°Õ4°hÐ?��c‘
Ø×!Ñ! #Ô&Ü˜%“jÔ#=Ô=Ø—M‘M u�MÖ-ð >÷ ð
 ÷) Š\øô ô Ü—‘ÐEÔFØ‘÷ Š\ðú÷ —ú÷ �\ˆ\úsU   Á6F(Â4F(ÃF(ÃE#Ã)
F(Ã3AF	Å	F(Å#"FÆF(ÆFÆF(ÆF%Æ F(Æ(F9	)ÚinspectrG  r   Ú	threadingÚLockÚobjectrY   Úwraps)rE  rH  r6  r3  r4  r5  rF  rG  s   f @@@@@@r5   Ú_sidebar_singleflight_cacherO  �  sj   þ€ ô ×!Ò! $Ó'€IÜ‹M€EÜ—’Ó!€JÜ—>’>Ó#€LÜ‹8€D÷*ô ‡_‚_�TÓ÷"ò "ó ð"ðH €Nr7   c                ó\   € V ^8„  d   QhR\         \        ,          R\        \        ,          /# )r.   rý   r1   )r
   r2   r|   )r4   s   "r5   r6   r6   Á  s&   € ÷ Fñ F”Xœc•]ð F¤t¬C¥yñ Fr7   c                 ó¬   € T ;'       g    R P                  R4       Uu. uF*  qP                  4       '       g   K  VP                  4       NK,  	  up# u upi )rH   Ú,)Úsplitr‚   )rý   r†   s   & r5   Ú	_csv_listrT  Á  s;   € Ø %§ ¨×2Ñ2°3Ô7ÓEÑ7˜!¿7¹7¿9ŒIˆA�G‰GŽIÑ7ÑEÐEùÒEs
   žAºAz/api/profiles/sessionsr˜   )ÚgeÚle)rU  ÚexcludeÚrecentr¹   Fc                óº   € V ^8„  d   QhR\         R\         R\         R\        R\        R\        R\        R,          R	\        R,          R
\        R,          R\        /
# )r.   ÚlimitrË   Úmin_messagesrÇ   Úorderr/   ÚsourceNÚsourcesÚexclude_sourcesÚfull)r]   r2   r\   )r4   s   "r5   r6   r6   Æ  s‘   € ÷ @9ñ @9ô ð	@9ô 36ð	@9ô WZð	@9ô
 ð@9ô
 '*ð@9ô
 @Cð@9ô �$�Jð@9ô ),¨d­
ð@9ô MPÐRVÍJð@9ô fjñ@9r7   c
                óv  aa	aaaaaa€ VR9  d   \        RRR7      hSR9  d   \        RRR7      hV'       d   VR8w  d   \        V4      .M
\        R	4      p
\        T;'       g    R
\	        V4      ;'       g    R
\	        V4      ;'       g    R
\        ^ V4      VR8H  VR8H  R7      oW,           o. o/ o. p\        P                  ! 4       oV
 F   w  rÍWÍ3VV	VVVVV3R llp\        WÍW¾4       K"  	  SR8X  d   RMRoSP                  V3R lRR7       VR8X  dN   \        S Uu. uF  qÿP                  R4      '       g   K  VNK  	  upW4      pVP                  R S 4       4       M\        SW4      pS	'       g   \        V4       RVR\        SP                  4       4      RSRV RVRVR\        V
4      /# u upi )u%  Unified, read-only session list aggregated across ALL profiles: opens each profile's
``state.db`` directly (no dashboard backend per profile) and tags rows with their owning
``profile``. Rows omit ``system_prompt`` / ``model_config`` unless ``full=1`` â€” same
projection as ``/api/sessions``.ÚonlyÚincluder—   z/archived must be one of: exclude, only, includer”   rX  z%order must be one of: created, recentr¹   zGET /api/profiles/sessionsN)r]  r^  r_  Úmin_message_countÚinclude_archivedÚarchived_onlyc                 ó  <€ \        VSR ,          SR,          SR,          R7      w  r4/ SCRVRV/CpV P                  ! RRSR^ RSR8H  R	S'       * R
R/VB pV P                  ! RRR/VB SV&   S	P                  \	        WaS
4      4       R# )r]  r^  r_  )r]  r^  r_  Úinclude_subagentsrZ  rË   Úorder_by_last_activerX  Úcompact_rowsÚinclude_pinnedTÚexclude_childrenNr  )r   Úlist_sessions_richÚsession_countrÕ   rÉ   )rä   rG   r»   rh  rW  Úscopedr¾   Úfiltersr`  Úmergedr¿   r\  Úper_profileÚtotalss   &&&    €€€€€€€r5   Ú_readÚ$get_profiles_sessions.<locals>._readë  sÌ   ø€ Ü)?Ø˜W XÕ.¸À	Õ8JØ 'Ð(9Õ :ô*<Ñ&Ðð e˜ÐdÐ!2°GÐ=PÐRcÑdˆFØ×(Ò(ñ FØ!ðFØ*+ðFØBGÈ8ÑBSðFð "&œXðFð 7;ðFð ?EñFˆDð ×+Ò+ÑL¸TÐLÀVÑLˆF�4‰LØ�M‰Mœ) D°Ó4Ö5r7   rÄ   rÅ   c                 ól   <€ V P                  S4      ;'       g    V P                  R 4      ;'       g    ^ # )rÅ   rÚ   )r†   Úsort_keys   &€r5   Ú<lambda>Ú'get_profiles_sessions.<locals>.<lambda>ù  s)   ø€ ˜aŸe™e H›o×IÐI°·±°|Ó1D×IÐIÈÐIr7   T©r=   ÚreverserÇ   c              3   óˆ   "  € T F8  qP                  R 4      '       g   K  VP                  R4      '       d   K4  Vx € K:  	  R# 5i)rÈ   rÇ   NrÚ   ©rÐ   r†   s   & r5   rÒ   Ú(get_profiles_sessions.<locals>.<genexpr>ÿ  s'   é € ÐU¡˜A¯5©5°¯?”aÀ1Ç5Á5È×CT—a’a£ùs   ‚AŸA¸
AÚsessionsÚtotalÚprofile_totalsrZ  rË   r¡   Ústorage)rW  rb  rc  )ÚcreatedrX  )r   r?   r¶   rE   rT  Úmaxr0  rå   Úsortr×   rv   rÕ   r   ÚsumÚvaluesrè   )rZ  rË   r[  rÇ   r\  r/   r]  r^  r_  r`  rµ   r¡   rG   r»   rt  r†   rÖ   rp  rq  r¿   rr  rw  rs  s   &&&&f&&&&f       @@@@@@r5   Úget_profiles_sessionsrˆ  Å  sª  ÿ€ ð Ð5Ô5Ü¨Ð4eÔfÐfØÐ)Ô)Ü¨Ð4[Ô\Ð\ç07¸GÀuÔ<LÔ" 7Ó+Ñ,Ü$Ð%AÓBð ô
 Ø�~ˆ~˜¤y°Ó'9×'AÐ'A¸TÜ! /Ó2×:Ð:°dÌcÐRSÐUaÓNbØ! YÑ.¸hÈ&Ñ>PôR€Gð •.€Kà#%€FØ€FØ#%€FÜ
�)Š)‹+€CÛ‰
ˆØ÷ 
	6õ 
	6ô 	˜ VÖ3ñ ð !&¨Ô 1‰}°|€HØ
‡K�KÔIÐSW€KÔXØ�6Ôô  ©FÓ H©F q·e±e¸J×6G§ ©FÑ HÈ&ÓXˆà�‰ÑU¡ÓUÕUä ¨Ó6ˆßÜ  Ô(Ø˜ ¬¨V¯]©]«_Ó)=Ð?OÐQWØ�U˜H f¨h¸ØÔ.¨wÓ7ð9ð 9ùò !Is   Ä#F6Å F6z/api/profiles/sessions/sidebarc                ó|   € V ^8„  d   QhR\         R\        R\         R,          R\        R\        R\         R,          /# )r.   Úrecents_profileÚrecents_limitÚrecents_excludeNÚ
cron_limitÚmessaging_limitÚmessaging_exclude)r2   r]   )r4   s   "r5   r6   r6     sM   € ÷ ñ ÜðÜ14ðÜLOÐRVÍJðäðä+.ðäILÈtÍñr7   c                ó<	  a"a#a$a%a&a'a(a)€ \        R4      pT ;'       g    RP                  4       ;'       g    RpT;'       g    RP                  R4       Uu. uF  qˆP                  4       '       g   K  VNK  	  p	pT;'       g    RP                  R4       Uu. uF  qˆP                  4       '       g   K  VNK  	  p
pRRV	3RRRRV
3/o)R\        \	        V^4      R	4      R\        \	        V^4      R	4      R\        \	        V^4      R	4      /o$S) Uu/ uF  q». bK  	  upo(/ p/ p. p\
        P
                  ! 4       pRV$V)3R llo#V#3R lo". p\        4       pV EFW  w  ppVR8w  d
   VV8w  d   K  VP                  VV34       \        V4      pVP                  4       '       g   KM  \        TT	;'       g    RR7      o'\        V4      \        V4      S$R,          \        V	4      S$R,          S$R,          \        V
4      S'^ ,          3o&\        S&4      pVf   \        VVVV"V&V'3R l4      pVf   K×  \!        V4      '       d   VP#                  V4       \%        VR,          4      S$R,          8¬  VV&   VR,          VV&   S) F-  pS(V,          P'                  \)        VV,          VV4      4       K/  	  EKZ  	  R V$V(3R llp\+        V4      p\-        VV4      pV Uu0 uF%  pVP/                  R4      '       g   K  VR,          kK'  	  upo%\        V4      pV UUu. uF  w  ppVV9  g   K  VNK  	  pppVR8g  ;'       d    VS%9   ;'       d    VV9  pVR8H  ;'       d]    \1        V4      ;'       dJ    V'       * ;'       d;    \2        ;QJ d    V%3R lV 4       F  '       d   K   R
M	  RM! V%3R lV 4       4      pV'       g	   V'       d-   R\5        V/ / R7      R\5        V4      R\5        V^ R7      RVRV/# RRV! R4      RVRV/RRV! R4      /RRV! R4      R\%        S(R,          4      /RVRV/p \7        V4      p!V!'       d@   V!V R&   R  F4  pV!V V,          R&   V Uu. uF  p\9        V4      NK  	  upV V,          R&   K6  	  V # u upi u upi u upi u upi u uppi u upi )!u  Batched sidebar session slices (recents / cron / messaging) â€” one profile-DB open per
refresh instead of three ``/api/profiles/sessions`` calls. Same row projection and 300s
active heuristic as the per-slice endpoint; all slices use ``min_messages=1`` /
``archived=exclude`` / recency order.

``recents_profile`` scopes the WHOLE payload, not just recents â€” the sidebar has one
scope, so a concrete profile must never show another profile's Telegram threads or
cronjobs; ``all`` asks for everything.

See #42651, #65710, #70629.
z"GET /api/profiles/sessions/sidebarr¹   rH   rR  r  Nr  r  r˜   Fc                 ó�   <€ SV,          w  r4VR 8X  d   TMRV3w  rTT P                  Y4;'       g    RSV,          ^ ^RRRRRVR7      # )r  FNT)r]  r_  rZ  rË   rd  re  rf  ri  rj  rk  rh  )rm  )rä   r=   Úrecents_subagentsr]  rW  rh  rÌ   Úslice_scopes   &&&   €€r5   Ú_sliceÚ-get_profiles_sessions_sidebar.<locals>._slice)  sf   ø€ Ø% cÕ*‰ˆà:=ÀÔ:JÑ%6ÐQVÐX_ÐP`Ñ"Ðð ×$Ñ$Ø¯?¨?°dÀ#ÀcÅ(ÐSTØ°%ÀuØ!%°DÈØ/ð	 %ó 1ð 	1r7   c                 óz   <€ R S! V R V4      RV P                  4       RS! V R4      RS! V R4      /p\        W4       V# )r  Úusager  r  )Úusage_totalsr	  )rä   Ú	cache_keyr’  r  r”  s   &&& €r5   Ú_build_slicesÚ4get_profiles_sessions_sidebar.<locals>._build_slices5  sN   ø€ ð ™V B¨	Ð3DÓEÀwÐPR×P_ÑP_ÓPaØ™&  VÓ,¨k¹6À"ÀkÓ;RðTˆä" 9Ô5Øˆr7   )r_  c                 ó   <€ S! V SS4      # r÷   r  )rä   rš  Úprofile_cache_keyr’  s   &€€€r5   rx  Ú/get_profiles_sessions_sidebar.<locals>.<lambda>N  s   ø€ ™=¨Ð->Ð@QÔRr7   r—  c                óh   € V ^8„  d   QhR\         R\        \        \         \        3,          ,          /# )r.   r=   r1   )r2   r|   rE   r   )r4   s   "r5   r6   Ú3get_profiles_sessions_sidebar.<locals>.__annotate__\  s'   € ÷ ñ ”Sð œT¤$¤s¬C x¥.Õ1ñ r7   c                 ó�   <€ SV ,          P                  \        R R7       \        SV ,          ^ SV ,          4      p\        V4       V# )Trz  )r…  rÛ   r×   r   )r=   ÚwinrÌ   r¾   s   & €€r5   Ú_windowÚ.get_profiles_sessions_sidebar.<locals>._window\  s:   ø€ ØˆS�	�‰œ8¨TˆÔ2Ü˜T #�Y¨¨3¨s­8Ó4ˆÜ  Ô%Øˆ
r7   r/   c              3   ó,   <"  € T F	  qS9   x € K  	  R # 5ir÷   r  )rÐ   rG   Úfailed_namess   & €r5   rÒ   Ú0get_profiles_sessions_sidebar.<locals>.<genexpr>p  s   øé € Ð6±¨˜Ö$³ùs   ƒT)Úprofiles_truncatedÚprofiles_usage)r€  r¡   r‚  r  r¨  r©  r€  Úprofiles_failed)r  N))FNr  )r¶   r‚   rS  Úminr„  r0  r  r²   r  rá   r   r2   rõ   r©   rþ   rå   r  r:   rÔ   rÕ   rÉ   rè   r#  rv   r\   r¹   r*  r-  rE   )*rŠ  r‹  rŒ  r�  rŽ  r�  rµ   Úrecents_scoper†   Úrecents_exclude_listÚmessaging_exclude_listr  Úrecents_truncatedr�  r¡   r¿   r   ÚcontributedrG   r»   rã   r  r=   r£  r‚  Ú	retryabler"  r!  Ú_homeÚliveÚscoped_failedÚ
all_failedÚbodyr'  rš  r”  rÌ   r¦  r�  r’  r¾   r“  s*   &&&&&&                            @@@@@@@@r5   Úget_profiles_sessions_sidebarr·  	  s¥  ÿ€ ô  ÐCÓD€Gà$×-Ð-¨×4Ñ4Ó6×?Ð?¸%€MØ(7×(=Ð(=¸2×'DÑ'DÀSÔ'IÓWÑ'I !ÏWÉWÏYŸA˜AÑ'IÐÐWØ*;×*AÐ*A¸r×)HÑ)HÈÔ)MÓ[Ñ)M A×QXÑQX×QZŸa˜aÑ)MÐÐ[à˜tÐ%9Ð:¸FÀNØ Ð'=Ð >ð@€Kà”cœ#˜m¨QÓ/°Ó5°v¼sÄ3ÀzÐSTÓCUÐWZÓ?[ØœœC °Ó3°SÓ9ð;€Cá<GÓ,H¹K°q°ªU¹KÑ,H€DØ)+ÐØ24€NØ#%€FÜ
�)Š)‹+€C÷
1ð 
1õð €GÜ“u€KÜ‰
ˆˆdØ˜EÔ! d¨mÔ&;ÙØ�‰˜˜d�|Ô$Ü# DÓ)ˆØ�~‰~×ÒÙÜ2°4ÐI]×IeÐIeÐaeÔfÐÜ  ›\Ô+BÀ7Ó+KÈSÐQZÍ^Ü"Ð#7Ó8¸#¸f½+ÀsÈ;ÕGWÜ"Ð#9Ó:Ð<MÈaÕ<PðRÐô ,Ð,=Ó>ˆØŠ>Ü%Ø�d˜FÞRóTˆFð Š~ÙÜ˜6×"Ò"Ø�O‰O˜DÔ!ô
 #& f¨YÕ&7Ó"8¸CÀ	½NÑ"JÐ˜$ÑØ% g�ˆ�tÑÛˆCØ��I×ÑœY v¨c¥{°D¸#Ó>Ö?ô ñ5 ÷:ñ ô & gÓ.€GÜ)¨&°'Ó:€IÙ.7ÓN©i s¸3¿7¹7À9×;M”N�C˜	—N�N©iÑN€LÜ�'‹l€GÙ$+ÔC¡G‘[�T˜5¨t¸7Ñ/B�DˆD¡G€DÑCà˜Ñ÷ 	-ð 	-Ø˜\Ñ)÷	-ð 	-à Ñ,ð ð 	˜Ñ÷ 	7ð 	7Ü�‹J÷	7ð 	7àŒO÷	7ð 	7÷ ‹CÔ6±Ó6�C�CŠCÔ6±Ó6Ó6ð	 ÷ Ÿ
ð Ô)Ø¨bÀôEàÔ& yÓ1ØÔ+¨I¸QÔ?Ø�f˜i¨ð2ð 	2ð 	�J¡¨	Ó 2Ð4HÐJ[Ø$ nð6à�™W V›_Ð-Ø�j¡'¨+Ó"6¸ÄÀTÈ+ÕEVÓAWÐXØ�&˜) Wð.€Dô ˜iÓ(€FßØ"(ˆÐÑÛ3ˆCØ+1ˆD��IÐ'Ñ(Ù8AÓ"B¹	°¤4¨¦9¹	Ñ"BˆD��I�hÓñ 4ð €Kùò] XùÚ[ùò -IùòB OùãCùòF #Cs<   ÁQ?Á1Q?ÂRÂ2RÄR	ËRË3RÌRÌ$RÑRc                ó¼   € V ^8„  d   QhR\         \        \         \        \        3,          3,          R\        \         \        \        3,          ,          R\        RR/# )r.   ÚintoÚentriesÚ	child_keyr1   N)rE   r2   r   r|   )r4   s   "r5   r6   r6   �  sO   € ÷ nñ n”tœC¤¤c¬3 h¥Ð/Õ0ð n¼4ÄÄSÌ#ÀXÅÕ;Oð nÔ\_ð nÐdhñ nr7   c                óZ  € V EF  pV P                  VR,          4      pVf   W0VR,          &   K-  VR8X  d3   VR,          P                  VP                  R4      ;'       g    . 4       MqVP                  V4      ;'       g    .  Uu/ uF  qUR,          VbK  	  pp\        YcP                  V4      ;'       g    . R4       \        VP	                  4       4      WB&   RV9   g   Kà  VP                  R4      ;'       g    ^ VP                  R4      ;'       g    ^ ,           VR&   EK!  	  R# u upi )zâFold ``entries`` into ``into`` by id, recursing through one child list (repos merge
their lanes, lanes merge their sessions). Counts add up; everything else is
first-writer, since the entries describe the same path either way.rÏ   Nr  ÚsessionCount)rv   rÕ   Ú_merge_by_idr|   r‡  )r¹  rº  r»  Úentryr  ÚcÚchildrens   &&&    r5   r¾  r¾  �  s  € ô ˆØ—8‘8˜E $�KÓ(ˆØÒØ %��t•ÑÙØ˜
Ô"Ø�ZÕ ×'Ñ'¨¯	©	°*Ó(=×(CÐ(CÀÕDàGOÇ|Á|ÐT]ÓG^×GdÐGdÐbdÐGdÓ2eÑGdÀ!°Tµ7¸A²:ÑGdˆHÐ2eÜ˜§9¡9¨YÓ#7×#=Ð#=¸2¸zÔJÜ"& x§¡Ó'8Ó"9ˆHÑØ˜XÖ%Ø(0¯©°^Ó(D×(IÐ(IÈÈeÏiÉiÐXfÓNg×NlÐNlÐklÕ'mˆH�^Ô$ó ùò 3fs   ÂD(c          
      óÈ   € V ^8„  d   QhR\         \        \         \        \        3,          3,          R\        \         \        \        3,          ,          R\        R\        RR/# )r.   rq  Úprojectsr/   Úpreview_limitr1   N)rE   r2   r   r|   r]   )r4   s   "r5   r6   r6      sS   € ÷ )?ñ )?Ü””dœ3¤˜8•nÐ$Õ%ð)?Ü15´d¼3Ä¸8µnÕ1Eð)?ÜPSð)?äð)?àñ)?r7   c                óv  € V EF,  pR VP                  R4      ;'       g    .  4       p. VOVP                  R4      ;'       g    . O F  pW&R&   VR8H  VR&   K  	  ^ RIHp T! VP                  R4      ;'       g
    VR	,          4      pW„R
&   V P                  V4      p	V	f   W@V&   K¥  V	P                  R4      '       d   VP                  R4      '       g   YIrIW�V&   V	P                  R4      ;'       g    .  U
u/ uF  qªR	,          V
bK  	  pp
\        Y´P                  R4      ;'       g    . R4       \	        VP                  4       4      V	R&   R F@  pV	P                  V4      ;'       g    ^ VP                  V4      ;'       g    ^ ,           Wœ&   KB  	  \        V	P                  R4      ;'       g    ^ VP                  R4      ;'       g    ^ 4      V	R&   V	P                  R4      ;'       g    . VP                  R4      ;'       g    . ,           pVP                  \        RR7       VRV V	R&   EK/  	  R# u up
i )a\  Fold one profile's projects into the shared tree, keyed by folder: the same checkout
in two profiles is one group, as is ``__no_project__`` (else one "Home" per profile), and
a declared project (``p_<hash>``) folds with another profile's auto entry for the same
folder. Sessions carry the owning profile; a group header never claims a single owner.c              3   ó®   "  € T FK  pVP                  R 4      ;'       g    .  F)  pVP                  R4      ;'       g    .  F  pVx € K	  	  K+  	  KM  	  R# 5i)Úgroupsr  NrÚ   )rÐ   ÚrÚlaner†   s   &   r5   rÒ   Ú&_merge_profile_tree.<locals>.<genexpr>¨  sX   é € ð >Ñ$>˜qØ%&§U¡U¨8£_×%:Ð%:¸Ò%:˜TØ"&§(¡(¨:Ó"6×"<Ð"<¸"Ò"<˜Qõ á"<ñ Ù%:ñ Ó$>ùs   ‚AŸA½AÚreposÚpreviewSessionsr/   rd   rÂ   )Ú	_path_keyrI   rÏ   ÚmergeKeyNÚisAutorÇ  Ú
lastActiveTrz  )r½  ÚtotalTokensÚtotalCostUsd)	rv   Útui_gateway.project_treerÍ  r¾  r|   r‡  r„  r…  rÛ   )rq  rÃ  r/   rÄ  ÚprojectÚlane_sessionsÚsessionrÍ  r=   r  rÈ  rË  Ú	total_keyÚpreviewss   &&&&          r5   Ú_merge_profile_treerÙ     s  € ô ˆñ> G§K¡K°Ó$8×$>Ð$>¸BÐ$>ó >ˆð Q˜ÐP¨'¯+©+Ð6GÓ*H×*NÐ*NÈBÓPˆGØ!(�IÑØ,3°yÑ,@ˆGÐ(Ó)ñ Qõ 	7Ù˜Ÿ™ FÓ+×<Ð<¨w°t­}Ó=ˆà!�
ÑØ—:‘:˜c“?ˆØÒØ!�3‰KÙð �<‰<˜×!Ò!¨'¯+©+°h×*?Ò*?Ø '�gØ"�3‰Kà@HÇÁÈWÓ@U×@[Ð@[ÐY[Ð@[Ó+\Ñ@[¸1¨d­G°QªJÑ@[ˆÐ+\Ü�UŸK™K¨Ó0×6Ð6°B¸ÔAÜ  §¡£Ó0ˆ�ÑÛHˆIØ#+§<¡<°	Ó#:×#?Ð#?¸aÀGÇKÁKÐPYÓDZ×D_ÐD_Ð^_Õ"`ˆHÓñ Iä!$ X§\¡\°,Ó%?×%DÐ%DÀ1ÀgÇkÁkÐR^ÓF_×FdÐFdÐcdÓ!eˆ�ÑØ—L‘LÐ!2Ó3×9Ð9°r¸g¿k¹kÐJ[Ó>\×>bÐ>bÐ`bÕcˆØ�‰œ(¨DˆÔ1Ø&.¨~°Ð&>ˆÐ"Ô#óE ùò4 ,]s   Ã9H6z/api/profiles/projects/treec                óR   € V ^8„  d   QhR\         R\         R\        \        ,          /# )r.   rÄ  Úsession_limitr/   )r]   r
   r2   )r4   s   "r5   r6   r6   Î  s(   € ÷ ñ ¬cð Äcð Ô[cÔdgÕ[hñ r7   c                óÎ   a aaa	a
€ ^ RI Ho / o	. o
. p\        RV4       F  w  rEWE3VV	V V
V3R llp\        WEW64       K   	  \	        S	P                  4       R RR7      pRVRR	R
S
RV/# )aë  Project tree for every profile at once, for the all-profiles sidebar.

``projects.tree`` over JSON-RPC answers for the backend's own profile only; this runs the
same builder once per profile against its ``state.db``, scoping the other inputs
(projects.db, repo-scan policy, junk filters) through the home override. Discovery is
off: a repo with zero sessions is the same repo in every profile (the disk scan would
multiply empty lanes by the profile count), and discovery is the one part of the builder
that writes (policy reconciliation), which a read-only fan-out must not do.

``profile`` limits the scan to that one profile: a native grant may read only its own, so
the Desktop merges one such read per profile by each project's ``mergeKey``.
)ÚserverzGET /api/profiles/projects/treec           
      óò   <€ \        V4      ;_uu_ 4        SP                  V SR S	R R7      w  r4\        SVR,          VS4       SP                  VR,          4       RRR4       R#   + '       g   i     R# ; i)F)rÄ  ÚhydraterÛ  Úinclude_discoveredrÃ  Úscoped_session_idsN)r,   Ú_build_project_treerÙ  rÕ   )
rä   rG   r»   ÚtreeÚ
_active_idÚgateway_serverrq  rÄ  rá  rÛ  s
   &&&  €€€€€r5   rt  Ú)get_profiles_projects_tree.<locals>._readá  sl   ø€ Ü# D×)Õ)Ø#1×#EÑ#EØ m¸UØ"/ÀEð $Fó $KÑ �ô $ F¨D°Õ,<¸dÀMÔRØ"×)Ñ)¨$Ð/CÕ*DÔE÷ *×)×)Ò)ús   •AA%Á%A6	c                 ó8   € V P                  R 4      ;'       g    ^ # )rÐ  rÚ   )Úps   &r5   rx  Ú,get_profiles_projects_tree.<locals>.<lambda>ë  s   € °Q·U±U¸<Ó5H×5MÐ5MÈAÐ5Mr7   Trz  rÃ  Ú	active_idNrá  r¡   )Útui_gatewayrÝ  r¼   rå   Úsortedr‡  )rÄ  rÛ  r/   r¡   rG   r»   rt  rÃ  rå  rq  rá  s   ff&     @@@r5   Úget_profiles_projects_treerí  Ì  s   ü€ õ 5Ø(*€FØ$&ÐØ#%€Fä-Ð.OÐQXÖY‰
ˆØ÷ 	Fó 	Fô 	˜ VÖ3ñ Zô �f—m‘m“oÑ+MÐW[Ô\€HØ˜ +¨tÐ5IÐK]Ø�fðð r7   z2^https://github\.com/[\w.-]+/[\w.-]+/pull/(\d+)/?$c                óh   € V ^8„  d   QhR\         R\        \        \        \         3,          ,          /# )r.   Úcontentr1   )r2   r
   r©   r]   )r4   s   "r5   r6   r6   õ  s+   € ÷ 	Dñ 	D¤cð 	D¬h´u¼SÄ#¸XµÕ.Gñ 	Dr7   c                ó�  €  \         P                  ! V 4      ;'       g    / P                  R4      p\        T\        4      '       g   R# \        P                  TP                  4       4      pT'       d,   \        TP                  ^4      4      TP                  ^ 4      3# R#   \         P                  \        \
        3 d     R# i ; i)z3The (number, url) a tool result announces, or None.ÚoutputN)ÚjsonÚloadsrv   ÚJSONDecodeErrorÚ	TypeErrorÚAttributeErrorr?  r2   Ú
_PR_URL_REÚmatchr‚   r]   Úgroup)rï  rñ  rø  s   &  r5   Ú_pr_url_from_tool_outputrú  õ  s˜   € ðÜ—*’*˜WÓ%×+Ð+¨×0Ñ0°Ó:ˆô �fœc×"Ò"ÙÜ×Ñ˜VŸ\™\›^Ó,€Eß49ŒC�—‘˜A“Ó §¡¨Q£Ð0ÐC¸tÐCøô × Ñ ¤)¬^Ð<ô Úðús   ‚B! ŸB! Â! CÃCz$/api/profiles/sessions/pull-requestsc                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r.   r¶  r/   )r*   r
   r2   )r4   s   "r5   r6   r6     s    € ÷ 7ñ 7Ô/@ð 7Ì8ÔTWÍ=ñ 7r7   c                ó  aa€ \        \        P                  R V P                  ;'       g    .  4       4      4      R,          oS'       g   R/ R. /# / oVV3R lp\	        RV4       F  w  r4\        W4RV4       K  	  RSRS/# )uD  The PR each of these sessions opened, recovered from its own transcript: a session
that starts in the main checkout and works in a worktree has no branch of its own, so
its PR is invisible to the branch join â€” but ``gh pr create`` ran in the conversation
(see ``_pr_url_from_tool_output``). Read-only across every profile.c              3   ó8   "  € T F  q'       g   K  Vx € K  	  R # 5ir÷   r  r}  s   & r5   rÒ   Ú7post_profiles_sessions_pull_requests.<locals>.<genexpr>  s   é € ÐA©N a»q§¢«Nùs   ‚	�
:NiÐ  NÚpull_requestsr   c                 ó¬   <€ V P                  S4       F=  p\        VR ,          4      pV'       g   K  RV^ ,          RV^,          /SVR,          &   K?  	  R# )rï  ÚnumberÚurlÚ
session_idN)Úfind_pr_url_messagesrú  )rä   ÚprÚparsedÚfoundÚwanteds   &  €€r5   rt  Ú3post_profiles_sessions_pull_requests.<locals>._read  sK   ø€ Ø×)Ñ)¨&Ö1ˆBÜ-¨b°­mÓ<ˆFß‰và+3°V¸AµYÀÀvÈaÅyÐ*Q��b˜Õ&Ó'ó	 2r7   z)POST /api/profiles/sessions/pull-requestsN)r|   rE   ÚfromkeysÚidsr¼   rå   )r¶  r/   rt  rG   r»   r  r  s   &&   @@r5   Ú$post_profiles_sessions_pull_requestsr    s�   ù€ ô ”$—-‘-ÑA¨D¯H©H¯N¨N¸¨NÓAÓAÓBÀ5ÕI€FßØ  Y°Ð3Ð3à')€EöRô .Ð.YÐ[bÖc‰
ˆÜ˜ T¨5Ö1ñ dð ˜U I¨vÐ6Ð6r7   c                 ó   € \        V 4      # r÷   r   )rE  s   &r5   rx  rx    s   € Ô>OÐPTÔ>Ur7   )Úthread_runnerc                  óÞ   € ^ RI Hp   V P                  RR7      pRV Uu. uF  p\        V4      NK  	  up/# u upi   \         d&    \
        P                  R4       R\        T 4      /u # i ; i)r9  r«   T)Úlazy_skill_countr¬   z@GET /api/profiles failed; falling back to profile directory scan)r°   r¬   Úlist_profilesr`   r3   r;   r™   r   )r´   r¬   rè  s      r5   Ú_read_profilesr    sp   € å3ðCà×-Ñ-¸tÐ-ÓDˆØ¹(ÓC¹(°QÔ-¨aÖ0¹(ÑCÐDÐDùÒCøÜô CÜ�‰ÐYÔZØÔ3°LÓAÐBÒBðCús   ˆ< Ÿ7³< ·< ¼-A,Á+A,z/api/profilesc               ƒ   ó2   "  € \        4       G R j  x€L
 #  L5ir÷   )r  r  r7   r5   Úlist_profiles_endpointr  '  s   é € äÓ!×!Ð!Ñ!ùs   ‚�‘c                ó$   € V ^8„  d   QhR\         /# ©r.   r¶  )r!   )r4   s   "r5   r6   r6   -  s   € ÷ EMñ EM¬ñ EMr7   c              ƒ   ó  a a
aaaaa"  € ^ RI Hp S P                  ;'       g    RP                  4       pV'       d   RTS P                  '       * rTpM2S P                  '       d   RRRrTpMS P
                  pV'       d   RMRpTp\        RR+\        \        \        3R7      ;_uu_ 4        VP                  ! R+R	S P                  R
VRS P                  RVRS P                  RS P                  RS P                  /S P                  e   RS P                  /M/ B oV'       g   VP!                  SRR7       VP#                  S P                  4      '       g   VP%                  S P                  4       RRR4       S P&                  ;'       g    RP                  4       oS P(                  ;'       g    RP                  4       oRoR VVVV3R llp\+        S;'       d    S4      ;'       d    \-        RS P                  VRR7      pS P.                  '       d   \-        RS P                  ^ V V3R lR7      M^ pS P0                  '       d   \-        RS P                  ^ V V3R lR7      M^ p	R V 3R lloR S P2                   4        U
a
u. uF/  o
S
'       g   K  RS
R\-        R S
S P                  VV
3R! lR"7      /NK1  	  pp
R#RR	S P                  R$\5        S4      R%VR&SR'VR(V	R)VR*S P                  RJ/	#   + '       g   i     ELŠ; iu up
i 5i),r9  r«   rH   Trd   FNzPOST /api/profiles failed©rŽ   r�   rG   Ú
clone_fromÚ	clone_allÚclone_configÚ	no_skillsrP   Úclone_channelsÚsoul)Úquietc                ó$   € V ^8„  d   QhR\         /# rC   )r\   )r4   s   "r5   r6   Ú-create_profile_endpoint.<locals>.__annotate__Q  s   € ÷ ñ œñ r7   c                  ó”   <€  \        SSS\        4       R 7       R#   \         d!   p \        T P                  4      o Rp ? R# Rp ? ii ; i))rp   NFT)ry   r   r   r2   r–   )r0   rK   Úmodel_errorrI   rL   s    €€€€r5   Ú
_set_modelÚ+create_profile_endpoint.<locals>._set_modelQ  sA   ø€ ð	Ü   x°ÔD[ÓD]Õ^ñ øô ô 	Ü˜cŸj™j›/ˆKÝûð	ús   ƒ œA§AÁAz'Setting model for new profile %s failed)r¥   rd   z-Writing MCP servers for new profile %s failedc                  ó0   <€ \        SS P                  4      # r÷   )r   Úmcp_servers©r¶  rI   s   €€r5   rx  Ú)create_profile_endpoint.<locals>.<lambda>^  ó   ø€ Ô-¨d°D×4DÑ4DÔEr7   )rd   r¥   z2Applying skill selection for new profile %s failedc                  ó0   <€ \        SS P                  4      # r÷   )r�   Úkeep_skillsr(  s   €€r5   rx  r)  b  r*  r7   c                ó$   € V ^8„  d   QhR\         /# )r.   Úidentrb   )r4   s   "r5   r6   r!  f  s   € ÷ Lñ Lœcñ Lr7   c                 ód   <€ \        R SP                  RRV R.\        RV 4      4      P                  # )z-pr€   Úinstallz--yes)rA   rG   r   Úpid)r.  r¶  s   &€r5   Ú_spawn_installÚ/create_profile_endpoint.<locals>._spawn_installf  s5   ø€ Ü# T¨4¯9©9°hÀ	È5ÐRYÐ$ZÜ$4°YÀÓ$FóHßHKÉð	Lr7   c              3   óT   "  € T F  q;'       g    R P                  4       x € K   	  R# 5i)rH   N)r‚   )rÐ   Úis   & r5   rÒ   Ú*create_profile_endpoint.<locals>.<genexpr>n  s   é € ÐA±¨A—w�w˜B—o‘o×'Ð'³ùs   ‚(�(Ú
identifierr1  z7Spawning hub-skill install %s for new profile %s failedc                  ó   <€ S ! S4      # r÷   r  )r2  r.  s   €€r5   rx  r)  m  s
   ø€ ‘~ eÔ,r7   ©r¥   ÚokrI   Ú	model_setr#  Úmcp_writtenÚskills_disabledÚhub_installsÚsoul_setr  )r°   r¬   r  r‚   r  Úclone_from_defaultrœ   Ú
ValueErrorÚFileExistsErrorÚFileNotFoundErrorÚcreate_profilerG   r  rP   r  r  Úseed_profile_skillsÚcheck_alias_collisionÚcreate_wrapper_scriptrL   rK   r\   r¦   r'  r,  Ú
hub_skillsr2   )r¶  r´   Úexplicit_sourceÚcloner  r  r$  r;  r<  r=  r.  r>  r2  rK   r#  rI   rL   s   f         ` @@@@@r5   Úcreate_profile_endpointrK  ,  sþ  þé € å3Ø—‘×,Ð,¨"×3Ñ3Ó5€Oßà*.°ÀTÇ^Á^ÔAS˜<ˆ˜<Ø	��ˆà*.°	¸5˜<ˆ˜<à×'Ñ'ˆß"'‘Y¨Tˆ
ØˆÜ	Ð4ÀÜ&0´/ÔCTÐ%U÷
Wö 
Wà×*Ò*ñ jØ—‘ðjØ'1ðjØ=A¿^¹^ðjà%ðjà15·±ðjàMQ×M]ÑM]ðjð  ×.Ñ.ðjð KOÏ)É)ÒJ_°F¸D¿I¹IÑ3FÐegñjˆ÷ Ø×,Ñ,¨T¸Ð,Ô>Ø×1Ñ1°$·)±)×<Ò<Ø×.Ñ.¨t¯y©yÔ9÷
Wð  —‘×#Ð# ×*Ñ*Ó,€HØ�Z‰Z×Ð˜2×$Ñ$Ó&€Eð €K÷ó ô �X×'Ð' %Ó(÷ \ð \¬\Ø1°4·9±9ÀÐUZô.\€Ið KO×JZ×JZÐJZô Ø7¸¿¹ÈAÝEõGà`að ð KO×JZ×JZÐJZô #Ø<¸d¿i¹iÐQRÝEõGà`að ÷Lð Lñ B°·²ÔAô	*Lñ BˆEÄUô	/ˆ�u˜e¤\ØEÀuÈdÏiÉiÝ,ô&.ó 	/ñ Bð	 ð *Lð �$˜ §	¡	¨6´3°t³9¸kÈ9ÐVcÐepØ˜;Ð(9¸?Ø˜L¨*°d·i±iÀtÐ6KðMð M÷m
W÷ 
Wð 
Wüò`*Lùsq   ‰2L¼&LÁ#LÁ=+LÂ(A6K/Ä3K/ÅK/Å.LÆ	#LÆ-,LÇLÇ(+LÈ1LÉ?LÊ
LÊ&LÊ:5LË/L 	Ë:Lz/api/profiles/activec               ƒ  óN   a"  € ^ RI Ho V3R lp \        V 4      G Rj  x€L
 #  L5i)z¦``active`` is the sticky default written by ``hermes profile use`` (what new CLI
invocations pick up); ``current`` is the profile this running dashboard is scoped to.r«   c                  ó^   <€ RR lp RV ! SP                   4      RV ! SP                  RR7      /# )rd   c                 óL   €  V ! 4       ;'       g    R #   \          d    Tu # i ; i©rd   )r3   )r¥   Úon_errors   &&r5   Ú_or_defaultÚ>get_active_profile_endpoint.<locals>._run.<locals>._or_default}  s+   € ð Ù“t×(Ð(˜yÐ(øÜô  Ø’ð ús   ‚ � “#¢#ÚactiveÚcurrentÚcustom)rP  rO  )Úget_active_profileÚget_active_profile_name)rQ  r´   s    €r5   Ú_runÚ)get_active_profile_endpoint.<locals>._run{  s9   ø€ ô	 ð ™+ l×&EÑ&EÓFØ™; |×'KÑ'KÐV^Ô_ðað 	ar7   N)r°   r¬   r    )rX  r´   s    @r5   Úget_active_profile_endpointrZ  u  s$   øé € õ 4õ
aô # 4Ó(×(Ð(Ñ(ùs   ƒ%ž#Ÿ%c                ó$   € V ^8„  d   QhR\         /# r  )r"   )r4   s   "r5   r6   r6   ‹  s   € ÷ Rñ RÔ,?ñ Rr7   c              ƒ  ó  "  € ^ RI Hp \        R4      ;_uu_ 4        \        VP                  V P
                  4      G Rj  x€L
  RRR4       RRRVP                  V P
                  4      /#  L+  + '       g   i     L1; i5i)z“Set the sticky active profile (mirrors ``hermes profile use``); does not retarget the
running dashboard, only subsequent CLI commands and gateways.r«   z POST /api/profiles/active failedNr:  TrS  )r°   r¬   rœ   r    Úset_active_profilerG   Únormalize_profile_name)r¶  r´   s   & r5   Úset_active_profile_endpointr_  Š  sc   é € õ 4Ü	Ð;×	<Õ	<ä × ?Ñ ?ÀÇÁÓK×KÐK÷ 
=ð �$˜ ,×"EÑ"EÀdÇiÁiÓ"PÐQÐQñ 	L÷ 
=×	<üs.   ‚Bœ$A.Á A,ÁA.Á'BÁ,A.Á.A>	Á9Bz"/api/profiles/{name}/setup-commandc                ó$   € V ^8„  d   QhR\         /# ©r.   rG   rb   )r4   s   "r5   r6   r6   –  s   € ÷ 5ñ 5¬#ñ 5r7   c              ƒ   ó$   "  € R \        V 4      /# 5i)Úcommand)rf   re   s   &r5   Úget_profile_setup_commandrd  •  s   é € àÔ-¨dÓ3Ð4Ð4ùs   ‚c                ó0   € V ^8„  d   QhR\         R\        /# )r.   rc  r1   )r2   r|   )r4   s   "r5   r6   r6   ¢  s   € ÷ +ñ +¤cð +¬dñ +r7   c                 óŒ   € R RV .pRV  R2p\          UUu. uF!  w  r4Y4f   VRV.MV.V'       d   V.M. OVO3NK#  	  upp# u uppi )Úshz-lczsh -lc 'Ú'ú-e)Ú_LINUX_TERMINALS)rc  rg  ÚquotedÚexeÚflags   &    r5   Ú_linux_terminal_commandsrn  ¢  sj   € Ø
��wÐ	€BØ˜�y Ð"€Fõ *ô+á)‰IˆCð 
¢\ˆs�D˜&Ñ!¸Ð7\ÏÀ¹vÐSUÐ7\ÐY[Ð7\Ó]Ù)ò+ð +ùó +s
   •A ¯A z"/api/profiles/{name}/open-terminalc                ó$   € V ^8„  d   QhR\         /# ra  rb   )r4   s   "r5   r6   r6   «  s   € ÷ ,ñ ,¬sñ ,r7   c           
   ƒ   óÔ  "  € \        R V 4      ;_uu_ 4        \        V 4      p\        P                  P	                  R4      '       d   \
        P                  ! RRRRV.4       Má\        P                  R8X  dA   VP                  RR4      P                  R	R
4      p\
        P                  ! RRRV R2.4       MŒ\        V4       Fp  w  r4\        P                  ! \
        P                  RV.\
        P                  \
        P                  R7      G Rj  x€L
 ^ 8X  g   KZ  \
        P                  ! V4        M	  \        RRR7      hRRR4       RRRX/#  L@  + '       g   i     L; i5i)z*POST /api/profiles/%s/open-terminal failedr¢  zcmd.exez/cÚstartrH   ÚdarwinÚ\z\\Ú"z\"Ú	osascriptri  z0tell application "Terminal"
activate
do script "z
"
end tellÚwhich)ÚstdoutÚstderrNr—   z$No supported terminal emulator foundr”   r:  Trc  )rœ   rf   ÚsysÚplatformÚ
startswithÚ
subprocessÚPopenÚreplacern  ÚasyncioÚ	to_threadÚcallÚDEVNULLr   )rG   rc  ÚescapedÚ
executableÚ
popen_argss   &    r5   Úopen_profile_terminal_endpointr†  ª  s6  é € ä	ÐEÀt×	LÕ	LÜ(¨Ó.ˆä�<‰<×"Ñ" 5×)Ò)Ü×Ò˜i¨¨w¸¸GÐDÕEÜ�\‰\˜XÔ%Ø—o‘o d¨FÓ3×;Ñ;¸CÀÓGˆGÜ×Ò˜k¨4Ø RÐSZÐR[Ð[fÐgðiõ jô +CÀ7Ö*KÑ&�
Ü ×*Ò*¬:¯?©?¸WÀjÐ<QÔZd×ZlÑZlÜ2<×2DÑ2DôF÷ FØIJöKä×$Ò$ ZÔ0Ùñ	 +Lô $°Ð<bÔcÐc÷! 
Mð" �$˜	 7Ð+Ð+ñF÷ 
M×	Lüs5   ‚E(—C;EÄE
ÄEÄ'EÅE(ÅEÅE%	Å E(z/api/profiles/{name}c                ó0   € V ^8„  d   QhR\         R\        /# ©r.   rG   r¶  )r2   r%   )r4   s   "r5   r6   r6   Á  s   € ÷ gñ g¬ð g´=ñ gr7   c           
   ƒ   óì  "  € ^ RI Hp \        RV \        \        3R7      ;_uu_ 4        \        VP                  WP                  4      G Rj  x€L
 pRRR4        VP                  V 4      R8H  pV'       d,   RRR	RR
VP                  P                  4       R\        X4      /# RRR	VP                  VP                  4      R\        X4      /#  L~  + '       g   i     L„; i  \         d    Rp L�i ; i5i)r9  r«   zPATCH /api/profiles/%s failed©r�   Nrd   Fr:  TrG   rR   rI   )r°   r¬   rœ   rA  rB  r    Úrename_profileÚnew_namer^  r‚   r2   )rG   r¶  r´   rI   rJ   s   &&   r5   Úrename_profile_endpointr�  À  sá   é € å3Ü	Ð8¸$Ü&0´/Ð%B÷
Dö 
Dô ' |×'BÑ'BÀDÏ-É-ÓX×Xˆ÷	
DðØ!×8Ñ8¸Ó>À)ÑKˆ
÷ Ø�d˜F I¨~¸t¿}¹}×?RÑ?RÓ?TÐV\Ô^aÐbfÓ^gÐhÐhØ�$˜ × CÑ CÀDÇMÁMÓ RÐTZÔ\_Ð`dÓ\eÐfÐfñ Y÷	
D÷ 
Dûô ô ØŠ
ðüsY   ‚'C4©$CÁCÁCÁC4ÁC! Á/C4Á7AC4ÃCÃC	ÃC4Ã!C1Ã.C4Ã0C1Ã1C4c                ó$   € V ^8„  d   QhR\         /# ra  rb   )r4   s   "r5   r6   r6   Ô  s   € ÷ +ñ +¬ñ +r7   c              ƒ  ó\  "  € ^ RI Hp  \        RV 4      ;_uu_ 4        \        VP                  V RR7      G Rj  x€L
 pRRR4       RRR\        X4      /#  L  + '       g   i     L!; i  \
         d4   pRRR\        TP                  4      RR	R
RRTP                  /u Rp?# Rp?ii ; i5i)a˜  The dashboard collects the user's confirmation in its own dialog, so ``yes=True``
always skips the CLI's interactive prompt.

A delete whose identity settlement stays pending answers ``ok`` with ``settlement_pending``
and the retry command: the profile directory is already gone, and folding that state into
the generic 500 made a dashboard client read a completed delete as a failure (its retry
then 404'd).r«   zDELETE /api/profiles/%s failedT)ÚyesNr:  rI   Úidentity_settledFÚsettlement_pendingÚretry_command)	r°   r¬   rœ   r    Údelete_profiler   r2   rI   r“  )rG   r´   rI   r0   s   &   r5   Údelete_profile_endpointr•  Ó  s¦   é € õ 4ðPÜÐ=¸t×DÕDô +¨<×+FÑ+FÈÐRVÔW×WˆD÷ Eð �$˜¤ D£	Ð*Ð*ñ	 X÷ E×Dûô ,ô PØ�d˜F¤C¨¯©£MÐ3EÀuØ$ d¨O¸S×=NÑ=NðPõ 	PûðPüsf   ‚B,ŠA+ žAºA»A¿A+ ÁB,ÁAÁA(	Á#A+ Á'B,Á(A+ Á+B)Á6(B$ÂB)ÂB,Â$B)Â)B,z/api/profiles/{name}/soulc                ó$   € V ^8„  d   QhR\         /# ra  rb   )r4   s   "r5   r6   r6   é  s   € ÷ 0ñ 0¤ñ 0r7   c              ƒ   óž   a"  € \        V 4      R ,          oV3R lp\        VR \        4      G Rj  x€L
 pV\        J d   RRRR/# RVRR/#  L5i)úSOUL.mdc                  ó`   <€ S P                  4       '       g   \        # S P                  R R7      # )ú	utf-8-sig©Úencoding)rá   Ú_MISSINGÚ	read_text)Ú	soul_paths   €r5   rX  Úget_profile_soul.<locals>._runë  s+   ø€ à×Ñ×!Ò!ÜˆOØ×"Ñ"¨KÐ"Ó8Ð8r7   Nrï  rH   rá   FT)r@   r¢   rí   r�  )rG   rX  rï  rŸ  s   &  @r5   Úget_profile_soulr¡  è  sX   øé € ä$ TÓ*¨YÕ6€Iõ9ô # 4¨´GÓ<×<€GØ”(ÓØ˜2˜x¨Ð/Ð/Ø�w ¨$Ð/Ð/ñ =ùs   ƒ-A°A±Ac                ó0   € V ^8„  d   QhR\         R\        /# rˆ  )r2   r&   )r4   s   "r5   r6   r6   ø  s   € ÷ ñ ¤Cð Ô/@ñ r7   c              ƒ   óæ   aa"  € \        V 4      R ,          oVV3R lp \        V4      G Rj  x€L
  RR/#  L  \         d,   p\        P	                  RT 4       \        RRT 2R7      hRp?ii ; i5i)	r˜  c                  ó@   <€ ^ RI Hp  V ! SSP                  RRR7       R# )r9  )Úatomic_write_textTi¤  )Úpreserve_modeÚcreate_modeN)Úutilsr¥  rï  )r¥  r¶  rŸ  s    €€r5   rX  Ú!update_profile_soul.<locals>._runû  s   ø€ Ý+ñ 	˜) T§\¡\ÀÐSX×Yr7   Nz PUT /api/profiles/%s/soul failedr˜   zCould not write SOUL.md: r”   r:  T)r@   r    rí   r;   r™   r   )rG   r¶  rX  r›   rŸ  s   &f  @r5   Úupdate_profile_soulrª  ÷  sv   ùé € ä$ TÓ*¨YÕ6€IöZðUä Ó%×%Ð%ð �$ˆ<Ðñ	 	&øÜô UÜ�‰Ð9¸4Ô@Ü¨Ð6OÐPQÈsÐ4SÔTÐTûðUüs1   „A1Ÿ8 ­6®8 ²A1¶8 ¸A.Á&A)Á)A.Á.A1z /api/profiles/{name}/descriptionc                ó0   € V ^8„  d   QhR\         R\        /# rˆ  )r2   r'   )r4   s   "r5   r6   r6     s   € ÷ 
Hñ 
H´Cð 
HÔ?Wñ 
Hr7   c           	   ƒ  ó.  "  € ^ RI Hp \        V 4      pVP                  ;'       g    RP	                  4       p\        RV RRR7      ;_uu_ 4        \        VP                  W4RR7      G Rj  x€L
  RRR4       RR	R
VRR/#  L  + '       g   i     L; i5i)z¢Set or clear a profile's role description (kanban routing signal), stored as
user-authored (``description_auto: false``) so the auto-describer won't overwrite it.r«   rH   z'PUT /api/profiles/%s/description failedr  F)rP   rQ   Nr:  TrP   rQ   r  )r°   r¬   r@   rP   r‚   rœ   r    Úwrite_profile_meta)rG   r¶  r´   ro   Útexts   &&   r5   Ú#update_profile_description_endpointr¯    s•   é € õ 4Ü& tÓ,€KØ×Ñ×"Ð" ×)Ñ)Ó+€DÜ	ÐBÀDØ#%°2÷
7ö 
7äØ×+Ñ+¨[Ð]bôd÷ 	dð 	d÷
7ð �$˜ tÐ-?ÀÐGÐGñ	d÷
7÷ 
7üs0   ‚ABÁBÁ+B Á,BÁ0BÂ BÂB	ÂBz/api/profiles/{name}/modelc                ó0   € V ^8„  d   QhR\         R\        /# rˆ  )r2   r(   )r4   s   "r5   r6   r6     s   € ÷ >ñ >¬cð >Ô9Kñ >r7   c              ƒ  ó–  "  € \        V 4      pVP                  ;'       g    RP                  4       pVP                  ;'       g    RP                  4       pV'       d	   V'       g   \	        RRR7      h\        RV RRR7      ;_uu_ 4        \        \        W#V4      G Rj  x€L
  RRR4       RR	R
VRV/#  L  + '       g   i     L; i5i)u«   Set the main model for a specific profile's config.yaml without touching the dashboard's
own profile â€” ``POST /api/model/set`` (main scope) via the HERMES_HOME override.rH   r—   zprovider and model are requiredr”   z!PUT /api/profiles/%s/model failedr  Nr:  TrL   rK   r  )r@   rL   r‚   rK   r   rœ   r    ry   )rG   r¶  ro   rL   rK   s   &&   r5   Úupdate_profile_model_endpointr²    s¬   é € ô ' tÓ,€KØ—‘×#Ð# ×*Ñ*Ó,€HØ�Z‰Z×Ð˜2×$Ñ$Ó&€EßŸ5Ü¨Ð4UÔVÐVÜ	Ð<¸dØ#%°2÷
7ö 
7äÔ 4°kÈUÓS×SÐS÷
7ð �$˜
 H¨g°uÐ=Ð=ñ 	T÷
7÷ 
7üsB   ‚AC	ÁC	ÁC	Á&$C	Â
B6ÂB4Â B6Â$C	Â4B6Â6C	ÃC	z"/api/profiles/{name}/describe-autoc                ó0   € V ^8„  d   QhR\         R\        /# rˆ  )r2   r)   )r4   s   "r5   r6   r6   +  s   € ÷ 2ñ 2¬sð 2Ô:Mñ 2r7   c           
   ƒ  óJ  a a"  € \        S 4       VV 3R lp\        RS R	R	R7      ;_uu_ 4        \        V4      G Rj  x€L
 pRRR4       R\        XP                  4      RVP
                  RVP                  R\        VP                  4      /#  LP  + '       g   i     LV; i5i)
zùAuto-generate a profile's description via the auxiliary LLM (mirrors ``hermes profile
describe <name> --auto``). A failed generation is ``ok: false`` with a reason rather than
an HTTP error so the UI can surface it inline and let the operator retry.c                  ó\   <€ ^ RI Hp  V P                  S\        SP                  4      R7      # )r9  )Úprofile_describer)Ú	overwrite)r°   r¶  Údescribe_profiler\   r·  )r¶  r¶  rG   s    €€r5   rX  Ú,describe_profile_auto_endpoint.<locals>._run2  s%   ø€ Ý0Ø ×1Ñ1°$Ä$ÀtÇ~Á~ÓBVÐ1ÓWÐWr7   z*POST /api/profiles/%s/describe-auto failedr  Nr:  ÚreasonrP   rQ   r  )r@   rœ   r    r\   r:  rº  rP   )rG   r¶  rX  Úoutcomes   ff  r5   Údescribe_profile_auto_endpointr¼  *  sŒ   ùé € ô ˜ÔöXô 
ÐEÀtØ#%°2÷
7ö 
7ô *¨$Ó/×/ˆ÷
7ð
 ”$�w—z‘zÓ" H¨g¯n©n¸mÈW×M`ÑM`Ø¤ W§Z¡ZÓ 0ð2ð 2ñ 0÷
7÷ 
7üs-   „*B#®B½B¾BÁAB#ÂBÂB 	ÂB#c                ó0   € V ^8„  d   QhR\         R\        /# )r.   ro   r1   )r   r   )r4   s   "r5   r6   r6   C  s   € ÷ Vñ V¤tð V´ñ Vr7   c                ó\   € \         P                  ! V R,          P                  RR7      4      # )zThe desktop appearance overlay bundled with an imported profile
(``desktop.json`` at the profile root); raises when unreadable.údesktop.jsonrš  r›  )rò  ró  rž  ©ro   s   &r5   Ú_read_desktop_overlayrÁ  C  s&   € ô �:Š:�{ ^Õ3×>Ñ>ÈÐ>ÓTÓUÐUr7   z/api/profiles/{name}/exportc                ó0   € V ^8„  d   QhR\         R\        /# rˆ  )r2   r#   )r4   s   "r5   r6   r6   J  s   € ÷ 0ñ 0¬ð 0´=ñ 0r7   c           	   ƒ   ó  "  € ^ RI Hp VP                  ;'       g    RP                  4       pV'       g    \	        VP                  V 4      4      p\        RV 4      ;_uu_ 4        \        VP                  YVP                  ;'       g    RR	7      G Rj  x€L
 pRRR4       R
RR\	        X4      /#   \         d   p\        R\	        T4      R7      hRp?i\         d   p\        RRT 2R7      hRp?ii ; i Lb  + '       g   i     Lh; i5i)r9  r«   rH   r—   r”   Nr˜   z#Could not create export directory: z#POST /api/profiles/%s/export failed)Úextra_filesr:  TÚarchive)r°   r¬   rñ  r‚   r2   Úget_profile_export_pathrA  r   rí   rœ   r    Úexport_profilerÄ  )rG   r¶  r´   rñ  r0   rw   s   &&    r5   Úexport_profile_endpointrÈ  I  sí   é € å3Ø�k‰k×Ð˜R×&Ñ&Ó(€Fßð	eÜ˜×=Ñ=¸dÓCÓDˆFô 
Ð>À×	EÕ	EÜ(Ø×'Ñ'¨À4×CSÑCS×C[ÐC[ÐW[ô]÷ ]ˆ÷ 
Fð �$˜	¤3 v£;Ð/Ð/øô ô 	BÜ¨C¼¸C»ÔAÐAûÜô 	eÜ¨CÐ:]Ð^aÐ]bÐ8cÔdÐdûð	eúñ]÷ 
F×	Eüsd   ‚2D¶B0 ÁDÁ$0C9ÂC7ÂC9ÂDÂ0C4Â;CÃC4ÃC4ÃC/Ã/C4Ã4DÃ7C9Ã9D		ÄDz/api/profiles/importc                ó$   € V ^8„  d   QhR\         /# r  )r$   )r4   s   "r5   r6   r6   \  s   € ÷ `ñ `¬ñ `r7   c              ƒ   óh  aaa"  € ^ RI Ho V P                  ;'       g    RP                  4       pV'       g   \	        RRR7      h\        R\        \        3R7      ;_uu_ 4        \        SP                  YP                  ;'       g    RP                  4       ;'       g    RR	7      G Rj  x€L
 oRRR4       SP                  o\        R
SVV3R lR7       RpSR,          pVP                  4       '       d   \        RSV3R lR7      pRRRSR\        S4      RV/#  Lq  + '       g   i     Lw; i5i)r9  r«   rH   r—   zarchive path is requiredr”   z POST /api/profiles/import failedrŠ  Nre   z/Creating wrapper for imported profile %s failedc                  óX   <€ SP                  S 4      ;'       g    SP                  S 4      # r÷   )rF  rG  )Úimportedr´   s   €€r5   rx  Ú)import_profile_endpoint.<locals>.<lambda>k  s0   ø€ ˜\×?Ñ?ÀÓI÷ Mð MØ ,× BÑ BÀ8Ó LðMr7   r9  r¿  z4Reading desktop.json from imported profile %s failedc                  ó   <€ \        S 4      # r÷   )rÁ  rÀ  s   €r5   rx  rÍ  t  s   ø€ Ô,¨[Ô9r7   r:  TrG   rI   Údesktop)r°   r¬   rÅ  r‚   r   rœ   rA  rB  r    Úimport_profilerG   r¦   Úis_filer2   )r¶  rÅ  Údesktop_overlayÚoverlay_pathrÌ  ro   r´   s   &   @@@r5   Úimport_profile_endpointrÔ  [  s  úé € å3Ø�|‰|×!Ð!˜r×(Ñ(Ó*€GßÜ¨Ð4NÔOÐOä	Ð;Ü&0´/Ð%B÷
Dö 
Dä-Ø×'Ñ'¨¿	¹	¿¸ÀR×7NÑ7NÓ7P×7XÐ7XÐTXôZ÷ Zˆ÷
Dð
 ×Ñ€Hô ÐBÀHõNõOð
 €OØ Õ/€LØ×Ñ×ÒÜ&ØBÀHÜ9ô;ˆð �$˜ ¨&´#°kÓ2BÀIÈÐ_Ð_ñ#Z÷
D÷ 
Düs;   …2D2¸,D2Á$;DÂ DÂ+DÂ,DÂ0A-D2ÄDÄD/	Ä*D2z$/api/profiles/{name}/desktop-overlayc                ó$   € V ^8„  d   QhR\         /# ra  rb   )r4   s   "r5   r6   r6   y  s   € ÷ 0ñ 0¬Cñ 0r7   c              ƒ  ó�   a"  € \        V 4      oV3R lp\        VR\        4      G Rj  x€L
 pV\        J d   RRRR/# RRRV/#  L5i)z‡The desktop appearance/interface overlay bundled with an imported profile
(``desktop.json`` at the profile root), or ``exists: false``.c                  ó`   <€ S R ,          P                  4       '       g   \        # \        S 4      # )r¿  )rÑ  r�  rÁ  rÀ  s   €r5   rX  Ú)get_profile_desktop_overlay.<locals>._run~  s'   ø€ à˜nÕ,×5Ñ5×7Ò7ÜˆOÜ$ [Ó1Ð1r7   r¿  Nrá   FrÏ  T)r@   r¢   r3   r�  )rG   rX  Úoverlayro   s   &  @r5   Úget_profile_desktop_overlayrÚ  x  sV   øé € ô ' tÓ,€Kõ2ô # 4¨¼ÓC×C€GØ”(ÓØ˜% ¨DÐ1Ð1Ø�d˜I wÐ/Ð/ñ Dùs   ƒ&A©AªAc                ó@   € V ^8„  d   Qh/ ^ \         9   d
   \        ;R&   # )r.   r9   )Ú__conditional_annotations__r  )r4   s   "r5   r6   r6      s    € ÷ 	ñ 	÷v "Ò !”cÑ !òw	r7   )NrH   )r¹   é   Né2   éd   N)é   iÐ  Nr÷   )
)zx-terminal-emulatorri  )zgnome-terminalz--)Úkonsoleri  )zxfce4-terminalN)zmate-terminalN)Ú
lxterminalN)Útilixri  )Ú	alacrittyri  )ÚkittyrH   )Úxtermri  )œrÜ  Ú__doc__r  Ú
contextlibrû   rY   Úhermes_cli.web_read_coalescingr   rJ  rò  ÚloggingÚrer|  ry  rK  r0  Úcollectionsr   Úpathlibr   Útypingr   r   r   r	   r
   r   Úfastapir   r   r   Úhermes_cli.session_listingr   Úhermes_cli.web_depsr   ru   r   Úhermes_cli.profilesr   Úhermes_cli.web_server_configr   r   r   Úhermes_cli.web_server_gatewayr   Úhermes_cli.web_routers._commonr   Úhermes_cli.web_server_profilesr   r   r   Úhermes_cli.web_server_sessionsr   Úhermes_state_healthr   r   r   Ústarlette.concurrencyr    Úhermes_cli.web_modelsr!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   Ú	getLoggerr;   r  r9   r>   Úsessions_routerÚrouterr?   r@   rA   r`   rf   rm   ry   r�   rM  r�  ÚcontextmanagerrC  rA  rœ   r¢   r¦   r¶   r¼   rÉ   r×   rÛ   rå   rè   r:  r@  r  rù   rL  rø   rò   rõ   rþ   r	  r  r  r  r#  r*  r-  rO  rT  rv   rˆ  r·  r¾  rÙ  rí  Úcompiler÷  rú  Úpostr  rZ   r  r  rK  rZ  r_  rd  rj  rn  r†  Úpatchr�  Údeleter•  r¡  Úputrª  r¯  r²  r¼  rÁ  rÈ  rÔ  rÚ  r6   )rÜ  s   @r5   Ú<module>r     sõ  øðö	ó Û Û Û Ý 9Û Û Û Û 	Û Û 
Û Û Ý #Ý ß =× =ç 3Ñ 3å =Ý $Ý 5Ý @÷ñ õ CÝ @÷ñ õ Dß RÑ RÝ 3÷÷ ÷ ÷ Uð ×ÒÐ0Ó1€ñ  ›EÐ Ó !õ4ñ “+€Ù	‹€ñ Ð.Ð0LÓMÐ ÙÐ2Ð4TÓUÐ ÙÐ2Ð4SÓTÐ õ;õ&Dõ÷õ6ñ2 ‹8€ð ×Ñð<Ð4EÐ3Gð <Ø!+ ö<ó ð<õ*Tð°$÷ õõ dõõõ<õõ8Jð !Ð ØÐ Ø%(Ð "Ù$›Ð Ø'ŸnšnÓ.Ð õFõSò
$ò7ò'õ
#õLõNõ]õ
ò=õ@Fð ×ÑÐ-Ó.ñ
 �r˜a CÔ(¹¸aÀA¼Ð\]Ø¨HÀUØ°TÐY]Ðlqö@9ó /ð@9ðF ×ÑÐ5Ó6Øöó ó 7ðõDnõ&)?ðX ×ÑÐ2Ó3Øöó ó 4ððH �ZŠZÐMÓN€
õ	Dð ×ÒÐ<Ó=ö7ó >ð7ð2 ×Ó�>Ñ1UÔVñCó WðCð ‡�ˆOÓñ"ó ð"ð ‡‚ˆ_ÓôEMó ðEMðP ‡�Ð"Ó#ñ)ó $ð)ð( ‡‚Ð#Ó$ôRó %ðRð ‡�Ð0Ó1ô5ó 2ð5ðJÐ õ+ð ‡‚Ð1Ó2ô,ó 3ð,ð* ‡‚Ð$Ó%ôgó &ðgð$ ‡‚Ð%Ó&ô+ó 'ð+ð( ‡�Ð'Ó(ô0ó )ð0ð ‡‚Ð'Ó(ôó )ðð* ‡‚Ð.Ó/ô
Hó 0ð
Hð ‡‚Ð(Ó)ô>ó *ð>ð ‡‚Ð1Ó2ô2ó 3ð2õ0Vð ‡‚Ð*Ó+ô0ó ,ð0ð" ‡‚Ð#Ó$ô`ó %ð`ð8 ‡�Ð2Ó3ô0ó 4ò0r7   