
    Pmj                        d Z ddlmZ ddlZddlZddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZmZ d&dZd'dZd'dZd'dZd'dZd'dZd'dZddd(dZd'dZd'dZd'd Zd)d!Zd*d#Zd+d%Z dS ),u  CLI handlers for ``hermes egress ...``.

Subcommands:
    install  — download the pinned iron-proxy binary
    setup    — interactive wizard: install binary, generate CA, mint tokens, write config
    start    — launch the proxy as a managed subprocess
    stop     — terminate the managed proxy
    status   — show binary version + config presence + listen state + mappings
    disable  — flip ``proxy.enabled`` to False (does not stop a running proxy)
    config   — print the generated proxy.yaml path (for debugging / external review)

The top-level command is ``hermes egress``.  Note that the inbound OAuth
reverse-proxy command (``hermes proxy``) lives elsewhere in
``hermes_cli/main.py`` — different direction, different purpose.
    )annotationsN)List)Console)Panel)Table)
iron_proxy)load_configsave_configparent_parserargparse.ArgumentParserreturnNonec                   |                      d          }|                    ddt          j         d          }|                    ddd	
           |                    t                     |                    dd          }|                    dt          ddt          j         d           |                    ddd
           |                    ddd
           |                    ddd
           |                    ddddd           |                    dddd           |                    t                     |                    d d!          }|                    t                     |                    d"d#          }|                    t                     |                    dd$          }|                    t                     |                    d%d&          }|                    t                     |                    d'd(          }|                    d)dd*
           |                    t                     |                    d+d,          }	|	                    t                     |                    d-d.          }
|
                    t                      dS )/zAttach the egress subcommand tree to a parent parser.

    Called from ``hermes_cli.main`` as part of building the top-level
    ``hermes egress`` parser.
    egress_command)destinstallzDownload iron-proxy binary (v))helpz--force
store_truez1Re-download even if a managed copy already exists)actionr   )func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restartzIf 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)add_subparsers
add_parserip_IRON_PROXY_VERSIONadd_argumentset_defaultscmd_installint_DEFAULT_TUNNEL_PORT	cmd_setup	cmd_startcmd_stopcmd_restart
cmd_reload
cmd_statuscmd_disable
cmd_config)r   subr   r   r   r   r   reload_pr    r!   cfgs              :/home/thesage/.hermes/hermes-agent/hermes_cli/proxy_cli.pyregister_clir8   $   sM    
&
&,<
&
=
=CnnFR-CFFF   G ,@     k***NNL   E 
c4L"2ILLL     
<N     
P    
 
,?     
)L$     
Y}L    
 
I&&&NN7)GNHHE	I&&&>>&'D>EED8$$$nnK   G k***~~G   H
 z***^^H+J^KKF
A    
 Z(((nnY-MnNNGk***
..(M.
N
NC*%%%%%    argsargparse.Namespacer*   c                `   t                      }	 t          j        t          | j                            }nE# t
          $ r8}|                    d|            |                    d           Y d }~dS d }~ww xY wt          j        |          pd}|                    d| d|            dS )	N)forceu   [red]✗ install failed:[/red] z?  Manual install: https://github.com/ironsh/iron-proxy/releases   (version unknown)u   [green]✓[/green] installed   r   )r   r%   install_iron_proxyboolr=   	Exceptionprintiron_proxy_version)r:   consolebinaryexcversions        r7   r)   r)      s    iiG&T$*-=-=>>>   ===>>>M	
 	
 	
 qqqqq #F++B/BGMME&EEGEEFFF1s   '8 
A:-A55A:c                   t                      }|                    t          j        dd                     |                                 |                    d           	 t	          j        d          }|(|                    d           t	          j                    }t	          j        |          pd}|                    d	| d
|            n1# t          $ r$}|                    d| d           Y d }~dS d }~ww xY w|                                 |                    d           	 t	          j	                    \  }}n1# t          $ r$}|                    d| d           Y d }~dS d }~ww xY w|                    d	|            |                                 |                    d           g }| j
        rt                      }|                    d          pi                     d          pi }	|	                    d          s,|                    d           |                    d           dS 	 ddlm}
 t          j                            |	                    dd          d                                          }|s/|                    d|	                    dd           d           dS |
                    ||	                    dd          dd          \  }}t'          |                                          }|s|                    d           dS |                    d t+          |           d!           no# t          $ r9}|                    d"| d           |                    d#           Y d }~dS d }~ww xY wt-                      }|r|                    d$| d%           t	          j        |pd &          }t	          j                    }t3          t5          | d'd                    }|ry|rvdd l}dd(lm} |j                                        ry|                    d)           	 t?          d*                                                                           }n# tB          $ r d}Y nw xY w|d+k    r|                    d,           dS 	 dd l"}t	          j#                    }|d-z  }|$                                rx|%                                &                    d.          }|d/| z  }|'                    tQ          |          tQ          |                     |                    d0| d1           nI# tR          $ r#}|                    d2| d3           Y d }~n!d }~ww xY w|r|s|                    d4           t	          j*        |||5          }|s`|                    d6           |                    d7           tW          t          j,                  D ]}|                    d8|            dS t	          j-        |pd &          }|r[|                                 |                    d9           |D ]}|                    d8|            |                    d:           t]          d;d<=          }|/                    d>d?           |/                    d@dA?           |/                    dBdC?           |D ]H}|0                    |j1        dD2                    |j3                  ti          |j5                             I|                    |           |                                 |                    dE           t                      }|6                    dFi           } | j7        B| j7        dk     s| j7        dGk    r|                    dH           dS tq          | j7                  }!n-tq          |                     dIt          j9                            }!|!| dI<   t'          |                     dJ          pg           }"t'          t          j:                  dK |"D             z   }#t	          j#                    dLz  }$d;}%	 t	          j;        |$           n2# tx          $ r%}d}%|                    dM| d3           Y d }~nd }~ww xY w|                     dN          }&t	          j=        ||||!|$|#|&O          }'t	          j>        |'          }(t	          j?        |          })t	          j@                     |                    dP|(            |                    dQ|)            |%r|                    dR|$ dS           d;| d<   | 6                    dTd;           | 6                    dUd;           |                     dV          }*| j
        rd| dV<   nSt5          | dWd          r!dX| dV<   |*dk    r|                    dY           n!|*dk    r|                    dZ           ndX| dV<   t          |           t	          jB                    }+|+jC        d u},|,rt	          jD                     dd l}t5          | d[d           }-|-d;u rd;}.ns|-du rd}.nl|,rh|j                                        rL	 t?          d\                                                                           }n# tB          $ r d}Y nw xY w|d]v }.nd;}.nd}.|.r	 t	          jE        t3          |                     dTd;                              }/|/jF        rd^nd_}0|,rd`nda}1|                    d	|1 db|/jC         dc|/j7         dD|0 dd	           n\# t          $ r8}|                    de| d3           |                    df           Y d }~nd }~ww xY w|,r|                    dg           |                                 |                    dh           |                    di           dS )jNz[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_stylez2[bold]Step 1[/bold]  Install the iron-proxy binaryF)install_if_missingu*     No iron-proxy on PATH — downloading…r?   u     [green]✓[/green] r@   u     [red]✗ install failed: z[/red]r>   z'[bold]Step 2[/bold]  Generate a CA certu!     [red]✗ CA generation failed: z:[bold]Step 3[/bold]  Mint proxy tokens for known providerssecrets	bitwardenenableduS     [red]✗ --from-bitwarden requested but secrets.bitwarden.enabled is false.[/red]zG  Run `hermes secrets bitwarden setup` first, or omit --from-bitwarden.r   )rO   access_token_envBWS_ACCESS_TOKEN u*     [red]✗ --from-bitwarden requested but % is not set in the environment.[/red]
project_id)access_tokenrU   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: 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).z  [dim]Loaded z> provider key name(s) from ~/.hermes/.env for discovery.[/dim])available_env_namesrotate_tokens)datetimeu   [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: z[/dim]z6  [yellow]Could not back up mappings before rotation: z	[/yellow]z_[dim]Note: --rotate-tokens is a no-op on first-time setup (no existing tokens to rotate).[/dim])existing
discoveredr\   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]Tboldshow_headerheader_stylezProvider envstylezUpstream hostsdimProxy tokengreen, z6[bold]Step 4[/bold]  Write config and persist mappingsproxyi  ua     [red]✗ --tunnel-port must be between 1 and 65534 (the plain-HTTP listener uses port+1).[/red]tunnel_portextra_allowed_hostsc                .    g | ]}|t           j        v|S  )r%   _DEFAULT_ALLOWED_HOSTS).0hs     r7   
<listcomp>zcmd_setup.<locals>.<listcomp>  s,     1 1 1!2+D"D"D"D"D"Dr9   z	audit.logu     [yellow]⚠ upstream_deny_cidrs)mappingsca_certca_keyrj   	audit_logallowed_hostsrr   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]auto_installenforce_on_dockercredential_source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]r   z;  Restart the running proxy now with the new config? [Y/n] )rS   yyes	listeningznot yet listening	restartedstartedz% iron-proxy with the new config (pid=z, port=r   u>     [yellow]⚠ could not start iron-proxy with the new config: 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]u_   [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])Gr   rD   r   fitr%   find_iron_proxyrA   rE   rC   ensure_ca_certfrom_bitwardenr	   getagent.secret_sourcesrO   osenvironstripfetch_bitwarden_secretslistkeyslen_load_env_file_into_environdiscover_provider_mappingsload_mappingsrB   getattrsysr[   stdinisattyinputlowerEOFErrorshutil_proxy_state_direxistsnowstrftimecopy2strOSErrormerge_mappingssorted_BEARER_PROVIDERSdiscover_uncovered_providersr   
add_columnadd_rowreal_env_namejoinupstream_hosts_redact_tokenproxy_token
setdefaultrj   r*   r+   rn   ensure_audit_logRuntimeErrorbuild_proxy_configwrite_proxy_configwrite_mappingsensure_management_tokenr
   
get_statuspid
stop_proxystart_proxyr   )2r:   rF   rG   rI   rH   ca_crtru   rY   r6   bw_cfgbwrV   rN   _loadedr^   r]   r\   _sys_dtans_shutil	state_dirmappings_srctsbackuprs   env_name	uncoverednametablem	proxy_cfgrj   extra_hostsallowedaudit_log_pathaudit_log_ok
deny_cidrsiron_cfgcfg_pathmappings_pathexisting_sourcelive_statuswas_runningrestart_pref
do_restart
new_statusr   verbs2                                                     r7   r,   r,      s   iiGMM%)	Q       MMOOOMMFGGG	#u===>MMFGGG*,,F'//F3FAfAAAABBBB   ?C???@@@qqqqq
 MMOOOMM;<<<*,,   E#EEEFFFqqqqq MM2&22333 MMOOOMMNOOO%' @mm'')$$*//<<Bzz)$$ 		MM<   MM$   1&	<<<<<<:>>

-/ABBB egg    ;zz"46HII; ; ;  
 q33)!::lB77"#	 4  JGQ #'w||~~"6"6& 8  
 qMMPC 344PPP     		 		 		MMPSPPP   MM7  
 11111		" -.. 	MM7 7 7 7  
 ./74  J !!H'$7788F  &
( &
,,,,,,: 	MM=  
899??AAGGII   h;<<<q
	$$$$+--I$6L""$$ @WWYY''88"%Bb%B%BBc,//V===>>>>??? 	 	 	MM"" " "       	
 
 
 
4	
 	
 	

    H  	S	
 	
 	
 	:	
 	
 	
 r344 	/ 	/HMM-8--....q
 //74  I  
(	
 	
 	
  	+ 	+DMM/4//*****	
 	
 	
 d888E	^6222	%U333	]'222 
 
OIIa&''!-((	
 	
 	
 	

 MM% MMOOOMMJKKK
--Cw++I
 #a4#3e#;#;MM?   1$*++)--r7NOOPP*Imy}}%:;;ArBBK2,-- 1 11 1 1 G (**[8N L7
N++++ 7 7 75s555666666667 455J$ &  H $X..H%h//M    MM>H>>???MMCMCCDDD 
A~ A A A	
 	
 	
  Ii...,d333  mm$788O /)4	%&&	~u	-	- /).	%&k))MMT   
K	'	' 	L	
 	
 	
 	

 */	%&-//K/-K 
 4D11Lt

			

	 : 		Q %''%%''      00JJJJ
 
	#'	nd(K(K#L#L  J (2';TATI"-<;;9DMMV V V"V V/9/EV VIRV V V     	 	 	MM** * *   MM2       	  
 
R	
 	
 	
 MMOOOMM	<   MM	8   1s   "A0C 
DC<<D.E 
E3E..E3=A;M :A(M $&M 
N.N		N3Q5 5RR%B(U 
U;U66U;%a: :
b)b$$b)3j; ;k
	k
6m 
n.nnc                   t                      }t                      }|                    d          pi }|                    d          s|                    d           dS |                    dd          }|                    d          pi                     d          }|dk    o%|d uo!t	          |                    d                    }|dk    rg|set	          |                    d	d
                    r|                    d           n,|                    d           |                    d           dS |r7|5t          |          }t	          |                    d	d
                    |d	<   |r|pi                     dd          }t          j                            |d                                          s0|                    d| d           |                    d           dS |pi                     d          s,|                    d           |                    d           dS 	 t          j
        t	          |                    dd                    ||          }n0# t          $ r#}	|                    d|	            Y d }	~	dS d }	~	ww xY w|j        r4|j        rdnd}
|                    d|j         d|j         d|
            n|                    d            dS d!S )"Nri   rP   uL   [yellow]proxy.enabled is false — run `hermes egress setup` first.[/yellow]r>   rz   r|   rN   rO   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]uv   [red]✗ Refusing to start: proxy.credential_source is 'bitwarden' but secrets.bitwarden is disabled or missing.[/red]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.rQ   rR   rS   u<   [red]✗ Refusing to start: credential_source=bitwarden but rT   zv  Either export the access token, or run `hermes egress setup --no-bitwarden` to switch back to env-based credentials.rU   uh   [red]✗ Refusing to start: credential_source=bitwarden but secrets.bitwarden.project_id is empty.[/red]zy  Run `hermes secrets bitwarden setup` to configure the project, or switch back via `hermes egress setup --no-bitwarden`.rx   T)rM   refresh_secrets_from_bitwardenbitwarden_configu+   [red]✗ failed to start iron-proxy:[/red] z[green]listening[/green]z"[yellow]not yet listening[/yellow]u+   [green]✓[/green] iron-proxy running  pid=z  port=r@   u1   [red]✗ iron-proxy did not come up cleanly[/red]r   )r   r	   r   rD   rB   dictr   r   r   r%   r   rC   r   r   rj   )r:   rF   r6   r   rz   r   
refresh_bwbw_access_envr    rH   r   s              r7   r-   r-   "  s   iiG
--C  &BI==## 	
 	
 	
 q "&95AAggi  &B++K88F[( 	($	(I&&''  K''
'	2E::;; 	MM>    MM!  
 MM5   1
  
f(f'+MM.66(
 (
#$  2**+=?QRRz~~mR006688 
	MMH H H H   MM)  
 1"!!,// 
	MM?   MM#  
 1#IMM.$$G$GHH+5#
 
 

    ICIIJJJqqqqq z  6&&5 	
 	6&* 6 6&6 6*36 6	
 	
 	
 	

 	IJJJq1s   28I+ +
J5JJc                    t                      }t          j                    r|                    d           n|                    d           dS )Nu%   [green]✓[/green] iron-proxy stoppedz%[dim]iron-proxy was not running[/dim]r   )r   r%   r   rD   )r:   rF   s     r7   r.   r.     sG    iiG	} ?=>>>>=>>>1r9   c                    t                      }t          j                    }|r|                    d           t	          |           S )ai  Stop the running daemon (if any) and start it with the current config.

    The one-command way to apply config changes (new allowlist hosts, rotated
    tokens, a Bitwarden key rotation) without making the operator remember the
    stop/start dance.  Delegates to ``cmd_start`` so all the credential-source
    guards run exactly as they do for ``start``.
    z)[dim]stopped the running iron-proxy[/dim])r   r%   r   rD   r-   )r:   rF   r   s      r7   r/   r/     s@     iiG-//K CABBBT??r9   c                    t                      }	 t          j                     n0# t          $ r#}|                    d|            Y d}~dS d}~ww xY w|                    d           |                    d           dS )u  Hot-reload the running daemon's ruleset via the management API.

    Applies allowlist / token / mapping changes already written to
    proxy.yaml WITHOUT restarting the daemon — no dropped connections, no
    restart window.  When the change involves new upstream SECRETS (a
    Bitwarden rotation, a newly added provider key), use
    ``hermes egress restart`` instead: the daemon reads real credentials
    from its own environment at spawn time, and a reload does not
    re-populate that env.
    u   [red]✗ reload failed:[/red] Nr>   u[   [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   )r   r%   reload_proxyrC   rD   )r:   rF   rH   s      r7   r0   r0     s     iiG
   <s<<===qqqqq MM	.   MM	@  
 1s   $ 
AAAF)show_tokensr   rB   r   c                   t                      }|                    d          pi }t          j                    }d'd}ddd	 |t	          |                    d
                               d|j        pd d|j        pd d|j        pd d|j        pd d|j	         |j
        r
d|j
         ndd ||j                   d|                    dd           d |t	          |                    dd                               dg}t          j                    }|ru|                    ddg           |D ][}| r|j        nt          |j                  }|                    d|j         d| d d!                    |j                   d"           \t          j                    }	|	r4|                    dd#g           |	D ]}
|                    d|
            t	          |                    d
                    r|j        s|                    dd$g           nGt	          |                    d
                    r%|j
        r|j        s|                    dd%g           d&                    |          S )(zDPlain-text egress status for slash commands, Dashboard, and Desktop.ri   valuerB   r   r   c                    | rdndS )Nr~   norm   r   s    r7   ynzformat_status_text.<locals>.yn  s    'uu4'r9   zEgress proxy statusrS   z	Enabled: rP   zBinary: z	(missing)zBinary version: z	(unknown)zConfig: z(not generated)z	CA cert: zTunnel port: zProcess: pid zProcess: (stopped)zListening: zCredential src: rz   r|   zDocker enforce: ry   Tz*Scope: Docker backend only in this releasezToken mappings:  - z: z (rh   r   zHUncovered providers (real credentials still visible inside the sandbox):zDNext: run `hermes egress setup` to mint tokens and write proxy.yaml.zBNext: run `hermes egress start` before launching Docker sandboxes.
r   rB   r   r   )r	   r   r%   r   rB   binary_pathbinary_versionconfig_pathca_cert_pathrj   r   r   r   extendr   r   appendr   r   r   r   
configured)r   r6   r   r    r   linesrs   r   tokr   r   s              r7   format_status_textr     s   
--C  &BI]__F( ( ( ( 	
8BBtIMM)4455668866%466A60?KAA<6%:):<<>F'<+<>>,*,,(.
L$
$$$8L,bb)**,,F9==)<eDDFFO22d9==1Dd#K#KLLMMOO4E  !!H Zb+,--- 	Z 	ZA#.P!--M!-4P4PCLLXXX3XX$))ADT:U:UXXXYYYY/11I (V
 	 	 	  	( 	(DLL''''IMM)$$%% af.? ab`abbbb	immI&&	'	' a a@P ab^_```99Ur9   c                   t                      }t                      }|                    d          pi }t          j                    }t          dd d          }|                    dd           |                    d           |                    dt          t          |                    d	                                         |                    d
t          |j        pd                     |                    d|j        pd           |                    dt          |j        pd                     |                    dt          |j        pd                     |                    dt          |j                             |                    d|j        r
d|j         nd           |                    dt          |j                             |                    dt          |                    dd                               |                    dt          t          |                    dd                                         |                    |           t          j                    }|r|                                 |                    d           t          dd          }|                    dd           |                    d d!           |                    d"d#           |D ]X}| j        r|j        nt-          |j                  }	|                    |j        d$                    |j                  |	           Y|                    |           | j        r|                    d%           t          j                    }
|
rF|                                 |                    d&           |
D ]}|                    d'|            d(S ))Nri   F)r      )ra   boxpaddingrS   r_   rc   EnabledrP   Binaryz[dim](missing)[/dim]zBinary versionz[dim](unknown)[/dim]Configz[dim](not generated)[/dim]zCA certzTunnel portProcesszpid z[dim](stopped)[/dim]	ListeningzCredential srcrz   r|   zDocker enforcery   Tz[bold]Token mappings[/bold]r`   zReal envrK   Upstreamre   rf   rg   rh   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   r%   r   r   r   r   _ynrB   r   r   r   r   r   rj   r   r   rD   r   r   r   r   r   r   r   r   )r:   rF   r6   r   r    r   rs   m_tabler   r   r   r   s               r7   r1   r1      s   iiG
--C  &BI]__Fev>>>E	Rv&&&	R	MM)CY]]9-E-E(F(F$G$GHHH	MM(C(:(T>T$U$UVVV	MM"F$9$S=STTT	MM(C(:(Z>Z$[$[\\\	MM)C(;([?[$\$\]]]	MM-C(:$;$;<<<	MM)6:$a$76:$7$7$7Kabbb	MM+C(8$9$9:::	MM"C	6I5(Q(Q$R$RSSS	MM"CY]];NPT-U-U(V(V$W$WXXXMM%!!H 3444Dv>>>:V444:U333=888 	O 	OA#'#3U!--q}9U9UCOOAOTYYq7G-H-H#NNNNg 	MM)   /11I )C	
 	
 	
  	) 	)DMM---((((1r9   c                n   t                      }t                      }|                    di           }|                    d          s|                    d           dS d|d<   t          |           |                    d           t          j                    j        |                    d           dS )Nri   rP   z+[dim]proxy.enabled was already false.[/dim]r   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   rD   r
   r%   r   r   )r:   rF   r6   r   s       r7   r2   r2   7  s    iiG
--Cw++I==## CDDDq IiMMABBB 
}&G	
 	
 	
 1r9   c                    t                      }t          j                    }|j        |                    d           dS |                    t          |j                             dS )NuD   [yellow](no config generated — run `hermes egress setup`)[/yellow]r>   r   )r   r%   r   r   rD   r   )r:   rF   r    s      r7   r3   r3   N  sa    iiG]__F!R	
 	
 	
 qMM#f())***1r9   c                    	 ddl m}  n# t          $ r Y dS w xY w	  |             }n# t          $ r Y dS w xY wd}t	          t
          j                  t	          t
          j                  z  }|D ]t}|t          j	        v r%t          j	        |         
                                r5|                    |          pd
                                }|r|t          j	        |<   |dz  }u|S )u  Backfill provider keys from ``~/.hermes/.env`` into ``os.environ``.

    ``hermes egress setup`` discovers providers by reading ``os.environ``, but
    many operators keep their keys ONLY in ``~/.hermes/.env`` (which the agent
    loads at runtime but which is NOT exported into an interactive shell).
    Without this, ``setup`` reports "no provider keys found" even though the
    keys plainly exist — a confusing first-run papercut.

    Only fills names that aren't already set in the process env (an exported
    value always wins), and only for known bearer-provider names so we don't
    slurp unrelated secrets into the process. Returns the count of names added.
    r   )load_envrS   r>   )hermes_cli.configr  ImportErrorrC   setr%   r   _NON_BEARER_PROVIDERSr   r   r   r   )r  file_envaddedknownr   vals         r7   r   r   _  s   .......   qq8::   qqE$%%B,D(E(EEE  2:"*T"2"8"8":":||D!!'R..00 	"BJtQJELs   	 

& 
44r   c                    | rdndS )Nz[green]yes[/green]z[dim]no[/dim]rm   r   s    r7   r  r    s    #(=o=r9   tokenc                Z    t          |           dk     r| S | d d          d| dd           S )N      u   …)r   )r  s    r7   r   r     s:    
5zzBCRCj))U233Z)))r9   )r   r   r   r   )r:   r;   r   r*   )r   rB   r   r   )r   r*   r   )r  r   r   r   )!__doc__
__future__r   argparser   typingr   rich.consoler   
rich.panelr   
rich.tabler   agent.proxy_sourcesr   r%   r  r	   r
   r8   r)   r,   r-   r.   r/   r0   r   r1   r2   r3   r   r  r   rm   r9   r7   <module>r     s     # " " " " "  				                               0 0 0 0 0 0 6 6 6 6 6 6 6 6]& ]& ]& ]&J   G G G GTu u u up         : /4 . . . . . .b4 4 4 4n   .	 	 	 	"   B> > > >* * * * * *r9   