
    |+j=                        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ZddlZddl	m
Z
 ddlmZmZ ddlmZ  e
e          j        dz  Zd#dZd$dZd$d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S )*u  
``hermes photon ...`` CLI subcommands — registered by the plugin via
``ctx.register_cli_command()``.

Subcommands:

    setup              full first-time setup (device login + project + user + sidecar)
    status             show login + project + sidecar dep state
    install-sidecar    npm install inside plugins/platforms/photon/sidecar/

The device-code login runs automatically as the first step of ``setup``;
there is no standalone ``login`` verb (matching how every other Hermes
gateway channel onboards through a single setup surface).

Photon uses the spectrum-ts gRPC stream for inbound — there is no webhook
to register, so there are no webhook subcommands.
    )annotationsN)Path)Colorscolor   )authsidecarparserargparse.ArgumentParserreturnNonec                >   |                      dd          }|                    dd          }|                    ddd	
           |                    ddd
           |                    dd           |                    dd           |                    dd           |                    ddd           |                    ddd           |                    dd           |                    dd           |                     t                     dS )z(Wire up `hermes photon ...` subcommands.photon_commandF)destrequiredsetupz:First-time setup (device login + project + user + sidecar))helpz--project-nameNz&Project name (default: 'Hermes Agent'))defaultr   z--phonez+Your E.164 phone number (e.g. +15551234567)z--first-name)r   z--last-namez--emailz--no-browser
store_truez@Don't try to open a browser for device login; print the URL only)actionr   z--skip-sidecar-installz/Skip `npm install` inside the sidecar directorystatusz(Show login + project + sidecar dep stateinstall-sidecarz,Run npm install inside the sidecar directory)func)add_subparsers
add_parseradd_argumentset_defaultsdispatch)r
   subsp_setups      ;/usr/local/lib/hermes-agent/plugins/platforms/photon/cli.pyregister_clir"   &   sr     &6 GGDooI   G )4F  H H HDK  M M M666555D111`  b b b1,O  Q Q Q 	OOH#MONNNOO%,ZO[[[
X&&&&&    argsargparse.Namespaceintc                   t          | dd           }|t          |           S |dk    rt          |           S |dk    rt          |           S |dk    rt          |           S t	          d| t
          j                   dS )Nr   r   r   r   zunknown subcommand: file   )getattr_cmd_status
_cmd_setup_cmd_install_sidecarprintsysstderr)r$   subs     r!   r   r   C   s    
$($
/
/C
{4   
g~~$
h4   
#D)))	
&
&
&SZ88881r#   c                    d }	 t          j        | j         |          }n6# t          $ r)}t	          d| t
          j                   Y d}~dS d}~ww xY w|}t	          dt          j                                dS )	u  Run the RFC 8628 device-code login flow and persist the token.

    Internal helper — invoked as the first step of ``setup``. There is
    no standalone ``hermes photon login`` command; Photon onboards
    through the single ``setup`` surface like every other channel.
    c                   | j         p| j        }t                       t          d           t          d|            t          d| j                    t          d           t          d           t                       d S )Nu   ┌─ Photon device login ────────────────────────────────────────u   │  Open this URL:  u   │  Enter the code: u0   │  (waiting for approval — Ctrl-C to cancel)   └──────────────────────────────────────────────────────────────)verification_uri_completeverification_urir/   	user_code)codetargets     r!   _print_codez&_run_device_login.<locals>._print_code\   s    /H43H  d  	e  	e  	e.f..///6dn66777@AAA  N  	O  	O  	Or#   )open_browseron_user_codezlogin failed: r(   Nr   u!   ✓ logged in — token saved to r   )photon_authlogin_device_flow
no_browser	Exceptionr/   r0   r1   _auth_json_path)r$   r;   tokene_s        r!   _run_device_loginrF   U   s      -!_,$
 
 
    "q""4444qqqqq
 	A	
Mk.I.K.K
M
MNNN1s   " 
AAAc                   t          j                    }|sYt          d           t          |           }|dk    r|S t          j                    }|st          dt          j                   dS nt          d           | j        pt           j        }t          j                    }	 |rt          d           nt          j	        ||          }|r1|
                    d          r|d         }t          d	| d
           nMt          d| d           t          j        ||          }|
                    d          }t          d           n6# t          $ r)}t          d| t          j                   Y d }~dS d }~ww xY w|st          dt          j                   dS 	 t          d           t          j        ||          }|
                    d          }	|	st          dt          j                   dS t          |	          }	t          j        ||          }
t          j        |	|
||           t          d|	 d           n6# t          $ r)}t          d| t          j                   Y d }~dS d }~ww xY w| j        p&t%          t'          dt(          j                            }d }d }d }|st          d           n| j        }| j        }	 t          j        |	|
||| j        |          \  }}ng# t4          $ r)}t          d| t          j                   Y d }~dS d }~wt          $ r)}t          d| t          j                   Y d }~dS d }~ww xY wt          |rdnd           |}|
                    d          }t          j        |          }t9          |           |sd	 t          j        ||          }|r|
                    d          }n6# t          $ r)}t          d | d!t          j                   Y d }~nd }~ww xY w|rt                       t          t'          d"t(          j                             t          t'          d#t(          j                  t'          t          |          t(          j        t(          j                  z              t          t'          d$t(          j                             t          t'          d%t(          j                             nt          d&           |ra	 t          j         |||rt          |          nd |'           n6# t          $ r)}t          d(| d!t          j                   Y d }~nd }~ww xY w| j!        rt          d)           n%t          d*           tE                      }|dk    r|S t                       t          d+           t          d,           dS )-Nu7   [1/5] No Photon token found — running device login...r   z(login completed but token was not storedr(   r   z#[1/5] Reusing existing Photon tokenz'[2/5] Reusing configured Photon projectidz[2/5] Found existing project ''z[2/5] Creating Photon project 'z'...)nameu     ✓ project createdzproject setup failed: z%could not resolve a Photon project idz7[3/5] Enabling Spectrum and provisioning credentials...spectrumProjectIdz4spectrum provisioning failed: no spectrum project id)spectrum_project_idproject_secretdashboard_project_idrJ   u#     ✓ Spectrum enabled (project id u   ) — secret savedzspectrum provisioning failed: z=[4/5] Your iMessage phone number (E.164, e.g. +15551234567): zL      Skipped user registration (no phone given). Re-run with --phone later.)phone_number
first_name	last_nameemailz      invalid phone number: z       user registration failed: u     ✓ phone registeredu     ✓ phone already registeredphoneNumberz*      (could not fetch the assigned line: )u   ┌─ Your agent's iMessage number ───────────────────────────────u
   │  📱 u<   │  Text this number from your phone to talk to your agent.r5   uC         No iMessage line assigned yet — check the Photon dashboard.)rO   assigned_phone_numberuser_idrN   z.      (could not save Photon status metadata: z;[5/5] Skipping sidecar npm install (--skip-sidecar-install)z3[5/5] Installing Node sidecar deps (spectrum-ts)...u   ✓ Photon setup complete.z<  Start the gateway:  hermes gateway start --platform photon)#r>   load_photon_tokenr/   rF   r0   r1   project_nameDEFAULT_PROJECT_NAMEload_dashboard_project_idfind_project_by_namegetcreate_projectrA   ensure_spectrum_enabledstrregenerate_project_secretstore_project_credentialsphone_promptr   r   CYANrP   rR   register_user_if_absentrQ   
ValueErroruser_assigned_line_autoconfigure_accessget_imessage_lineGREENBOLDstore_user_numbersskip_sidecar_install_install_sidecar)r$   rC   rcrJ   dashboard_idexistingcreatedrD   projspectrum_idsecretrb   agent_numberregistered_phoneregistered_user_idrP   rR   userlines                      r!   r-   r-   u   s    )++E 
5GHHHt$$77I-// 	<3:NNNN1	 	3444 @ @D8::L 	/;<<<<"7tDDH /HLL.. /'~>t>>>????BBBBCCC%4UFFF&{{400-...   *q**<<<<qqqqq  5CJGGGGqGHHH25,GGhh233 	HszZZZZ1+&&6ulKK- +!!-		
 	
 	
 	
 	SKSSSTTTT   2q22DDDDqqqqq
 J 'KK	
 	
 E L  %\]]]] _

	'?V"%.  MD''  	 	 	4443:FFFF11111 	 	 	8Q88szJJJJ11111	 	'W&&7WXXX !XXd^^
 #5d;; 	e$$$  V	V0EED 7#xx66 	V 	V 	VCqCCC#*UUUUUUUUU	V 
Ue  X  Z`  Zf  g  g  	h  	h  	h,--C%%v|V[AAB	
 	
 	
 	eRTZT`aabbbe  T  V\  Vb  c  c  	d  	d  	d  	dSTTT 	Z	Z*-&23EO.///4%1	      	Z 	Z 	ZG1GGGcjYYYYYYYYY	Z   KLLLLCDDD77I	GGG	
&'''	
HIII1s   %B'E 
F E;;F #AI ;AI 
I>I99I>"K9 9
ML''M4MM0,O 
P'PP)T/ /
U"9UU"rb   r_   c                @   	 ddl m}m} n# t          $ r Y dS w xY wdD ]\  }}	  ||          rt	          d| d           % |||            t	          d| d| d	           H# t
          $ r+}t	          d
| d| t          j                   Y d}~xd}~ww xY wdS )a  Allowlist the operator and set their DM as the cron home channel.

    Writes ``PHOTON_ALLOWED_USERS`` (so the gateway authorizes the operator's
    own inbound messages instead of denying them) and ``PHOTON_HOME_CHANNEL``
    (the default space for cron delivery) to the operator's E.164 number. Each
    is only filled when unset, so a hand-tuned allowlist / home channel is
    never clobbered on a re-run.
    r   )get_env_valuesave_env_valueN))PHOTON_ALLOWED_USERSzallowlisted your number)PHOTON_HOME_CHANNELz$set your DM as the cron home channelz      u"    already set — leaving it as-is.u     ✓ z (rT   z      could not set z: r(   )hermes_cli.configr|   r}   ImportErrorr/   rA   r0   r1   )rb   r|   r}   keylabelrD   s         r!   rh   rh     s+   CCCCCCCCC    F F
U	F}S!! FsFFFGGGN3&&&*5**C***++++ 	F 	F 	F33333#*EEEEEEEEE	FF Fs)    
A&"A&&
B0!BB_argsc                0   t                       t          j        t                     t	          j        d          pt          j        d          }t          dz  	                                }t          d|pd            t          d|rdnd            d	S )
NPHOTON_NODE_BINnodenode_modulesz  node binary         : u   ✗ missing (install Node 18+)z  sidecar deps        : u   ✓ installedu'   ✗ run `hermes photon install-sidecar`r   )
_refresh_status_numbersr>   print_credential_summaryr/   osgetenvshutilwhich_SIDECAR_DIRexists)r   node_binsidecar_installeds      r!   r,   r,   (  s     (///y*++Cv|F/C/CH%6>>@@	
SX%Q1Q
S
STTT	
z8I%x__Ox
z
z{{{1r#   c                    t          j                    \  } }| r|rd S t          j                    \  }}|r|sd S 	 t          j        ||           d S # t          $ r*}t          d| dt          j                   Y d }~d S d }~ww xY w)Nz.      (could not refresh Photon user numbers: rT   r(   )r>   load_user_numbersload_project_credentialsrefresh_user_numbersrA   r/   r0   r1   )rb   assignedrt   rM   rD   s        r!   r   r   5  s    !355OE8  "-"F"H"HK n V(nEEEEE V V VCqCCC#*UUUUUUUUUUVs   A 
BB  Bc                    t                      S )N)rn   )r   s    r!   r.   r.   B  s    r#   c                 x   t          j        d          pd} t          j        |           st          dt          j                   dS t          dt
           d|  d           t          j        | dd	gt          t
                    d
          }|j	        dk    rt          dt          j                   |j	        S )NnpmzInpm is not on PATH. Install Node.js 18+ (https://nodejs.org/) and re-run.r(   r   z  $ cd z && z install spectrum-ts@latestinstallzspectrum-ts@latestF)cwdcheckr   znpm install failed)
r   r   r/   r0   r1   r   
subprocessrunr_   
returncode)r   procs     r!   rn   rn   F  s    
,u


&C< 	
 	
 	
 	

 q
 

FL
F
Fc
F
F
FGGG>	i-.  D
 !"4444?r#   c            
     \    t          j        dddddddd          } t          |            dS )zCRun Photon first-time setup from the `hermes gateway setup` wizard.r   NF)r   rX   rb   rP   rQ   rR   r@   rm   )argparse	Namespacer-   )r$   s    r!   gateway_setupr   h  sG    "	 	 	D tr#   F)ru   promptru   boolc               "   t           j                                        sdS 	 |r&t          j        |                                           S t          |                                           S # t          t          f$ r t                       Y dS w xY w)N )	r0   stdinisattygetpassstripinputKeyboardInterruptEOFErrorr/   )r   ru   s     r!   rc   rc   z  s    9 r 	3?6**00222V}}""$$$x(   rrs   'A+ 
 A+ +BB)r
   r   r   r   )r$   r%   r   r&   )rb   r_   r   r   )r   r%   r   r&   )r   r   )r   r&   )r   r_   ru   r   r   r_   )__doc__
__future__r   r   r   r   r   r   r0   pathlibr   hermes_cli.colorsr   r   r   r   r>   __file__parentr   r"   r   rF   r-   rh   r,   r   r.   rn   r   rc    r#   r!   <module>r      s   " # " " " " "   				      



       + + + + + + + + ! ! ! ! ! !tH~~$y0' ' ' ':   $   @U U U UpF F F F6
 
 
 

V 
V 
V 
V      D   $ ,1 	 	 	 	 	 	 	 	r#   