
    FjR                       d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	m
Z
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mZmZ ddlmZ d.dZd/dZd/dZd/dZd/dZ d/dZ!d0dZ"d1dZ#d d!d2d'Z$d(d)gZ%d3d-Z&dS )4u  CLI handlers for ``hermes secrets bitwarden ...``.

Subcommands:
    setup    — interactive wizard: install bws, prompt for token + project, test fetch
    status   — show current config + binary version + last fetch outcome
    sync     — run a fetch right now and show what would be applied (dry-run friendly)
    disable  — flip ``secrets.bitwarden.enabled`` to False
    install  — just download the bws binary (no token / project required)
    )annotationsN)Path)ListOptional)Console)Panel)Table)	bitwarden)get_env_pathload_configsave_configsave_env_value)masked_secret_promptparent_parserargparse.ArgumentParserreturnNonec                ,   |                      d          }|                    dd          }|                    dd           |                    dd	           |                    d
d           |                    t                     |                    dd          }|                    t
                     |                    dd          }|                    ddd           |                    t                     |                    dd          }|                    t                     |                    ddt          j	         d          }|                    ddd           |                    t                     dS )zAttach the ``bitwarden`` subcommand tree to a parent parser.

    Called from ``hermes_cli.main`` as part of building the top-level
    ``hermes secrets`` parser.
    secrets_bw_command)destsetupzAInteractive wizard: install bws, store access token, pick project)helpz--project-idz.Pre-select a project UUID instead of promptingz--access-tokenzCProvide the access token non-interactively (will be stored in .env)z--server-urlzBitwarden region / self-hosted endpoint. Examples: https://vault.bitwarden.com (US, default), https://vault.bitwarden.eu (EU), or your self-hosted URL. Skips the interactive region prompt.)funcstatusz!Show config + binary + last fetchsyncz)Fetch secrets now and report what changedz--apply
store_truezKActually export the secrets into the current shell's env (default: dry-run))actionr   disablez"Turn off the Bitwarden integrationinstallz,Download and verify the pinned bws binary (v)z--forcez1Re-download even if a managed copy already existsN)add_subparsers
add_parseradd_argumentset_defaults	cmd_setup
cmd_statuscmd_synccmd_disablebw_BWS_VERSIONcmd_install)r   subr   r   r   r   r   s          5/usr/local/lib/hermes-agent/hermes_cli/secrets_cli.pyregister_clir.   '   s    
&
&,@
&
A
ACNNP   E 
=     
R     
3     
I&&&^^H+N^OOF
Z(((>>&'R>SSDZ    
 	8$$$nnY-QnRRGk***nnNBONNN   G @    
 k*****    argsargparse.Namespaceintc           	     h   t                      }|                    t          j        dd                     |                                 |                    d           	 t	          j        d          }|(|                    d           t	          j                    }t          |          }|                    d| d	| d
           nF# t          $ r9}|                    d| d           |                    d           Y d }~dS d }~ww xY w|                                 |                    d           t                      }|
                    di           
                    di           }|                    dd          }| j        pd                                }|s%t          d| d                                          }|s|                    d           dS |                    d          s|                    d           t!          ||           |t"          j        |<   |                    dt'                       d|            |                                 |                    d           t)          | ||          }	|	dS |	r|                    d|	            n|                    d           | j        r4| j                                        r| j                                        }
n|                                 |                    d           d}
t-          ||||	           }|dS |s,|                    d!           |                    d"           dS t/          d#d$%          }|                    d&dd'(           |                    d)           |                    d*d+,           t3          |d          D ]Q\  }}|                    t7          |          |                    d-d.          |                    d/d.                     R|                    |           	 |                    d0t;          |           d1                                          }|s<	 t=          |          }n%# t>          $ r |                    d2           Y nw xY wd|cxk    rt;          |          k    rn n||dz
           d/         }
n'|                    d3t;          |           d4           |                                 | j        r| j                                        sd5nd'}|                    d6| d7           	 t	          j         ||
|d|	8          \  }}n1# t          $ r$}|                    d9| d           Y d }~dS d }~ww xY w|s|                    d:           nt/          d#d$%          }|                    d)d,           |                    d;           tC          |          D ]E}||k    rd<}n$t"          j                            |          rd=}nd>}|                    ||           F|                    |           |D ]}|                    d?|            d#|d@<   |
|dA<   |	|dB<   |
                    d|           |
                    dCdD           |
                    dEd#           |
                    dFd#           tE          |           |                                 |                    dG           |                    dH           dIS )JNu  [bold]Bitwarden Secrets Manager setup[/bold]

Need an access token? In the Bitwarden web app:
  Secrets Manager → Machine accounts → [your account] →
  Access tokens → Create access token

Copy the token (starts with [cyan]0.[/cyan]…) — it cannot be retrieved later.cyan)border_stylez([bold]Step 1[/bold]  Install the bws CLIFinstall_if_missingu#     No bws on PATH — downloading…u     [green]✓[/green]   (r    u"     [red]✗ Could not install bws: [/red]z>  Manual install: https://github.com/bitwarden/sdk-sm/releases   z.[bold]Step 2[/bold]  Provide your access tokensecretsr
   access_token_envBWS_ACCESS_TOKEN z  Paste access token (z): z#  [red]Empty token, aborting.[/red]z0.u     [yellow]Warning: token doesn't start with '0.' — usually that means you pasted something other than a BSM access token.  Continuing anyway.[/yellow]u     [green]✓[/green] stored in z as z,[bold]Step 3[/bold]  Pick a Bitwarden regionu     [green]✓[/green] using uN     [green]✓[/green] using bws default (US Cloud, https://vault.bitwarden.com)z#[bold]Step 4[/bold]  Pick a project
server_urlz?  [yellow]No projects visible to this machine account.[/yellow]ur     In the Bitwarden web app, open the machine account → Projects tab and grant it access to at least one project.Tboldshow_headerheader_style#   stylewidthNameIDdimrH   name?idz  Select project [1-z]:   [red]Enter a number.[/red]     [red]Out of range — pick 1-.[/red]   z[bold]Step z[/bold]  Test fetch)access_token
project_idbinary	use_cacher@   u     [red]✗ Fetch failed: zB  [yellow]Fetch succeeded but the project has no secrets.[/yellow]Statusu5   [dim]bootstrap token — never overrides itself[/dim]z9[yellow]already set in env (will be overwritten)[/yellow]z[green]new[/green]z  [yellow]warning:[/yellow] enabledrV   r@   cache_ttl_seconds,  override_existingauto_installuv   [green]✓ Bitwarden Secrets Manager is enabled.[/green]  Secrets will be pulled at the start of every Hermes process.z  Status:  [cyan]hermes secrets bitwarden status[/cyan]
  Refresh: [cyan]hermes secrets bitwarden sync[/cyan]
  Disable: [cyan]hermes secrets bitwarden disable[/cyan]r   )#r   printr   fitr)   find_bwsinstall_bws_bws_version	Exceptionr   
setdefaultgetrU   stripr   
startswithr   osenvironr   _resolve_server_urlrV   _list_projectsr	   
add_column	enumerateadd_rowstrinputlenr2   
ValueErrorfetch_bitwarden_secretssortedr   )r0   consolerW   versionexccfgsecrets_cfg	token_envtokenr@   rV   projectstableipchoiceidxstep_numr;   warningskeyr   ws                          r-   r%   r%   e   s   iiGMM	`
  	
 	
 	
	 	 	 MMOOOMM<===666>MM?@@@^%%Fv&&CfCCCCCDDDD   F3FFFGGG;	
 	
 	
 qqqqq MMOOOMMBCCC
--C>>)R00 jb11  24FGGI$"++--E V$%Li%L%L%LMMSSUU ;<<<qD!! 
_	
 	
 	

 9e$$$!BJyMMSLNNSS	SSTTT MMOOOMM@AAA$T;@@Jq 
@J@@AAAA6	
 	
 	
  %T4?0022 %T_**,,

;<<<
!&%ZPPP1 	MM[\\\MM?   1$V<<<F!444   U+++h** 	H 	HDAqMM#a&&!%%"4"4aeeD#6F6FGGGGe	T]]#L#h--#L#L#LMMSSUUF &kk   <=== C((((3x==(((((%cAg.t4
MMRCMMRRRSSS	T MMOOOLT_-B-B-D-DLqq1HMM====>>>
6!!
 
 
    =#===>>>qqqqq  Z[[[[$V<<<v..."""'?? 	' 	'CiP$$ .T-MM#v&&&&e : :8Q889999 "K	 *K *K-y999.444.555>4000MMOOOMM	G   MM	C  
 1sC   "A*C 
D.DD7R R)(R)U1 1
V;VVc                   t                      }t                      }|                    d          pi                     d          pi }t          |                    d                    }|                    dd          }|                    dd          }t	          |                    dd          pd                                          }t          t          j                            |                    }t          d	d d
          }	|		                    dd           |		                    d           |	
                    dt          |                     |	
                    d|           |	
                    dt          |                     |	
                    d|pd           |	
                    d|pd           |	
                    dt          t          |                    dd	                                         |	
                    dt	          |                    dd                               |	
                    dt          t          |                    dd                                         t          j        d	          }
|
r*|	
                    d|
 dt          |
           d            n|	
                    dd!           |                    t!          |	d"d#$                     |s|                    d%           d&S |s|                    d'| d(           |s|                    d)           d&S )*Nr;   r
   rZ   r<   r=   rV   r>   r@   Fr      )rC   boxpaddingrA   rM   EnabledzToken env varzToken in envz
Project IDz[dim](unset)[/dim]z
Server URLz:[dim]default (US Cloud, https://vault.bitwarden.com)[/dim]zOverride existingr]   zCache TTL (s)r[   r\   zAuto-installr^   Tr6   z
bws binaryz (r    z[yellow]not installed[/yellow]zBitwarden Secrets Managerr4   )titler5   z=
  Run [cyan]hermes secrets bitwarden setup[/cyan] to enable.r   z
  [yellow]Enabled but uG    is not set — Hermes will skip BSM and warn on next startup.[/yellow]uC   
  [yellow]Enabled but no project_id — nothing to fetch.[/yellow])r   r   rf   boolrp   rg   ri   rj   r	   rm   ro   _ynr)   ra   rc   r_   r   )r0   rv   ry   bw_cfgrZ   r{   rV   r@   	token_setr~   rW   s              r-   r&   r&     s   iiG
--Cggi  &B++K88>BF6::i(())G

-/ABBIL"--JVZZb117R88>>@@JRZ^^I..//Iev>>>E	Rv&&&	R	MM)S\\222	MM/Y///	MM.S^^444	MM,Z%G3GHHH	MMRR   
MM%s4

;NPU0V0V+W+W'X'XYYY	MM/S4G)M)M%N%NOOO	MM.Sfjj.N.N)O)O%P%PQQQ[E222F Gl%I%I,v2F2F%I%I%IJJJJl%EFFFMM%%@vVVVWWW VWWWq 
1y 1 1 1	
 	
 	
  
R	
 	
 	
 1r/   c                   t                      }t                      }|                    d          pi                     d          pi }|                    d          s|                    d           dS |                    dd          }t          j                            |d                                          }|s|                    d	| d
           dS |                    dd          }|s|                    d           dS t          |                    dd          pd                                          }	 t          j	        ||d|          \  }}	n1# t          $ r$}
|                    d|
 d           Y d }
~
dS d }
~
ww xY w|s|                    d           dS t          |                    dd                    p| j        }t          dd          }|                    dd           |                    d           d}t          |          D ]}||k    r|                    |d           t          t          j                            |                    }|r|s|                    |d           f| j        r8||         t          j        |<   |dz  }|                    |d|rdndz              |                    |d |rd!ndz              |                    |           |	D ]}|                    d"|            | j        s|                    d#           n|                    d$| d%           dS )&Nr;   r
   rZ   z`[yellow]Bitwarden integration is disabled.  Run `hermes secrets bitwarden setup` first.[/yellow]r:   r<   r=   r>   z[red]z is not set.[/red]rV   z$[red]No project_id configured.[/red]r@   F)rU   rV   rX   r@   z[red]Fetch failed: r9   z'[yellow]No secrets in project.[/yellow]r   r]   TrA   rB   rJ   r4   rM   Actionz![dim]skip (bootstrap token)[/dim]z[dim]skip (already set)[/dim]z[green]exported[/green]z (overrode)z[green]would export[/green]z (overrides)z[yellow]warning:[/yellow] u   
  This was a dry-run — secrets are picked up automatically on the next [cyan]hermes[/cyan] invocation.  Re-run with [cyan]--apply[/cyan] to export into the current shell instead.z
  [green]Exported z( secret(s) into current process.[/green])r   r   rf   r_   ri   rj   rg   rp   r)   rt   rd   r   applyr	   rm   ru   ro   )r0   rv   ry   r   r{   r|   rV   r@   r;   r   rx   overrider~   appliedr   alreadyr   s                    r-   r'   r'   <  s   iiG
--Cggi  &B++K88>BF::i   ?	
 	
 	
 q

-/ABBIJNN9b))//11E ;i;;;<<<qL"--J <===qVZZb117R88>>@@J	6!!	
 
 
    7C777888qqqqq  ?@@@qFJJ2E::;;ItzHd888E	V6***	XGg d d)MM#BCCCrz~~c**++ 	8 	MM#>???: 	d%clBJsOqLGMM#8W<\MMZ\]^^^^MM#<RY@a_abccccMM% 8 861667777: `8	
 	
 	
 	
 	^W^^^___1s   E 
F'FFc                    t                      }t                      }|                    di                               di           }d|d<   t          |           |                    d           dS )Nr;   r
   FrZ   u   [green]Disabled.[/green]  Bitwarden secrets will NOT be pulled on the next Hermes invocation.
  Your access token is left in .env — remove it manually if you also want to revoke the credential.r   )r   r   re   r   r_   )r0   rv   ry   r   s       r-   r(   r(     ss    iiG
--CnnY++K,, F9MM	$   1r/   c                &   t                      }	 t          j        t          | j                            }|                    d| dt          |           d           dS # t          $ r$}|                    d| d           Y d }~dS d }~ww xY w)	N)forceu   [green]✓[/green] r8   r    r   z[red]Install failed: r9   r:   )r   r)   rb   r   r   r_   rc   rd   )r0   rv   pathrx   s       r-   r+   r+     s    iiG~D$4$4555JDJJ\$5G5GJJJKKKq   9c999:::qqqqqs   AA" "
B,BBbr   rp   c                    | rdndS )Nz[green]yes[/green]z[dim]no[/dim] )r   s    r-   r   r     s    #$9/9r/   rW   r   c                   	 t          j        t          |           dgddd          }|j        dk    r8|j        p|j                                                                        d         S n# t          t           j	        f$ r Y nw xY wdS )Nz	--versionTrT   )capture_outputtexttimeoutr   zversion unknown)

subprocessrunrp   
returncodestdoutstderrrg   
splitlinesOSErrorTimeoutExpired)rW   ress     r-   rc   rc     s    
n[[+&	
 
 
 >QJ,#*3355@@BB1EE Z./   s   A)A- -BBr>   r?   r|   rv   r   r@   Optional[List[dict]]c               |   t           j                                        }||d<   |                    dd           |r||d<   	 t	          j        t          |           ddddg|d	d	d
          }n=# t          t          j        f$ r$}|	                    d| d           Y d}~dS d}~ww xY w|j
        dk    r|j        p|j                                        dd         }|	                    d| d           |                                }d|v sd|v r|	                    d           nd|v sd|v r|	                    d           dS 	 t          j        |j        pd          }	n6# t          j        $ r$}|	                    d| d           Y d}~dS d}~ww xY wt%          |	t&                    sg S d |	D             S )zICall ``bws project list`` and return the parsed list, or None on failure.r=   NO_COLOR1BWS_SERVER_URLprojectlistz--outputjsonT   )envr   r   r   z  [red]Couldn't list projects: r9   Nr   r\   z   [red]bws project list failed: invalid_clientz400 bad requesta$    [yellow]'invalid_client' from the US identity endpoint usually means the token is for a different Bitwarden region.  Re-run [cyan]hermes secrets bitwarden setup[/cyan] and pick EU or self-hosted at the region prompt, or set [cyan]secrets.bitwarden.server_url[/cyan] in config.yaml.[/yellow]authorizationinvalidzu  [yellow]This usually means the access token is wrong or revoked. Double-check it in the Bitwarden web app.[/yellow]z[]z  [red]bws returned non-JSON: c                f    g | ].}t          |t                    |                    d           ,|/S )rP   )
isinstancedictrf   ).0r   s     r-   
<listcomp>z"_list_projects.<locals>.<listcomp>  s6    CCC!z!T22CquuT{{CACCCr/   )ri   rj   copyre   r   r   rp   r   r   r_   r   r   r   rg   lowerr   loadsJSONDecodeErrorr   r   )
rW   r|   rv   r@   r   r   rx   errlowereddatas
             r-   rl   rl     s<    *//

C#CNN:s### + *
n[[)VZ@
 
 
 Z./   CCCCDDDttttt ~z'SZ..00#6DDDDEEE))++w&&*;w*F*FMM=    ''9+?+?MME   tz#*,--   BsBBBCCCttttt dD!! 	CCtCCCCs0   +A. .B(B##B(	E% %F4FF)u7   US Cloud  (https://vault.bitwarden.com — bws default)r>   )z&EU Cloud  (https://vault.bitwarden.eu)zhttps://vault.bitwarden.eurz   r   Optional[str]c                "   | j         r2| j                                         r| j                                         S t          j                            dd                                          }|r|                    d| d           |S t          |                    dd          pd                                          }|r|                    d| d           t          dd	d
d          }|                    ddd           |                    d           t          t          d          D ]+\  }\  }}|                    t          |          |           ,|                    t          t          t                    dz             d           |                    |           t          t                    dz   }		 d|	 d}
|r|
dz  }
|
dz  }
|                    |
                                          }|s|r|S |                    d           V	 t          |          }n%# t          $ r |                    d           Y w xY wd|cxk    rt          t                    k    rn nt          |dz
           d         S ||	k    rl|                    d                                          }|s|                    d           d
S |                    d          s|                    d           |S |                    d|	 d           P)a  Pick a Bitwarden server URL for setup.

    Resolution order:
      1. ``--server-url`` CLI flag (non-interactive)
      2. ``BWS_SERVER_URL`` env var (so users running with that already set
         in their shell don't have to re-enter it)
      3. Existing ``secrets.bitwarden.server_url`` value (for re-runs)
      4. Interactive menu: US / EU / self-hosted

    Returns the chosen URL as a string (empty string = bws default,
    i.e. US Cloud).  Returns None if the user aborted with an empty
    custom URL.
    r   r>   z'  Detected [cyan]BWS_SERVER_URL[/cyan]=u    in your shell — using it.r@   z  Existing config: [cyan]z?[/cyan]. Press Enter to keep, or pick a different option below.TrA   Nr   )rC   rD   r   r   rE   r4   rF   rG   zRegion / endpointr:   zSelf-hosted / custom URLz  Select region [1-]z (Enter to keep current)z: rQ   zD  Enter your Bitwarden server URL (e.g. https://vault.example.com): z!  [red]Empty URL, aborting.[/red])zhttp://zhttps://u]     [yellow]Warning: URL doesn't start with http:// or https:// — bws may reject it.[/yellow]rR   rS   )r@   rg   ri   rj   rf   r_   rp   r	   rm   rn   _REGION_PRESETSro   rr   rq   r2   rs   rh   )r0   rz   rv   env_urlexistingr~   r   label_url
custom_idxpromptr   r   customs                 r-   rk   rk     su   $  '4?0022 '$$&&&jnn-r2288::G [g[[[	
 	
 	
 ;??<44:;;AACCH 
E E E E	
 	
 	

 dT6RRRE	Sa000	()))%oq99 % %=E4c!ffe$$$$	MM#c/**Q.//1KLLLMM%_%%)J M4z444 	100F$v&&,,.. 	  MM8999	f++CC 	 	 	MM8999H	 ++++s?+++++++"37+A..*]]5  egg   ABBBt$$%<== ?   MK
KKKLLLA Ms   H' 'I	I	)r   r   r   r   )r0   r1   r   r2   )r   r   r   rp   )rW   r   r   rp   )
rW   r   r|   rp   rv   r   r@   rp   r   r   )r0   r1   rz   r   rv   r   r   r   )'__doc__
__future__r   argparser   ri   r   pathlibr   typingr   r   rich.consoler   
rich.panelr   
rich.tabler	   agent.secret_sourcesr
   r)   hermes_cli.configr   r   r   r   hermes_cli.secret_promptr   r.   r%   r&   r'   r(   r+   r   rc   rl   r   rk   r   r/   r-   <module>r      s    # " " " " "   				           ! ! ! ! ! ! ! !                         0 0 0 0 0 0            : 9 9 9 9 96+ 6+ 6+ 6+|c c c cL. . . .bG G G GT        : : : :     FH/D /D /D /D /D /Dl DLLM LM LM LM LM LMr/   