
    iM>                     
   d Z ddlZddlmZmZmZmZ ddlmZm	Z	 ddZ
dddded	ee         d
ee         dee         dz  deeee         gef                  dee         fdZ	 dddded	ee         d
ededz  def
dZded	ee         d
ededef
dZ	 dddded	ee         dedededz  f
dZded	ee         dededz  fdZ	 dded	ee         d
ee         dee         deeee         gef                  dee         fdZdS )zShared curses-based UI components for Hermes CLI.

Used by `hermes tools` and `hermes skills` for interactive checklists.
Provides a curses multi-select with keyboard navigation, plus a
text-based numbered fallback for terminals without curses support.
    N)CallableListOptionalSet)Colorscolorreturnc                      	 t           j                                        sdS ddl} |                     t           j        | j                   dS # t          $ r Y dS w xY w)u  Flush any stray bytes from the stdin input buffer.

    Must be called after ``curses.wrapper()`` (or any terminal-mode library
    like simple_term_menu) returns, **before** the next ``input()`` /
    ``getpass.getpass()`` call.  ``curses.endwin()`` restores the terminal
    but does NOT drain the OS input buffer — leftover escape-sequence bytes
    (from arrow keys, terminal mode-switch responses, or rapid keypresses)
    remain buffered and silently get consumed by the next ``input()`` call,
    corrupting user data (e.g. writing ``^[^[`` into .env files).

    On non-TTY stdin (piped, redirected) or Windows, this is a no-op.
    Nr   )sysstdinisattytermiostcflushTCIFLUSH	Exception)r   s    2/root/.hermes/hermes-agent/hermes_cli/curses_ui.pyflush_stdinr      sl    y!! 	F	7#344444   s   A )A 
AA)cancel_returns	status_fntitleitemsselectedr   r   c                f    t          |          t          j                                        sS 	 ddlt          |          dg fd}                    |           t                       d         d         nS # t          $ r t           |          cY S w xY w)a  Curses multi-select checklist. Returns set of selected indices.

    Args:
        title: Header line displayed above the checklist.
        items: Display labels for each row.
        selected: Indices that start checked (pre-selected).
        cancel_returns: Returned on ESC/q. Defaults to the original *selected*.
        status_fn: Optional callback ``f(chosen_indices) -> str`` whose return
            value is rendered on the bottom row of the terminal.  Use this for
            live aggregate info (e.g. estimated token counts).
    Nr   c           
                              d                                           rw                                                                                      dj        d                               dj        d                               ddd           d}d}	 |                                  |                                 \  }}rdnd}	 j	        }                                r|
                    d          z  }|                     dd|dz
  |           |                     ddd|dz
  j                   n# j        $ r Y nw xY w|dz
  |z
  }||k     r|}n|||z   k    r||z
  dz   }t          t          |t!          t#                    ||z                                 D ]\  }}	|dz   }
|
|dz
  |z
  k    r n|	v rd	nd
}|	|k    rdnd
}d
| d| d|	          }j        }|	|k    r3j	        }                                r|
                    d          z  }	 |                     |
d||dz
  |           # j        $ r Y w xY wr	            }|rxt'          d|t#          |          z
  dz
            }j        }                                r|
                    d          z  }|                     |dz
  ||||z
  dz
  |           n# j        $ r Y nw xY w|                                  |                                 }|j        t/          d          fv r|dz
  t#                    z  }n|j        t/          d          fv r|dz   t#                    z  }nd|t/          d
          k    r                    |h           n:|j        ddfv rt7                    d<   d S |dt/          d          fv rd<   d S <)Nr               Tu:     ↑↓ navigate  SPACE toggle  ENTER confirm  ESC cancelu   ✓    →z [z] kj
         q)curs_set
has_colorsstart_coloruse_default_colors	init_pairCOLOR_GREENCOLOR_YELLOWcleargetmaxyxA_BOLD
color_pairaddnstrA_DIMerror	enumeraterangeminlenA_NORMALmaxrefreshgetchKEY_UPordKEY_DOWNsymmetric_difference_update	KEY_ENTERset)stdscrcursorscroll_offsetmax_ymax_xfooter_rowshattrvisible_rowsdraw_iiycheckarrowlineattrstatus_textsxsattrkeyr   chosencursesr   result_holderr   r   s                      r   _drawzcurses_checklist.<locals>._drawC   s   OOA  "" +""$$$))+++  F$6;;;  F$7<<<  Ar***FMK%00u $-3aa!"ME((** 6!2!21!5!55NN1a	5AAANN1T	6<   
 |   D  %qy;6M))$*MM}|;;;$*\$9A$=M!*-SZZ9U)V)VWW" "  IFA 
AEAI333%&&[[EEcE%&&[[EEcE;u;;;;q;;D!?DF{{%}!,,.. 9 F$5$5a$8$88Dq!T519dCCCC!<     
&/i&7&7& ^!$QK0@0@(@1(D!E!EB$*LE%0022 > %):):1)=)= ="NN519b+urzTU~W\]]]!<       llnn6=#c((333$qjCJJ6FFV_c#hh777$qjCJJ6FFCHH__66x@@@@V-r2666'*6{{M!$FRSN**'5M!$FWKs8   A0E
 

EE3I
II#BK) )
K65K6)	rC   r   r   r   rX   wrapperr   r   _numbered_fallback)	r   r   r   r   r   rZ   rW   rX   rY   s	   `` `` @@@r   curses_checklistr]   #   s   & X 9 bUX#fV	 V	 V	 V	 V	 V	 V	 V	 V	 V	 V	p 	u#0#3#?}Q^S U U U!%.)TTTTTUs   AB B0/B0)r   c                (    t           j                                        sS 	 ddldg fd}                    |           t                       d         d         nS # t          $ r t                     cY S w xY w)a:  Curses single-select radio list. Returns the selected index.

    Args:
        title: Header line displayed above the list.
        items: Display labels for each row.
        selected: Index that starts selected (pre-selected).
        cancel_returns: Returned on ESC/q. Defaults to the original *selected*.
    Nr   c           
                               d                                           r`                                                                                      dj        d                               dj        d           }d}	 |                                  |                                 \  }}	 j	        }                                r|
                    d          z  }|                     dd|dz
  |           |                     ddd|dz
  j                   n# j        $ r Y nw xY w|dz
  }||k     r|}n|||z   k    r||z
  dz   }t          t          |t!          t#                    ||z                                 D ]\  }}|dz   }	|	|dz
  k    r n|k    rd	nd
}
||k    rdnd}d| d|
 d|          }j        }||k    r3j	        }                                r|
                    d          z  }	 |                     |	d||dz
  |           # j        $ r Y w xY w|                                  |                                 }|j        t-          d          fv r|dz
  t#                    z  }ni|j        t-          d          fv r|dz   t#                    z  }n;|t-          d          j        ddfv r|d<   d S |dt-          d          fv rd<   d S p)Nr   r   r   r   Tu1     ↑↓ navigate  ENTER/SPACE select  ESC cancel   r   u   ●u   ○r!   r    z (z) r"   r#   r$   r%   r&   r'   )r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r<   r=   r>   r?   r@   rB   )rD   rE   rF   rG   rH   rJ   rK   rL   rM   rN   radiorP   rQ   rR   rV   r   rX   r   rY   r   r   s                  r   rZ   zcurses_radiolist.<locals>._draw   s   OOA  "" =""$$$))+++  F$6;;;  F$7<<<FM8%00u"ME((** 6!2!21!5!55NN1a	5AAANN1Q	6<   
 |   D  %qyM))$*MM}|;;;$*\$9A$=M!*-SZZ9U)V)VWW" "  IFA 
AEAI~~()XHH8E()VHHE;u;;;;q;;D!?DF{{%}!,,.. 9 F$5$5a$8$88Dq!T519dCCCC!<       llnn6=#c((333$qjCJJ6FFV_c#hh777$qjCJJ6FFSXXv'7R@@@'-M!$FRSN**'5M!$Fq8s%   <A0D- -
D:9D:H//
H<;H<)r   r   r   rX   r[   r   r   _radio_numbered_fallback)r   r   r   r   rZ   rX   rY   s   ```` @@r   curses_radiolistrc      s     !9 MP#fB	 B	 B	 B	 B	 B	 B	 B	 B	 B	H 	u#0#3#?}Q^S P P P'uhOOOOOPs   AA2 2BBc           	         t          t          d|  t          j                             t          t          dt          j                             t          |          D ]C\  }}||k    rt          dt          j                  nd}t          d| d|dz   dd	|            Dt                       	 t          t          d
|dz    dt          j                                                            }|s|S t          |          dz
  }d|cxk    rt          |          k     rn n|S |S # t          t          t          f$ r |cY S w xY w)z1Text-based numbered fallback for radio selection.
  z&  Select by number, Enter to confirm.
u   (●)u   (○)  r    r   >2. z  Choice [default ]: r   )printr   r   YELLOWDIMr6   GREENinputstripintr9   
ValueErrorKeyboardInterruptEOFError)	r   r   r   r   rM   labelmarkervalidxs	            r   rb   rb     si    
%u
.
.///	%96:
F
FGGGe$$ 1 1545MMz6<000z/6//AE/////0000	GGG	E@x!|@@@&*MMNNTTVV 	O#hhl    c%jj     J)84   s   4AD+ 80D+ )D+ +EECancel)cancel_labeldefault_indexry   c                    t           j                                        sdS 	 ddldgt	          |          |gz   t          |          } fd}                    |           t                       d         d         |k    rdS d         S # t          $ r6 t	          |          |gz   t          |          }t           |          cY S w xY w)zCurses single-select menu. Returns selected index or None on cancel.

    Works inside prompt_toolkit because curses.wrapper() restores the terminal
    safely, unlike simple_term_menu which conflicts with /dev/tty.
    Nr   c           
                              d                                           r`                                                                                      dj        d                               dj        d           t          t                    dz
            }d}	 | 	                                 | 
                                \  }}	 j        }                                r|                    d          z  }|                     dd|dz
  |           |                     ddd|dz
  j                   n# j        $ r Y nw xY w|dz
  }||k     r|}n|||z   k    r||z
  dz   }t!          t#          |t          t                    ||z                                 D ]\  }}|dz   }	|	|dz
  k    r n||k    rdnd	}
d	|
 d	|          }j        }||k    r3j        }                                r|                    d          z  }	 |                     |	d||dz
  |           # j        $ r Y w xY w|                                  |                                 }|j        t-          d
          fv r|dz
  t                    z  }n[|j        t-          d          fv r|dz   t                    z  }n-|j        ddfv r|d<   d S |dt-          d          fv rd d<   d S U)Nr   r   r   r   Tu.     ↑↓ navigate  ENTER confirm  ESC/q cancelr   r!   r    r"   r#   r$   r%   r&   r'   )r(   r)   r*   r+   r,   r-   r.   r8   r9   r/   r0   r1   r2   r3   r4   r5   r6   r7   r:   r<   r=   r>   r?   r@   rB   )rD   rE   rF   rG   rH   rJ   rK   rL   rM   rN   rP   rQ   rR   rV   	all_itemsrX   rz   rY   r   s                 r   rZ   z#curses_single_select.<locals>._draw8  s   OOA  "" =""$$$))+++  F$6;;;  F$7<<<I(:;;FM5%00u"ME((** 6!2!21!5!55NN1a	5AAANN1H	6<   
 |   D  %qyM))$*MM}|;;;$*\$9A$=M!*-S^^]\=Y)Z)Z[[" "  IFA 
AEAI~~%&&[[EEcE5u55y|55D!?DF{{%}!,,.. 9 F$5$5a$8$88Dq!T519dCCCC!<       llnn6=#c((333$qjC	NN:FFV_c#hh777$qjC	NN:FFV-r2666'-M!$FRSN**'+M!$Fk5s%   A0E 
EE#I  
II)
r   r   r   rX   listr9   r[   r   r   _numbered_single_fallback)	r   r   rz   ry   
cancel_idxrZ   r}   rX   rY   s	   ` `   @@@r   curses_single_selectr   "  s!    9 tQG#fKK<.0	ZZ
?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	B 	u'M!,<
,J,J4Q G G GKK<.0	ZZ
(	:FFFFFGs   A)B B =CCr   c                    t          d|  d           t          |d          D ]\  }}t          d| d|            t                       	 t          dt          |           d                                          }|sdS t          |          dz
  }d	|cxk    rt          |          k     rn n||k     r|S ||k    rdS n# t          t          t          f$ r Y nw xY wdS )
z/Text-based numbered fallback for single-select.re   
r   rf   rh   z  Choice [1-ri   Nr   )	rj   r6   rn   r9   ro   rp   rq   rr   rs   )r   r   r   rM   rt   rv   rw   s          r   r   r     s+    




eQ'' ! !51    	GGG
23u::2223399;; 	4#hhl    c%jj     S:%5%5J*4 )84   4s   4C 6C ;C CCc           	      \   t          |          }t          t          d|  t          j                             t          t          dt          j                             	 t          |          D ]A\  }}||v rt          dt          j                  nd}t          d| d|dz   d	d
|            B|r7 ||          }	|	r*t          t          d|	 t          j                             t                       	 t          t          dt          j                            	                                }
|
snut          |
          dz
  }d|cxk    rt          |          k     rn n|                    |h           n# t          t          t          f$ r |cY S w xY wt                       J|S )z8Text-based toggle fallback for terminals without curses.re   z&  Toggle by number, Enter to confirm.
Tu   [✓]z[ ]rf   r    r   rg   rh   z"  Toggle # (or Enter to confirm): r   )rC   rj   r   r   rk   rl   r6   rm   rn   ro   rp   r9   rA   rq   rr   rs   )r   r   r   r   r   rW   rM   rt   ru   rS   rv   rw   s               r   r\   r\     s    ]]F	%u
.
.///	%96:
F
FGGG!%(( 	5 	5HAu56&[[U7FL111eF3v33A333E334444 	?#)F++K ?e0;00&*==>>>	"BFJOOPPVVXXC c((Q,CC$$$$#e**$$$$$22C5999-x8 	" 	" 	"!!!!	"%( Ms   ;;E= 7AE= =FF)r	   N)r   )N)__doc__r   typingr   r   r   r   hermes_cli.colorsr   r   r   strrp   r]   rc   rb   r   r   r\        r   <module>r      s    


 0 0 0 0 0 0 0 0 0 0 0 0 + + + + + + + +   6 '+59}U }U }U}U9}U #h}U
 HtO}U #c(S12}U 	X}U }U }U }UF bP
 "&bP bP bPbP9bP bP
 $JbP 	bP bP bP bPJ9  	
 	   : `G
 !`G `G `G`G9`G `G
 `G 	4Z`G `G `G `GF9  	4Z	   : 6:    9  #h  H	 
 #c(S12  	X           r   