
    ,j;F                       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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/
    telemetry          show or toggle Spectrum SDK telemetry (on/off)

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           |                    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	telemetryz.Show or toggle Spectrum SDK telemetry (on/off)state?)onoffz9Turn telemetry on or off (omit to show the current state))nargschoicesr   )func)add_subparsers
add_parseradd_argumentset_defaultsdispatch)r
   subsp_setupp_telemetrys       A/home/ubuntu/.hermes/hermes-agent/plugins/platforms/photon/cli.pyregister_clir*   '   s     &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[[[//= "  K sMH    
 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 |dk    rt	          |           S t          d| t          j                   dS )	Nr   r   r   r   r   zunknown subcommand: file   )getattr_cmd_status
_cmd_setup_cmd_install_sidecar_cmd_telemetryprintsysstderr)r,   subs     r)   r%   r%   M   s    
$($
/
/C
{4   
g~~$
h4   
#D)))
k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_urir8   	user_code)codetargets     r)   _print_codez&_run_device_login.<locals>._print_codeh   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: r0   Nr   u!   ✓ logged in — token saved to r   )photon_authlogin_device_flow
no_browser	Exceptionr8   r9   r:   _auth_json_path)r,   rD   tokene_s        r)   _run_device_loginrO   a   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 storedr0   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_idrS   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.r>   uC         No iMessage line assigned yet — check the Photon dashboard.)rX   assigned_phone_numberuser_idrW   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)#rG   load_photon_tokenr8   rO   r9   r:   project_nameDEFAULT_PROJECT_NAMEload_dashboard_project_idfind_project_by_namegetcreate_projectrJ   ensure_spectrum_enabledstrregenerate_project_secretstore_project_credentialsphone_promptr   r   CYANrY   r[   register_user_if_absentrZ   
ValueErroruser_assigned_line_autoconfigure_accessget_imessage_lineGREENBOLDstore_user_numbersskip_sidecar_install_install_sidecar)r,   rL   rcrS   dashboard_idexistingcreatedrM   projspectrum_idsecretrk   agent_numberregistered_phoneregistered_user_idrY   r[   userlines                      r)   r5   r5      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"rk   rh   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 (r]   z      could not set z: r0   )hermes_cli.configr   r   ImportErrorr8   rJ   r9   r:   )rk   r   r   keylabelrM   s         r)   rq   rq     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                v   t                       t          j        t                     t	          j        d          pt          j        d          }t          dz  	                                }t          d|pd            t          d|rdnd            t          d	t                      rd
nd 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`z  telemetry           : r   r   z# (`hermes photon telemetry on|off`)r   )_refresh_status_numbersrG   print_credential_summaryr8   osgetenvshutilwhich_SIDECAR_DIRexists_telemetry_enabled)r   node_binsidecar_installeds      r)   r4   r4   4  s     (///y*++Cv|F/C/CH%6>>@@	
SX%Q1Q
S
STTT	
z8I%x__Ox
z
z{{{	
q-?-A-A%LTTu
q
q
qrrr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: r]   r0   )rG   load_user_numbersload_project_credentialsrefresh_user_numbersrJ   r8   r9   r:   )rk   assignedr}   rV   rM   s        r)   r   r   B  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)rw   )r   s    r)   r6   r6   O  s    r+   boolc                     	 ddl m}   | d          }n$# t          $ r t          j        d          }Y nw xY w|pd                                                                dv S )zRead PHOTON_TELEMETRY from the env / ~/.hermes/.env.

    Mirrors the sidecar's truthy set (index.mjs) so the state shown here
    always matches what the sidecar will actually do.
    r   )r   PHOTON_TELEMETRY )1trueyesr   )r   r   r   r   r   striplower)r   raws     r)   r   r   S  s    ,333333m.// , , ,i*++,I2$$&&*DDDs    55c                z   t          | dd           }|3t          dt                      rdnd            t          d           dS 	 ddlm}  |d|dk    rd	nd
           n6# t
          $ r)}t          d| t          j                   Y d }~dS d }~ww xY wt          d| d           t          d           dS )Nr   zPhoton telemetry: r   r   zK  Toggle with `hermes photon telemetry on` / `hermes photon telemetry off`.r   )r   r   r   falsez!could not save PHOTON_TELEMETRY: r0   r   u   ✓ Spectrum telemetry turned z% (PHOTON_TELEMETRY in ~/.hermes/.env)zL  Restart the gateway for the sidecar to pick it up:  hermes gateway restart)r3   r8   r   r   r   rJ   r9   r:   )r,   r   r   rM   s       r)   r7   r7   a  s   D'4((E}L+=+?+?#J44ULLMMM[\\\q444444)Ud]]66PPPP   5!55CJGGGGqqqqq 

W5
W
W
WXXX	
XYYY1s   A# #
B-BBc                    t          j        d          pd} t          j        |           st          dt          j                   dS t          dt
           d|  d           t          j        | dgt          t
                    d	
          }|j	        dk    r>t          d|  d           t          j        | 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.r0   r   z  $ cd z && z ciciF)cwdcheckr   u&     npm ci failed — falling back to:  z installinstallznpm install failed)
r   r   r8   r9   r:   r   
subprocessrunrh   
returncode)r   procs     r)   rw   rw   r  s!   
,u


&C< 	
 	
 	
 	

 q 

.L
.
.c
.
.
.///>	d  D
 !DsDDDEEE~)L!!
 
 

 !"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   ra   rk   rY   rZ   r[   rI   rv   )argparse	Namespacer5   )r,   s    r)   gateway_setupr     sG    "	 	 	D tr+   F)r~   promptr~   c               "   t           j                                        sdS 	 |r&t          j        |                                           S t          |                                           S # t          t          f$ r t                       Y dS w xY w)Nr   )	r9   stdinisattygetpassr   inputKeyboardInterruptEOFErrorr8   )r   r~   s     r)   rl   rl     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.   )rk   rh   r   r   )r   r-   r   r.   )r   r   )r   r   )r   r.   )r   rh   r~   r   r   rh   )!__doc__
__future__r   r   r   r   r   r   r9   pathlibr   hermes_cli.colorsr   r   r   r   rG   __file__parentr   r*   r%   rO   r5   rq   r4   r   r6   r   r7   rw   r   rl    r+   r)   <module>r      s   $ # " " " " "   				      



       + + + + + + + + ! ! ! ! ! !tH~~$y0 '  '  '  'L   (   @U U U UpF F F F6   
V 
V 
V 
V   E E E E   "   X   $ ,1 	 	 	 	 	 	 	 	r+   