+
    jHàj¿u  ã                  óÊ  € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	H
t
 ^ RI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 R ltR R ltR R ltR R ltR R ltR R ltR R lt R R lt!R R lt"R R lt#R R  lt$R! R" lt%R#R$/R% R& llt&R' R( lt'R) R* lt(R+ R, lt)R- R. lt*R/ R0 lt+R1 R2 lt,R3 R4 lt-R5 R6 lt.R7 R8 lt/R9 R: lt0R; R< lt1R# )=z'CLI handlers for ``hermes egress ...``.)ÚannotationsN)Údatetime)ÚListÚOptional)ÚConsole)ÚPanel)ÚTable)Ú
iron_proxy)Úmask_secret)Úload_configÚload_envÚsave_configc               ó    € V ^8„  d   QhRRRR/# )é   Úparent_parserzargparse.ArgumentParserÚreturnÚNone© )Úformats   "Ú9/home/ubuntu/.hermes/hermes-agent/hermes_cli/proxy_cli.pyÚ__annotate__r      s   € ÷ 1'ñ 1'Ð 7ð 1'¸Dñ 1'ó    c                ó€  € V P                  RR7      pRR\        R\        RRR7      3.3R	R
\        R\        \        RR\
        P                   R2R7      3R\        RRR7      3R\        RRR7      3R\        RRR7      3R\        RRRRR7      3R\        RRRR7      3.3RR\        . 3R R!\        . 3RR"\        . 3R#R$\        . 3R%R&\        R'\        RR(R7      3.3R)R*\        . 3R+R,\        . 3.	pV FH  w  r4rVVP                  W4R-7      pV F  w  r‰VP                  ! V3/ V	B  K  	  VP!                  VR.7       KJ  	  R# )/z5Attach the egress subcommand tree to a parent parser.Úegress_command)ÚdestÚinstallz'Install the PM-pinned iron-proxy binaryz--forceÚ
store_truez"Verify and repair the managed copy)ÚactionÚhelpÚsetupz=Interactive wizard: install + CA + mint tokens + write configz--tunnel-portNz"Override the tunnel port (default Ú))ÚtypeÚdefaultr   z--from-bitwardenuÀ   Treat secrets as managed by Bitwarden â€” discover provider keys from secrets.bitwarden config instead of the current env.  Fails loudly if BW is unreachable rather than silently falling back.z--no-bitwardenz|Explicitly switch credential_source back to env on re-setup (only meaningful when the previous setup used --from-bitwarden).z--rotate-tokensu§   Mint fresh proxy tokens for every provider (default is to preserve tokens for providers that already had one â€” avoids 401-ing already-running sandboxes on re-setup).z	--restartÚrestartzŠIf a daemon is already running, restart it automatically after writing the new config/tokens (non-interactive default on a tty is to ask).)r   r   r"   r   z--no-restartÚstore_falsez|Do not restart a running daemon after setup; you'll need to run `hermes egress restart` yourself for changes to take effect.)r   r   r   ÚstartzStart the managed iron-proxyÚstopzStop the managed iron-proxyz<Restart the managed iron-proxy (stop if running, then start)Úreloaduo   Hot-reload the running daemon's ruleset from proxy.yaml (management API â€” no restart, no dropped connections)ÚstatuszShow proxy state and mappingsz--show-tokensziPrint the proxy tokens (default: redacted prefix only). Beware: tokens may persist in your shell history.ÚdisablezTurn off the proxy integrationÚconfigz#Print the generated proxy.yaml path)r   )Úfunc)Úadd_subparsersÚcmd_installÚdictÚ	cmd_setupÚintÚipÚ_DEFAULT_TUNNEL_PORTÚ	cmd_startÚcmd_stopÚcmd_restartÚ
cmd_reloadÚ
cmd_statusÚcmd_disableÚ
cmd_configÚ
add_parserÚadd_argumentÚset_defaults)
r   ÚsubÚcommandsÚnameÚ	help_textr+   Ú	argumentsÚparserÚflagÚkwargss
   &         r   Úregister_clirE      sé  € ð ×
&Ñ
&Ð,<Ð
&Ó
=€Cð 
Ð=¼{Øœ LÐ7[Ô\Ð]ðM
ð 	ð 
ÐQÔS\Øœd¬°TØ*LÌR×MdÑMdÐLeÐefÐ(gôið jà¤¨\ðQô"Sð Tð œt¨<ðSô Uð Vð ¤¨LðBô!Dð Eð œ$ I°lÈDð^ô`ð að œT y¸ðOôQð Rð#_
ð 	ð* 
Ð0´)¸RÐ@Ø	Ð.´¸"Ð=Ø	ÐRÔT_ÐacÐdØ	ð MÜNXÐZ\ð	^à	Ð2´JØœd¨,ðDôFð GðA
ð 	ð
 
Ð4´kÀ2ÐFØ	Ð8¼*ÀbÐIðI%€HóL -5Ñ(ˆ˜Ø—‘ �Ó5ˆÛ%‰LˆDØ×Ò Ñ/¨Ô/ñ &à×Ñ ÐÖ&ó	 -5r   c               ó    € V ^8„  d   QhRRRR/# ©r   Úargsúargparse.Namespacer   r0   r   )r   s   "r   r   r   I   s   € ÷ 
ñ 
Ð(ð 
¨Sñ 
r   c                óZ  € \        4       p \        P                  ! \        V P                  4      R 7      p\        P                  ! T4      ;'       g    RpTP                  RT RT 24       ^ #   \
         d1   pTP                  RT 24       TP                  R4        Rp?^# Rp?ii ; i))Úforceu   [red]âœ— install failed:[/red] z?  Manual install: https://github.com/ironsh/iron-proxy/releasesNú(version unknown)u   [green]âœ“[/green] installed ú  )r   r1   Úinstall_iron_proxyÚboolrK   Ú	ExceptionÚprintÚiron_proxy_version)rH   ÚconsoleÚbinaryÚexcÚversions   &    r   r-   r-   I   s•   € Ü‹i€GðÜ×&Ò&¬T°$·*±*Ó-=Ô>ˆô
 ×#Ò# FÓ+×BÐBÐ/B€GØ‡M�MÐ1°&°¸¸G¸9ÐEÔFÙøô ô Ø�‰Ð7¸°uÐ=Ô>Ø�‰ÐWÔXÝûðús   Œ*A/ Á/B*Á:%B%Â%B*c               ó    € V ^8„  d   QhRRRR/# rG   r   )r   s   "r   r   r   V   s   € ÷ !ñ !Ð&ð !¨3ñ !r   c                óv  € \        4       pVP                  \        P                  ! RRR7      4       \	        V4      '       g   ^# \        V4      pVf   ^# \        W4      pVf   ^# \        WV.VO5!  pVf   ^# \        WV4       VP                  4        VP                  R4       VP                  R4       ^ # )z\Four-step wizard; each ``_setup_*`` phase prints its own step and returns ``None`` to abort.zé[bold]iron-proxy setup[/bold]

Routes outbound sandbox traffic through a local TLS-intercepting
proxy so prompt-injected agents never see real provider API keys.

[dim]Project: https://github.com/ironsh/iron-proxy  (Apache-2.0)[/dim]Úcyan)Úborder_styleu_   [green]âœ“ iron-proxy is configured.[/green]  Sandboxes will route outbound traffic through it.aO    Start:   [cyan]hermes egress start[/cyan]
  Restart: [cyan]hermes egress restart[/cyan]  (after any re-setup)
  Reload:  [cyan]hermes egress reload[/cyan]   (apply ruleset edits in-place, no restart)
  Status:  [cyan]hermes egress status[/cyan]
  Stop:    [cyan]hermes egress stop[/cyan]
  Disable: [cyan]hermes egress disable[/cyan])	r   rQ   r   ÚfitÚ_setup_install_binaryÚ_setup_ca_certÚ_setup_mint_tokensÚ_setup_write_configÚ_setup_restart_daemon)rH   rS   ÚcaÚmappingsÚ	proxy_cfgs   &    r   r/   r/   V   s°   € ä‹i€GØ‡M�M”%—)’)ð	Qð ôô ô ! ×)Ò)ÙÜ	˜Ó	 €BØ	‚zÙÜ! 'Ó0€HØÒÙÜ# G°8ÐA¸bÓA€IØÒÙÜ˜'¨Ô3Ø‡M�M„OØ‡M�MÐsÔtØ‡M�Mð	8ôñ r   c               ó    € V ^8„  d   QhRRRR/# )r   rS   r   r   rO   r   )r   s   "r   r   r   z   s   € ÷ ñ  7ð ¨tñ r   c                ón  € \        V ^R4        \        P                  ! RR7      pVf'   V P                  R4       \        P                  ! 4       p\        P
                  ! V4      ;'       g    RpV P                  RV RV 24       R#   \         d!   pT P                  R	T R
24        Rp?R# Rp?ii ; i)é   zInstall the iron-proxy binaryF©Úinstall_if_missingNu*     No iron-proxy on PATH â€” downloadingâ€¦rL   õ     [green]âœ“[/green] rM   u     [red]âœ— install failed: ú[/red]T)Ú_stepr1   Úfind_iron_proxyrQ   rN   rR   rP   )rS   rT   rV   rU   s   &   r   r\   r\   z   s§   € Ü	ˆ'�1Ð5Ô6ð	Ü×#Ò#°uÔ=ˆØŠ>Ø�M‰MÐFÔGÜ×*Ò*Ó,ˆFÜ×'Ò'¨Ó/×FÐFÐ3FˆØ�‰Ð-¨f¨X°R¸°yÐAÔBñ øô ô Ø�‰Ð3°C°5¸Ð?Ô@Ýûðús   �AB	 Á-B	 Â	B4ÂB/Â/B4c               ó   € V ^8„  d   QhRR/# )r   rS   r   r   )r   s   "r   r   r   ‰   s   € ÷ ñ ˜Gñ r   c                óÖ   € \        V ^R4        \        P                  ! 4       w  rT P	                  RT 24       Y3#   \         d!   pT P	                  RT R24        Rp?R# Rp?ii ; i)r   zGenerate a CA certu!     [red]âœ— CA generation failed: rj   Nri   )rk   r1   Úensure_ca_certrP   rQ   )rS   Úca_crtÚca_keyrU   s   &   r   r]   r]   ‰   sm   € Ü	ˆ'�1Ð*Ô+ðÜ×*Ò*Ó,‰ˆð ‡M�MÐ)¨&¨Ð2Ô3Øˆ>Ðøô	 ô Ø�‰Ð9¸#¸¸fÐEÔFÝûðús   �= ½A(ÁA#Á#A(c               ó    € V ^8„  d   QhRRRR/# ©r   rS   r   rH   rI   r   )r   s   "r   r   r   ”   s   € ÷ Bñ B ð BÐ/Añ Br   c           	     ó&  € \        V ^R4       . pVP                  '       d   \        V 4      pVf   R# M'\        4       pV'       d   V P	                  RV R24       \
        P                  ! T;'       g    RR7      p\
        P                  ! 4       p\        \        VRR4      4      pV'       Ed   V'       dý   \        P                  P                  4       '       d5   V P	                  R4       \        R	4      R
8w  d   V P	                  R4       R#  \
        P                  ! 4       pVR,          pVP                  4       '       do   \         P"                  ! 4       P%                  R4      p	VRV	 2,          p
\&        P(                  ! \+        V4      \+        V
4      4       V P	                  RV
 R24       M!V'       d   V'       g   V P	                  R4       \
        P.                  ! WTVR7      pV'       gY   V P	                  R4       V P	                  R4       \1        \
        P2                  4       F  pV P	                  RV 24       K  	  R# \
        P4                  ! T;'       g    RR7      pV'       dP   V P	                  4        V P	                  R4       V F  pV P	                  RV 24       K  	  V P	                  R4       V P	                  \7        VRRRR7      4       V#   \,         d!   pT P	                  RT R24        Rp?EL6Rp?ii ; i)zVDiscover providers, merge with existing tokens (rotating on request), print the table.z%Mint proxy tokens for known providersNz  [dim]Loaded z> provider key name(s) from ~/.hermes/.env for discovery.[/dim])Úavailable_env_namesÚrotate_tokensFuŸ   [yellow]âš [/yellow]  --rotate-tokens will invalidate proxy tokens in every running Hermes sandbox.  They will start 401-ing against upstreams until restarted.zType 'rotate' to confirm: Úrotatez[yellow]Cancelled.[/yellow]zmappings.jsonz%Y%m%dT%H%M%Szmappings.json.rotated-z  [dim]backup: ú[/dim]z6  [yellow]Could not back up mappings before rotation: ú	[/yellow]z_[dim]Note: --rotate-tokens is a no-op on first-time setup (no existing tokens to rotate).[/dim])ÚexistingÚ
discoveredrw   zE  [yellow]No known provider API keys found in env/Bitwarden.[/yellow]z,  Set at least one of these and rerun setup:z    - uU     [yellow]âš [/yellow]  Detected provider env vars that the proxy does not yet cover:zÁ  [dim]These providers use request signing or SDK-minted OAuth (SigV4, service-account files) and will hold real credentials inside the sandbox.  Egress isolation is INCOMPLETE for these.[/dim]zProvider envzUpstream hosts©Úshow_tokens)rk   Úfrom_bitwardenÚ_bitwarden_env_namesÚ_load_env_file_into_environrQ   r1   Údiscover_provider_mappingsÚload_mappingsrO   ÚgetattrÚsysÚstdinÚisattyÚ_promptÚ_proxy_state_dirÚexistsr   ÚnowÚstrftimeÚshutilÚcopy2ÚstrÚOSErrorÚmerge_mappingsÚsortedÚ_BEARER_PROVIDERSÚdiscover_uncovered_providersÚ_mappings_table)rS   rH   ru   Úloadedr{   rz   rw   Ú	state_dirÚmappings_srcÚtsÚbackuprU   rb   Úenv_nameÚ	uncoveredr?   s   &&              r   r^   r^   ”   s�  € ä	ˆ'�1Ð=Ô>Ø%'ÐØ××ÐÜ2°7Ó;ÐØÒ&Ùð 'ô
 -Ó.ˆßØ�M‰M˜N¨6¨(Ð2pÐqÔrÜ×.Ò.ÐCV×C^ÐC^ÐZ^Ô_€Jô ×ÒÓ!€HÜ”'˜$ °Ó7Ó8€Fß€v—(ô �9‰9×Ñ×ÒØ�M‰Mðvôô Ð3Ó4¸Ô@Ø—‘Ð;Ô<Ùð		cÜ×+Ò+Ó-ˆIØ$ Õ6ˆLØ×"Ñ"×$Ò$Ü—\’\“^×,Ñ,¨_Ó=�Ø"Ð'=¸b¸TÐ%BÕB�Ü—’œS Ó.´°F³Ô<Ø—‘ °¨x°vÐ>Ô?ø÷ 
ŸØ�‰Ømô	
ô × Ò ¨(ÐRXÔY€HßØ�‰Ð]Ô^Ø�‰ÐDÔEÜœr×3Ñ3Ö4ˆHØ�M‰M˜F 8 *Ð-Ö.ñ 5áô ×/Ò/ÐDW×D_ÐD_Ð[_Ô`€IßØ�‰ŒØ�‰ÐmÔnÛˆDØ�M‰M˜F 4 &˜/Ö*ñ à�‰ð_ô	
ð
 ‡M�M”/ (¨NÐ<LÐZ_Ô`ÔaØ€Oøô7 ô 	cØ�M‰MÐRÐSVÐRWÐW`Ða×bÒbûð	cús   Ä3K% ÅA.K% Ë%LË0LÌLc               ó    € V ^8„  d   QhRRRR/# rs   r   )r   s   "r   r   r   Ù   s   € ÷ Iñ I ð IÐ0Bñ Ir   c                óÈ  € \        V ^R4       \        4       pVP                  R/ 4      pVP                  eL   VP                  ^8  g   VP                  R8”  d   V P	                  R4       R# \        VP                  4      pM)\        VP                  R\        P                  4      4      pWvR&   \        VP                  R4      ;'       g    . 4      p\        \        P                  4      V U	u. uF  q™\        P                  9  g   K  V	NK  	  up	,           p
\        P                  ! 4       R,          pR	p \        P                  ! V4       \        P                  ! VVVVVV
VP                  R4      R7      p\        P                  ! V4      p\        P                   ! V4      p\        P"                  ! 4        V P	                  RV 24       V P	                  RV 24       V'       d   V P	                  RV R24       R	VR&   VP                  RR	4       VP                  RR	4       VP                  R4      pVP$                  '       d   RVR&   MO\'        VRR
4      '       d   RVR&   VR8X  d   V P	                  R4       MVR8X  d   V P	                  R4       MRVR&   \)        V4       V# u up	i   \         d#   pR
pT P	                  RT R24        Rp?EL�Rp?ii ; i)zZWrite proxy.yaml + mappings, then enable the integration in config; returns ``proxy_cfg``.z!Write config and persist mappingsÚproxyNiþÿ  ua     [red]âœ— --tunnel-port must be between 1 and 65534 (the plain-HTTP listener uses port+1).[/red]Útunnel_portÚextra_allowed_hostsz	audit.logTFu     [yellow]âš  ry   Úupstream_deny_cidrs)rb   Úca_certrq   rŸ   Ú	audit_logÚallowed_hostsr¡   u     [green]âœ“[/green] config:   u     [green]âœ“[/green] mappings: u      [green]âœ“[/green] audit log: uf    [dim](reserved â€” not written by iron-proxy v0.39; per-request records land in iron-proxy.log)[/dim]ÚenabledÚauto_installÚenforce_on_dockerÚcredential_sourceÚ	bitwardenÚno_bitwardenÚenvzB[yellow]Switched credential_source from bitwarden to env.[/yellow]z|[dim]Keeping credential_source=bitwarden from existing config. Pass --no-bitwarden to switch to env-based credentials.[/dim])rk   r   Ú
setdefaultrŸ   rQ   r0   Úgetr1   r2   ÚlistÚ_DEFAULT_ALLOWED_HOSTSrˆ   Úensure_audit_logÚRuntimeErrorÚbuild_proxy_configÚwrite_proxy_configÚwrite_mappingsÚensure_management_tokenr~   rƒ   r   )rS   rH   rb   rp   rq   Úcfgrc   rŸ   Úextra_hostsÚhÚallowedÚaudit_log_pathÚaudit_log_okrU   Úiron_cfgÚcfg_pathÚmappings_pathÚexisting_sources   &&&&&             r   r_   r_   Ù   s­  € ä	ˆ'�1Ð9Ô:Ü
‹-€CØ—‘˜w¨Ó+€Ið ×ÑÒ#Ø×Ñ˜aÔ 4×#3Ñ#3°eÔ#;Ø�M‰MØsôñ Ü˜$×*Ñ*Ó+‰ä˜)Ÿ-™-¨´r×7NÑ7NÓOÓPˆØ*ˆmÑÜ�y—}‘}Ð%:Ó;×AÐA¸rÓB€KÜ”2×,Ñ,Ó-¹KÓ0n¹K°qÔTV×TmÑTmÑKm·°¹KÑ0nÕn€Gô ×(Ò(Ó*¨[Õ8€NØ€Lð7Ü
×Ò˜NÔ+ô ×$Ò$ØØØØØ ØØ%ŸM™MÐ*?Ó@ô€Hô ×$Ò$ XÓ.€HÜ×%Ò% hÓ/€Mô ×ÒÔ Ø‡M�MÐ3°H°:Ð>Ô?Ø‡M�MÐ3°M°?ÐCÔDßØ�‰Ø.¨~Ð.>ð ?@ð Aô	
ð
  €IˆiÑØ×Ñ˜¨Ô.Ø×ÑÐ,¨dÔ3ð  —m‘mÐ$7Ó8€OØ××ÐØ)4ˆ	Ð%Ò&Ü	��~ u×	-Ò	-Ø).ˆ	Ð%Ñ&Ø˜kÔ)Ø�M‰MÐ^Ô_øØ	˜KÔ	'Ø�‰ðLõ	
ð
 */ˆ	Ð%Ñ&Ü�ÔØÐùòo 1oøô ô 7ØˆØ�‰˜ s e¨9Ð5×6Ò6ûð7ús$   Ã0J/ÄJ/Ä9J4 Ê4K!Ê?KËK!c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   rS   r   rH   rI   rc   r.   r   r   r   )r   s   "r   r   r   %  s+   € ÷ (
ñ (
 7ð (
Ð2Dð (
ÐQUð (
ÐZ^ñ (
r   c                ó
  € \         P                  ! 4       P                  RJpV'       d   \         P                  ! 4        \	        VRR4      pVRJ g   VRJ d   TpM?V'       d6   \
        P                  P                  4       '       d   \        R4      R9   MRpMRpV'       dˆ    \         P                  ! \        VP                  RR4      4      R7      pVP                  '       d   RMR	pV'       d   R
MRpV P                  RV RVP                   RVP                   RV R2	4       R# V'       d   V P                  R4       R# R#   \         d2   p	T P                  RT	 R24       T P                  R4        Rp	?	R# Rp	?	ii ; i)u[  Stop a running daemon and decide whether to (re)start it with the new config.

--restart â†’ always (re)start; --no-restart â†’ never (print the manual hint); neither + tty â†’
ask only when a daemon was running; neither + !tty â†’ restart iff one was running (first-time
setup never auto-starts â€” matches the "configured, now run start" flow).
Nr#   TFz;  Restart the running proxy now with the new config? [Y/n] r¦   rg   Ú	listeningznot yet listeningÚ	restartedÚstartedri   z% iron-proxy with the new config (pid=z, port=ú, r    u>     [yellow]âš  could not start iron-proxy with the new config: ry   zV  Run [cyan]hermes egress start[/cyan] manually before launching new Docker sandboxes.u·     [yellow]âš  stopped the running iron-proxy; config or tokens changed.  Run [cyan]hermes egress restart[/cyan] (or [cyan]start[/cyan]) before launching new Docker sandboxes.[/yellow])Ú ÚyÚyes)r1   Ú
get_statusÚpidÚ
stop_proxyrƒ   r„   r…   r†   r‡   Ústart_proxyrO   r­   rÂ   rQ   rŸ   rP   )
rS   rH   rc   Úwas_runningÚrestart_prefÚ
do_restartÚ
new_statusrÂ   ÚverbrU   s
   &&&       r   r`   r`   %  s`  € ô —-’-“/×%Ñ%¨TÐ1€KßÜ
�ŠŒÜ˜4 ¨DÓ1€LØ�tÓ˜|¨uÓ4Ø!‰
ß	ô �y‰y×Ñ×!Ò!ô ÐQÓRØò ð ñ	 	ð ˆ
ßð	ÜŸš¼4À	ÇÁÈnÐ^bÓ@cÓ;dÔeˆJð
 (2×';×';Ð';™ÐATˆIß"-‘;°9ˆDØ�M‰MØ'¨ vð .Ø"Ÿ™Ð' w¨z×/EÑ/EÐ.FÀbÈÈÐSTðVö÷ 
Ø�‰ðRö	
ñ 
øô ô 	tØ�M‰MÐZÐ[^ÐZ_Ð_hÐiÔjØ�M‰MÐr×sÒsûð	tús   Â#0E ÅFÅ&E=Å=Fc               ó    € V ^8„  d   QhRRRR/# rG   r   )r   s   "r   r   r   P  s   € ÷ Eñ EÐ&ð E¨3ñ Er   c                ó^  € \        4       p\        4       pVP                  R 4      ;'       g    / pVP                  R4      '       g   VP                  R4       ^# VP                  RR4      pVP                  R4      ;'       g    / P                  R4      pVR8H  ;'       d'    VRJ;'       d    \	        VP                  R4      4      pVR8X  dI   V'       gA   \	        VP                  RR	4      4      '       d   VP                  R
4       M\        VRR4      # V'       d.   Ve*   \        V4      p\	        VP                  RR	4      4      VR&   V'       d�   T;'       g    / P                  RR4      p\        P                  P                  VR4      P                  4       '       g   \        VRV R2R4      # T;'       g    / P                  R4      '       g   \        VRR4      #  \        P                  ! \	        VP                  RR4      4      VVR7      pTP                  '       g   TP                  R4       ^# TP                  '       d   RMRp
TP                  RTP                   RTP                   RT
 24       ^ #   \         d    p	TP                  RT	 24        Rp	?	^# Rp	?	ii ; i) rž   r¥   uL   [yellow]proxy.enabled is false â€” run `hermes egress setup` first.[/yellow]r¨   r«   Úsecretsr©   NÚallow_env_fallbackFuÉ   [yellow]âš  credential_source=bitwarden but secrets.bitwarden is disabled or missing â€” falling back to host-env secrets (allow_env_fallback=true).  Rotated Bitwarden keys will NOT propagate.[/yellow]zTproxy.credential_source is 'bitwarden' but secrets.bitwarden is disabled or missing.zÆRe-enable it (`secrets.bitwarden.enabled: true`), switch back to env credentials with `hermes egress setup --no-bitwarden`, or set `proxy.allow_env_fallback: true` to opt into the host-env fallback.Úaccess_token_envÚBWS_ACCESS_TOKENrÆ   z credential_source=bitwarden but z is not set in the environment.ztEither export the access token, or run `hermes egress setup --no-bitwarden` to switch back to env-based credentials.Ú
project_idzFcredential_source=bitwarden but secrets.bitwarden.project_id is empty.zwRun `hermes secrets bitwarden setup` to configure the project, or switch back via `hermes egress setup --no-bitwarden`.r¦   T)rh   Úrefresh_secrets_from_bitwardenÚbitwarden_configu+   [red]âœ— failed to start iron-proxy:[/red] u1   [red]âœ— iron-proxy did not come up cleanly[/red]z[green]listening[/green]z"[yellow]not yet listening[/yellow]u+   [green]âœ“[/green] iron-proxy running  pid=z  port=rM   )r   r   r­   rQ   rO   Ú_refuser.   ÚosÚenvironÚstripr1   rÌ   rP   rÊ   rÂ   rŸ   )rH   rS   r¶   rc   r¨   Úbw_cfgÚ
refresh_bwÚbw_access_envr(   rU   rÂ   s   &          r   r3   r3   P  sv  € Ü‹i€GÜ
‹-€CØ—‘˜Ó ×&Ð& B€IØ�=‰=˜×#Ò#Ø�‰ÐdÔeÙð "Ÿ™Ð&9¸5ÓAÐØ�g‰g�iÓ ×&Ð& B×+Ñ+¨KÓ8€FØ# {Ñ2×iÐi°vÀTÐ7I×iÐiÌdÐSY×S]ÑS]Ð^gÓShÓNi€Jð ˜KÔ'·
Ü�	—‘Ð2°EÓ:×;Ò;Ø�M‰Mðvõô
 ØØfðnóð ÷ �fÒ(Ü�f“ˆÜ'+¨I¯M©MÐ:NÐPUÓ,VÓ'WˆÐ#Ñ$÷ ØŸ˜ 2×*Ñ*Ð+=Ð?QÓRˆÜ�z‰z�~‰~˜m¨RÓ0×6Ñ6×8Ò8ÜØØ2°=°/ÐA`Ðað`óð ð —�˜"×!Ñ! ,×/Ò/ÜØØXðTóð ðÜ—’Ü# I§M¡M°.À$Ó$GÓHØ+5Ø#ô
ˆð �:�:ˆ:Ø�‰ÐIÔJÙØ/5×/?×/?Ð/?Ñ+ÐEi€IØ‡M�MØ
5°f·j±j°\ÀÈ×I[ÑI[ÐH\Ð\^Ð_hÐ^iÐjôñ øô ô Ø�‰ÐCÀCÀ5ÐIÔJÝûðús   Ç%2J ÊJ,ÊJ'Ê'J,c               ó    € V ^8„  d   QhRRRR/# rG   r   )r   s   "r   r   r   ˜  s   € ÷ ñ Ð%ð ¨#ñ r   c                ó˜   € \        4       p\        P                  ! 4       '       d   VP                  R 4       ^ # VP                  R4       ^ # )u%   [green]âœ“[/green] iron-proxy stoppedz%[dim]iron-proxy was not running[/dim])r   r1   rË   rQ   ©rH   rS   s   & r   r4   r4   ˜  s8   € Ü‹i€GÜ	‡}‚}‡‚Ø�‰Ð=Ô>ñ ð 	�‰Ð=Ô>Ùr   c               ó    € V ^8„  d   QhRRRR/# rG   r   )r   s   "r   r   r   ¡  s   € ÷ ñ Ð(ð ¨Sñ r   c                ó„   € \        4       p\        P                  ! 4       '       d   VP                  R4       \	        V 4      # )z^Stop the daemon (if any) then delegate to ``cmd_start`` so every credential-source guard runs.z)[dim]stopped the running iron-proxy[/dim])r   r1   rË   rQ   r3   rä   s   & r   r5   r5   ¡  s+   € ä‹i€GÜ	‡}‚}‡‚Ø�‰ÐAÔBÜ�T‹?Ðr   c               ó    € V ^8„  d   QhRRRR/# rG   r   )r   s   "r   r   r   ©  s   € ÷ ñ Ð'ð ¨Cñ r   c                óä   € \        4       p \        P                  ! 4        TP	                  R4       TP	                  R4       ^ #   \         d    pTP	                  RT 24        Rp?^# Rp?ii ; i)a   Hot-reload the ruleset via the management API (no restart, no dropped connections).

New upstream SECRETS still need ``hermes egress restart``: the daemon reads credentials from
its own environment at spawn time and a reload does not re-populate that env.
u   [red]âœ— reload failed:[/red] Nu[   [green]âœ“[/green] iron-proxy ruleset reloaded in-place (no restart, connections preserved)u°   [dim]Note: new upstream secrets (rotated keys, new providers) still need `hermes egress restart` â€” the daemon reads real credentials from its environment at spawn time.[/dim])r   r1   Úreload_proxyrP   rQ   )rH   rS   rU   s   &  r   r6   r6   ©  si   € ô ‹i€GðÜ
�ŠÔð ‡M�MÐoÔpØ‡M�Mð	@ôñ
 øô ô Ø�‰Ð6°s°eÐ<Ô=Ýûðús   ŒA ÁA/ÁA*Á*A/r}   Fc               ó    € V ^8„  d   QhRRRR/# )r   r}   rO   r   rŽ   r   )r   s   "r   r   r   ¾  s   € ÷ ñ  tð ¸ñ r   c                ó"  € \        4       pVP                  R4      ;'       g    / p\        P                  ! 4       pRR.pVP	                  R \        W#R R R7       4       4       VP                  R4       \        P                  ! 4       pV'       d„   VP	                  RR	.4       V Fj  pV '       d   VP                  M\        VP                  4      pVP                  R
VP                   RV RRP                  VP                  4       R24       Kl  	  \        P                  ! 4       pV'       d1   VP	                  RR.4       V F  p	VP                  R
V	 24       K  	  \        VP                  R4      4      '       d'   VP                  '       g   VP	                  RR.4       MW\        VP                  R4      4      '       d8   VP                   '       d   VP"                  '       g   VP	                  RR.4       RP                  V4      # )zDPlain-text egress status for slash commands, Dashboard, and Desktop.rž   zEgress proxy statusrÆ   c              3  ó4   "  € T F  w  rV R V 2x € K  	  R# 5i)ú: Nr   )Ú.0ÚlabelÚvalues   &  r   Ú	<genexpr>Ú%format_status_text.<locals>.<genexpr>Ä  s$   é € ð áo‰LˆEð ˆ'��E�7ÕÛoùs   ‚c                ó   € V '       d   R # R# )rÈ   Únor   )Úvs   &r   Ú<lambda>Ú$format_status_text.<locals>.<lambda>Æ  s   € ×RSÈÐI]ÐY]ÐI]r   c                ó   € V # )Nr   ©Úts   &r   rö   r÷   Æ  s   € Ñmnr   ©ÚynÚdimz*Scope: Docker backend only in this releasezToken mappings:ú  - rí   z (rÅ   r    zHUncovered providers (real credentials still visible inside the sandbox):r¥   zDNext: run `hermes egress setup` to mint tokens and write proxy.yaml.zBNext: run `hermes egress start` before launching Docker sandboxes.Ú
)r   r­   r1   rÉ   ÚextendÚ_status_rowsÚappendr‚   Úproxy_tokenr
   Úreal_env_nameÚjoinÚupstream_hostsr“   rO   Ú
configuredrÊ   rÂ   )
r}   r¶   rc   r(   Úlinesrb   ÚmÚtokr›   r?   s
   $         r   Úformat_status_textr  ¾  s›  € ä
‹-€CØ—‘˜Ó ×&Ð& B€IÜ�]Š]‹_€FØ" BÐ'€EØ	‡L�Lñ ä(¨Ñ?]ÑcnÕoóô ð 
‡L�LÐ=Ô>Ü×ÒÓ!€HßØ�‰�bÐ+Ð,Ô-ÛˆAß#.�!—-’-´KÀÇÁÓ4NˆCØ�L‰L˜4 §¡Ð0°°3°%°r¸$¿)¹)ÀA×DTÑDTÓ:UÐ9VÐVWÐXÖYñ ô ×/Ò/Ó1€IßØ�‰�bÐdÐeÔfÛˆDØ�L‰L˜4 ˜v˜Ö'ñ äˆI�M‰M˜)Ó$×%Ò%¨f×.?×.?Ð.?Ø�‰�bÐ`ÐaÕbÜ	ˆi�m‰m˜IÓ&×	'Ò	'°··°À×@P×@PÐ@PØ�‰�bÐ^Ð_Ô`Ø�9‰9�UÓÐr   c               ó    € V ^8„  d   QhRRRR/# rG   r   )r   s   "r   r   r   Û  s   € ÷ ñ Ð'ð ¨Cñ r   c           	     ó6  € \        4       p\        4       pVP                  R 4      ;'       g    / p\        P                  ! 4       p\        RRRR7      pVP                  RRR7       VP                  R4       \        W4\        R R7       F  w  rgVP                  Wg4       K  	  VP                  V4       \        P                  ! 4       pV'       dm   VP                  4        VP                  R	4       VP                  \        VR
RV P                  R7      4       V P                  '       d   VP                  R4       \        P                  ! 4       p	V	'       d?   VP                  4        VP                  R4       V	 F  p
VP                  RV
 24       K  	  ^ # )rž   FN)Úshow_headerÚboxÚpaddingrÆ   Úbold©Ústylec                ó   € R V  R2# )z[dim]rx   r   rù   s   &r   rö   Úcmd_status.<locals>.<lambda>ã  s   € ÐPUÐVWÐUXÐX^ÑN_r   rû   z[bold]Token mappings[/bold]zReal envÚUpstreamr|   u�   [yellow]âš [/yellow]  proxy tokens just printed in full â€” they may persist in your shell history.  Consider clearing it after this command.zY[yellow]Uncovered providers[/yellow] (real credentials still visible inside the sandbox):rþ   )é    r   )r   r   r­   r1   rÉ   r   Ú
add_columnr  Ú_ynÚadd_rowrQ   r‚   r”   r}   r“   )rH   rS   r¶   rc   r(   Útablerï   rð   rb   r›   r?   s   &          r   r7   r7   Û  s:  € Ü‹i€GÜ
‹-€CØ—‘˜Ó ×&Ð& B€IÜ�]Š]‹_€FÜ˜e¨°vÔ>€EØ	×Ñ�R˜vÐÔ&Ø	×Ñ�RÔÜ$ Y¼3ÑD_×`‰ˆØ�‰�eÖ#ñ aà‡M�M�%ÔÜ×ÒÓ!€HßØ�‰ŒØ�‰Ð3Ô4Ø�‰”o h°
¸JÐTX×TdÑTdÔeÔfØ××ÐØ�M‰Mðdôô
 ×/Ò/Ó1€IßØ�‰ŒØ�‰ÐqÔrÛˆDØ�M‰M˜D  ˜-Ö(ñ ár   c               ó    € V ^8„  d   QhRRRR/# rG   r   )r   s   "r   r   r   ú  s   € ÷ ñ Ð(ð ¨Sñ r   c                óL  € \        4       p\        4       pVP                  R / 4      pVP                  R4      '       g   VP	                  R4       ^ # RVR&   \        V4       VP	                  R4       \        P                  ! 4       P                  e   VP	                  R4       ^ # )rž   r¥   z+[dim]proxy.enabled was already false.[/dim]Fu-   [green]âœ“[/green] proxy.enabled set to falseug     iron-proxy is still running â€” stop it with [cyan]hermes egress stop[/cyan] if you want it down too.)	r   r   r¬   r­   rQ   r   r1   rÉ   rÊ   )rH   rS   r¶   rc   s   &   r   r8   r8   ú  s†   € Ü‹i€GÜ
‹-€CØ—‘˜w¨Ó+€IØ�=‰=˜×#Ò#Ø�‰ÐCÔDÙØ €IˆiÑÜ�ÔØ‡M�MÐAÔBô 
‡}‚}ƒ×ÑÒ&Ø�‰Øuô	
ñ r   c               ó    € V ^8„  d   QhRRRR/# rG   r   )r   s   "r   r   r     s   € ÷ ñ Ð'ð ¨Cñ r   c                óÎ   € \        4       p\        P                  ! 4       pVP                  f   VP	                  R4       ^# VP	                  \        VP                  4      4       ^ # )NuD   [yellow](no config generated â€” run `hermes egress setup`)[/yellow])r   r1   rÉ   Úconfig_pathrQ   rŽ   )rH   rS   r(   s   &  r   r9   r9     sJ   € Ü‹i€GÜ�]Š]‹_€FØ×ÑÒ!Ø�‰Ð\Ô]ÙØ‡M�M”#�f×(Ñ(Ó)Ô*Ùr   c               ó    € V ^8„  d   QhRRRR/# )r   rS   r   r   zOptional[list[str]]r   )r   s   "r   r   r     s   € ÷ #ñ # 'ð #Ð.Añ #r   c                ó2  € \        4       pVP                  R4      ;'       g    / P                  R4      ;'       g    / pVP                  R4      '       g%   V P                  R4       V P                  R4       R#  ^ RIHp VP                  RR	4      p\
        P                  P                  VR
4      P                  4       pV'       g   V P                  RV R24       R# VP                  WRP                  RR
4      ^ RR7      w  rg\        VP                  4       4      pV'       g   V P                  R4       R# V P                  R\        V4       R24       V#   \         d2   p	T P                  RT	 R24       T P                  R4        Rp	?	R# Rp	?	ii ; i)z¶Secret names from Bitwarden for ``setup --from-bitwarden``; prints the error and returns
``None`` on any failure so the wizard aborts loudly instead of falling back to the host env.
rÔ   r©   r¥   uS     [red]âœ— --from-bitwarden requested but secrets.bitwarden.enabled is false.[/red]zG  Run `hermes secrets bitwarden setup` first, or omit --from-bitwarden.N)r©   rÖ   r×   rÆ   u*     [red]âœ— --from-bitwarden requested but z% is not set in the environment.[/red]rØ   F)Úaccess_tokenrØ   Úcache_ttl_secondsÚ	use_cacheu�     [red]âœ— Bitwarden returned an empty secrets list.[/red]
  Check the project_id in secrets.bitwarden and the BWS access-token's project scope.z	  Pulled z env names from Bitwarden.u2     [red]âœ— Could not enumerate Bitwarden secrets: rj   z›  Either fix the Bitwarden config and retry, or rerun setup without --from-bitwarden (the proxy will read secrets from the host process env at start time).)r   r­   rQ   Úagent.secret_sourcesr©   rÜ   rÝ   rÞ   Úfetch_bitwarden_secretsr®   ÚkeysÚlenrP   )
rS   r¶   rß   ÚbwÚ	token_envr#  rÔ   Ú_ÚnamesrU   s
   &         r   r   r     sg  € ô ‹-€CØ�g‰g�iÓ ×&Ð& B×+Ñ+¨KÓ8×>Ð>¸B€FØ�:‰:�i× Ò Ø�‰ÐkÔlØ�‰Ð_Ô`ÙðÝ8Ø—J‘JÐ1Ð3EÓFˆ	Ü—z‘z—~‘~ i°Ó4×:Ñ:Ó<ˆßØ�M‰MÐFÀyÀkÐQvÐwÔxÙØ×/Ñ/Ø%·*±*¸\È2Ó2NÐbcÐotð 0ó 
‰
ˆô �W—\‘\“^Ó$ˆßØ�M‰Mðhôñ Ø�‰˜	¤# e£* Ð-GÐHÔIØˆøÜô Ø�‰ÐJÈ3È%ÈvÐVÔWØ�‰ðnô	
õ ûðús,   Á;AE Ã	E Ã AE Ä:E ÅFÅ%&FÆFc               ó   € V ^8„  d   QhRR/# )r   r   r0   r   )r   s   "r   r   r   =  s   € ÷ ñ  Sñ r   c                 óæ  €  \        4       p ^ p\        \        P                  4      \        \        P
                  4      ,          pT F”  pT\        P                  9   d.   \        P                  T,          P                  4       '       d   KE  T P                  T4      ;'       g    RP                  4       pT'       g   Kx  T\        P                  T&   T^,          pK–  	  T#   \         d     ^ # i ; i)z¹Backfill known provider keys from ``~/.hermes/.env`` into ``os.environ``; returns the count.
Never overrides an exported value; only known provider names, so unrelated secrets stay out.rÆ   )
r   rP   Úsetr1   r’   Ú_NON_BEARER_PROVIDERSrÜ   rÝ   rÞ   r­   )Úfile_envÚaddedÚknownr?   Úvals        r   r€   r€   =  s»   € ðÜ“:ˆð €EÜ”×$Ñ$Ó%¬¬B×,DÑ,DÓ(EÕE€EÛˆØ”2—:‘:Ô¤"§*¡*¨TÕ"2×"8Ñ"8×":Ò":ÙØ�|‰|˜DÓ!×'Ð' R×.Ñ.Ó0ˆß‰3Ø"ŒB�J‰J�tÑØ�Q�JŠEñ ð €Løô ô Úðús   ‚
C! Ã!C0Ã/C0c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Ú
env_headerrŽ   Úhosts_headerr}   rO   r   r   r   )r   s   "r   r   r   P  s*   € ÷ ñ ¨#ð ¸Sð ÐRVð Ð[`ñ r   c               ób  € \        R RR7      pVP                  VRR7       VP                  VRR7       VP                  RRR7       V  Fb  pV'       d   VP                  M\        VP                  4      pVP	                  VP
                  RP                  VP                  4      V4       Kd  	  V# )	Tr  )r  Úheader_stylerY   r  rý   zProxy tokenÚgreenrÅ   )r   r  r  r
   r  r  r  r  )rb   r7  r8  r}   r  r	  r
  s   &&&$   r   r”   r”   P  s‘   € Ü˜d°Ô8€EØ	×Ñ�Z vÐÔ.Ø	×Ñ�\¨ÐÔ/Ø	×Ñ�]¨'ÐÔ2Ûˆß*ˆa�mŠm´¸A¿M¹MÓ0JˆØ�‰�a—o‘o t§y¡y°×1AÑ1AÓ'BÀCÖHñ ð €Lr   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   rS   r   Únr0   ÚtitlerŽ   r   r   r   )r   s   "r   r   r   [  s(   € ÷ 5ñ 5�7ð 5˜sð 5¨3ð 5°4ñ 5r   c                óT   € V P                  4        V P                  R V RV 24       R# )z[bold]Step z	[/bold]  N©rQ   )rS   r=  r>  s   &&&r   rk   rk   [  s$   € Ø‡M�M„OØ‡M�M�K ˜s )¨E¨7Ð3Ö4r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rS   r   ÚreasonrŽ   Úhintr   r0   r   )r   s   "r   r   r   `  s(   € ÷ ñ �Wð  cð °ð ¸ñ r   c                óX   € V P                  RV R24       V P                  RV 24       ^# )uX   Print a ``âœ— Refusing to start`` headline plus an indented remedy; returns exit code 1.u   [red]âœ— Refusing to start: rj   rM   r@  )rS   rB  rC  s   &&&r   rÛ   rÛ   `  s-   € à‡M�MÐ0°°¸Ð?Ô@Ø‡M�M�B�t�f�+ÔÙr   c               ó    € V ^8„  d   QhRRRR/# )r   rð   rO   r   rŽ   r   )r   s   "r   r   r   g  s   € ÷ >ñ >ˆtð >˜ñ >r   c                ó   € V '       d   R # R# )z[green]yes[/green]z[dim]no[/dim]r   )rð   s   &r   r  r  g  s   € ß#(ÐÐ=¨oÐ=r   c               ó    € V ^8„  d   QhRRRR/# )r   ÚtextrŽ   r   r   )r   s   "r   r   r   k  s   € ÷ ñ �#ð ˜#ñ r   c                óv   €  \        V 4      P                  4       P                  4       #   \         d     R# i ; i)zJ``input()`` lowered+stripped; EOF (closed stdin) reads as an empty answer.rÆ   )ÚinputrÞ   ÚlowerÚEOFError)rH  s   &r   r‡   r‡   k  s5   € ðÜ�T‹{× Ñ Ó"×(Ñ(Ó*Ð*øÜô Úðús   ‚&) ©8·8c               ó    € V ^8„  d   QhRRRR/# )r   rc   r.   r   zlist[tuple[str, str]]r   )r   s   "r   r   r   s  s   € ÷ ñ ˜Dð Ð9Nñ r   c               óˆ  € RV! \        V P                  R4      4      4      3R\        VP                  ;'       g	    V! R4      4      3RVP                  ;'       g	    V! R4      3R\        VP
                  ;'       g	    V! R4      4      3R	\        VP                  ;'       g	    V! R4      4      3R
\        VP                  4      3RVP                  '       d   RVP                   2MV! R4      3RV! VP                  4      3R\        V P                  RR4      4      3RV! \        V P                  RR4      4      4      3.
# )z£``(label, value)`` rows shared by the rich ``status`` table and the plain-text variant;
``yn`` renders booleans, ``dim`` wraps placeholder text for missing values.ÚEnabledr¥   ÚBinaryz	(missing)zBinary versionz	(unknown)ÚConfigz(not generated)zCA certzTunnel portÚProcesszpid z	(stopped)Ú	ListeningzCredential srcr¨   r«   zDocker enforcer§   T)
rO   r­   rŽ   Úbinary_pathÚbinary_versionr   Úca_cert_pathrŸ   rÊ   rÂ   )rc   r(   rü   rý   s   &&$$r   r  r  s  s%  € ð 
‘B”t˜IŸM™M¨)Ó4Ó5Ó6Ð7Ø	”3�v×)Ñ)×=Ð=©S°Ó-=Ó>Ð?Ø	˜6×0Ñ0×DÐD±C¸Ó4DÐEØ	”3�v×)Ñ)×CÐC©SÐ1BÓ-CÓDÐEØ	”C˜×+Ñ+×EÐE©sÐ3DÓ/EÓFÐGØ	œ˜F×.Ñ.Ó/Ð0Ø	¨6¯:¯:¨:�d˜6Ÿ:™:˜,Ñ'¹3¸{Ó;KÐLØ	‘b˜×)Ñ)Ó*Ð+Ø	œ3˜yŸ}™}Ð-@À%ÓHÓIÐJØ	™2œd 9§=¡=Ð1DÀdÓ#KÓLÓMÐNðð r   )2Ú__doc__Ú
__future__r   ÚargparserÜ   rŒ   r„   r   Útypingr   r   Úrich.consoler   Ú
rich.panelr   Ú
rich.tabler   Úagent.proxy_sourcesr	   r1   Úagent.redactr
   Úhermes_cli.configr   r   r   rE   r-   r/   r\   r]   r^   r_   r`   r3   r4   r5   r6   r  r7   r8   r9   r   r€   r”   rk   rÛ   r  r‡   r  r   r   r   Ú<module>ra     s»   ðÙ -å "ã Û 	Û Û 
Ý ß !å  Ý Ý å 0Ý $ß @Ñ @õ1'õh
õ!õHõõBõJIõX(
õVEõPõõð*¨e÷ õ:õ>õ&õ#õLõ&õ5õ
õ>õ÷r   