
    sj                        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m	Z	 ddl
mZ dZdZ ej        d          ZddZddZd dZd!dZd"dZd#d$dZd%dZd dZdS )&u  Per-terminal session breadcrumbs for ``hermes -c`` / ``--continue``.

Each CLI session writes a tiny breadcrumb file
``$HERMES_HOME/terminal-sessions/<terminal-id>`` containing
``{"session_id": ..., "cwd": ..., "ts": ...}``.  A bare ``hermes -c`` then
resumes the session that belongs to THIS terminal (tty / tmux pane / kitty
window / wezterm pane / ...) instead of the globally most-recent session —
so two terminals side by side each continue their own conversation.

Everything here is strictly best-effort: no function raises, and when no
stable terminal identity can be derived (no tty and no known multiplexer
env var) breadcrumbs are skipped entirely and ``-c`` falls back to the
existing latest-session behavior.  Gated by ``session.terminal_continue``
in config.yaml (default true).
    )annotationsN)Path)Optional)ZELLIJ_PANE_ID	TMUX_PANEKITTY_WINDOW_IDWEZTERM_PANETERM_SESSION_ID
WT_SESSIONi ' z[^A-Za-z0-9._-]returnr   c                 (    ddl m}   |             dz  S )Nr   get_hermes_homezterminal-sessions)hermes_constantsr   r   s    C/home/agent/.hermes/hermes-agent/hermes_cli/terminal_breadcrumbs.py_breadcrumbs_dirr   .   s(    000000?222    rawstrc                    t                               d|                                                     d                    dd         S )zGMake an id safe to use as a filename (``/dev/pts/3`` -> ``dev-pts-3``).-/Nx   )_SANITIZE_REsubstrip)r   s    r   	_sanitizer   4   s7    C!2!23!7!788#>>r   Optional[str]c                 ~   t           j        t           j        fD ]P} 	 t          j        |                                           }n# t          $ r Y 6w xY w|rdt          |           c S Qt          D ]K}t          j	        
                    |          }|r(|                                 dt          |           c S LdS )u  Derive a stable identity for the terminal this process runs in.

    Prefers the real tty device path (stdin, then stdout), else the first
    present multiplexer/emulator env var. Returns ``None`` when neither is
    available — callers must then skip breadcrumbs entirely.
    ztty-r   N)sysstdinstdoutosttynamefileno	Exceptionr   _TERMINAL_ENV_VARSenvirongetlower)fdnamevarvals       r   get_terminal_idr/   9   s     y#*% , ,	:biikk**DD 	 	 	H	 	,+)D//+++++	,! 5 5jnnS!! 	5iikk44IcNN44444	54s   &A
AAboolc                     	 ddl m}  t           |                                 d          pi                     dd                    S # t          $ r Y dS w xY w)z:Config gate: ``session.terminal_continue`` (default true).r   load_configsessionterminal_continueT)hermes_cli.configr3   r0   r)   r&   r2   s    r   
is_enabledr7   N   st    111111[[]]&&y117R<<=PRVWWXXX   tts   AA 
AA	directorynowfloatNonec                   	 |                                  D ]`}	 |                                r9||                                j        z
  t          k    r|                                 Q# t          $ r Y ]w xY wdS # t          $ r Y dS w xY w)zCBest-effort removal of breadcrumbs older than the staleness window.N)iterdiris_filestatst_mtime_STALE_AFTER_SECONDSunlinkOSError)r8   r9   entrys      r   _prune_stalerE   X   s    &&(( 	 	E==?? #sUZZ\\-B'BEY'Y'YLLNNN   		 	    s5   A9 AA'&A9 '
A41A9 3A44A9 9
BB
session_idcwdc                   	 | rt                      sdS t                      }|sdS t                      }|                    dd           t	          j                    }| |pt          j                    |d}|d| dz  }|                    t          j	        |          d           t          j
        |||z             t          ||           dS # t          $ r Y dS w xY w)	zRecord that this terminal's live session is ``session_id``.

    Synchronous, best-effort, never raises. No-op when the feature is
    disabled, the session id is empty, or no terminal identity exists.
    NT)parentsexist_ok)rF   rG   ts.z.tmputf-8encoding)r7   r/   r   mkdirtimer#   getcwd
write_textjsondumpsreplacerE   r&   )rF   rG   terminal_idr8   r9   payloadtmps          r   write_breadcrumbrZ   e   s
    	 	F%'' 	F$&&	t444ikk$%")++
 

 /k////tz'**W===

3	K/000Y$$$$$   s   C C B+C 
C! C!Optional[dict]c                    	 t                      } | sdS t                      | z  }t          j        |                    d                    }t          |t                    r6t          |                    d          pd          	                                sdS |                    d          }t          |t          t          f          r!t          j                    |z
  t          k    rdS |S # t          $ r Y dS w xY w)zReturn this terminal's breadcrumb payload, or ``None``.

    Ignores breadcrumbs older than the staleness window. Never raises.
    NrM   rN   rF    rK   )r/   r   rT   loads	read_text
isinstancedictr   r)   r   intr:   rQ   rA   r&   )rW   pathdatarK   s       r   read_breadcrumbre      s    
%'' 	4!!K/z$..'.::;;$%% 	S,1G1G1M2-N-N-T-T-V-V 	4XXd^^b3,'' 	DIKK",<?S,S,S4   tts$   C. BC. AC. ,C. .
C<;C<c                    t                      sdS t                      } | sdS t          |                     d          pd                                          }|sdS d}	 ddlm}  |            }|                    |          s-	 |(	 |                                 dS # t          $ r Y dS w xY wdS 	 |
                    |          p|}n# t          $ r Y nw xY w||&	 |                                 S # t          $ r Y S w xY wS # t          $ r. Y |(	 |                                 dS # t          $ r Y dS w xY wdS w xY w# |&	 |                                 w # t          $ r Y w w xY ww xY w)a`  Resolve a bare ``-c`` for this terminal, or ``None`` to fall back.

    Returns the breadcrumb's session id only when it still exists in the
    session DB, projected forward through the compression chain so the
    resume lands on the live tip rather than a dead compressed parent
    (same projection as ``main._resolve_session_by_name_or_id``).
    NrF   r]   r   )	SessionDB)r7   re   r   r)   r   hermes_staterg   get_sessioncloser&   get_compression_tip)crumbrF   dbrg   s       r   resolve_breadcrumb_sessionrn      s    << tE tUYY|,,23399;;J t	B******Y[[~~j)) 	 >




    >	//
;;IzJJ 	 	 	D	 >



        >




    > >



    s    %D 	B 
B-,B-3C 
D 
CD CD C44
D D
D=E  D) )
D76D7<D==E   E*EE*
E&#E*%E&&E*)r   r   )r   r   r   r   )r   r   )r   r0   )r8   r   r9   r:   r   r;   )N)rF   r   rG   r   r   r;   )r   r[   )__doc__
__future__r   rT   r#   rer    rQ   pathlibr   typingr   r'   rA   compiler   r   r   r/   r7   rE   rZ   re   rn    r   r   <module>rv      sE     # " " " " "  				 				 



             
  ) rz,--3 3 3 3? ? ? ?
   *   
 
 
 
    8   *# # # # # #r   