
    #jr                     d   d 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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  ej        e          ZdZ ej        d	          Zd
ZdZdZdZdefdZdee         fdZ dee         ddfdZ!efdee"         de#ddfdZ$dDdee%         de&e#e#f         fdZ'dEdZ(dZ)dZ*de"dee"         fdZ+de"de,fdZ-efdee"         de#fdZ.de"de"fd Z/dFde"d"e#de"fd#Z0dFde"d"e#de"fd$Z1e
 G d% d&                      Z2d'e"dee         fd(Z3d'e"dee         fd)Z4d*e"de"fd+Z5ed,d-d'e"d.e#d/e#d0e,de2f
d1Z6d,d2d3e#d0e,dee"e2f         fd4Z7de"fd5Z8d6d7dd8d3e#d9e"d:eee"e2f                  de"fd;Z9e
 G d< d=                      Z:d6d!d,d>d3e#d?e#d0e,de:fd@Z;dA Z<dB Z=dC Z>dS )GaU  ``hermes debug`` debug tools for Hermes Agent.

Currently supports:
    hermes debug share    Upload debug report (system info + logs) to a
                          paste service and print a shareable URL.
                          By default, log content is run through
                          ``agent.redact.redact_sensitive_text`` with
                          ``force=True`` before upload so credentials in
                          ``~/.hermes/logs/*.log`` are not leaked into
                          the public paste service. Pass ``--no-redact``
                          to disable.
    N)	dataclass)Path)Optionalget_hermes_home)atomic_replacez[[hermes debug share: log content redacted at upload time. run with --no-redact to disable]
zW(?<![A-Za-z0-9._%+-])[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}(?![A-Za-z0-9._%+-])https://paste.rs/zhttps://dpaste.com/api/i  i`T  returnc                  *    t                      dz  dz  S )aZ  Path to ``~/.hermes/pastes/pending.json``.

    Each entry: ``{"url": "...", "expire_at": <unix_ts>}``.  Scheduled
    DELETEs used to be handled by spawning a detached Python process per
    paste that slept for 6 hours; those accumulated forever if the user
    ran ``hermes debug share`` repeatedly.

    Deletion is now driven by the gateway's cron ticker
    (``gateway/run.py::_start_cron_ticker``) which calls
    ``_sweep_expired_pastes`` once per hour.  ``hermes debug share`` also
    runs an opportunistic sweep on entry as a fallback for CLI-only users
    who never start the gateway.
    pasteszpending.jsonr        5/home/ubuntu/.hermes/hermes-agent/hermes_cli/debug.py_pending_filer   @   s     x'.88r   c                  (   t                      } |                                 sg S 	 t          j        |                     d                    }t          |t                    rd |D             S n"# t          t          t          j	        f$ r Y nw xY wg S )Nutf-8encodingc                 L    g | ]!}t          |t                    r
d |v d|v |"S url	expire_at)
isinstancedict.0es     r   
<listcomp>z!_load_pending.<locals>.<listcomp>Y   sG       a&&+0A::+:J:J :J:J:Jr   )
r   existsjsonloads	read_textr   listOSError
ValueErrorJSONDecodeError)pathdatas     r   _load_pendingr)   Q   s    ??D;;== 		z$..'.::;;dD!! 	    	 Z!56   Is   AA0 0BBentriesc                    t                      }	 |j                            dd           |                    d          }|                    t          j        | d          d           t          ||           d S # t          $ r Y d S w xY w)NT)parentsexist_okz	.json.tmp   )indentr   r   )	r   parentmkdirwith_suffix
write_textr    dumpsr   r$   )r*   r'   tmps      r   _save_pendingr6   b   s    ??D$666{++tz'!444wGGGsD!!!!!    	s   A,A> >
BBurlsdelay_secondsc                 8   d | D             }|sdS t                      }d |D             }t          j                    |z   }|D ])}t          ||                    |d                    ||<   *d |                                D             }t          |           dS )zRecord *urls* for deletion at ``now + delay_seconds``.

    Only paste.rs URLs are recorded (dpaste.com auto-expires).  Entries
    are merged into any existing pending.json.
    c                 0    g | ]}t          |          |S r   )_extract_paste_id)r   us     r   r   z#_record_pending.<locals>.<listcomp>u   s&    ===1(9!(<(<=Q===r   Nc                 F    i | ]}|d          t          |d                   S r   )floatr   s     r   
<dictcomp>z#_record_pending.<locals>.<dictcomp>{   s*    QQQA%%+*?*?QQQr   g        c                     g | ]
\  }}||d S )r   r   )r   r<   tss      r   r   z#_record_pending.<locals>.<listcomp>   s$    FFFeaab))FFFr   )r)   timemaxgetitemsr6   )r7   r8   paste_rs_urlsr*   by_urlr   r<   mergeds           r   _record_pendingrI   o   s     >====M ooGQQQQQF	m+I 7 7	6::a#5#566q		FFv||~~FFFF&r   nowc                    t                      }|sdS | t          j                    n| }d}g }|D ]}	 t          |                    dd                    }n# t          t
          f$ r Y :w xY w||k    r|                    |           Z|                    dd          }	 t          |          r|dz  }n# t          $ r Y nw xY w|dz   |k    r|                    |           |dz  }|rt          |           |t          |          fS )	u9  Synchronously DELETE any pending pastes whose ``expire_at`` has passed.

    Returns ``(deleted, remaining)``.  Best-effort: failed deletes stay in
    the pending file and will be retried on the next sweep.  Silent —
    intended to be called from every ``hermes debug`` invocation with
    minimal noise.
    )r   r   Nr   r   r       iQ )r)   rB   r>   rD   	TypeErrorr%   appenddelete_paste	Exceptionr6   len)rJ   r*   currentdeleted	remainingentryr   r   s           r   _sweep_expired_pastesrW      sg    ooG v [dikkkcGGI  	eiiQ7788II:& 	 	 	H	wU###iir""	C   1  	 	 	 D	 uw&&U####qLGG !i   S^^$$s#   #AA+*A+!B77
CCc                  F    	 t                       dS # t          $ r Y dS w xY w)zBAttempt pending-paste cleanup without letting /debug fail offline.N)rW   rQ   r   r   r   !_best_effort_sweep_expired_pastesrY      s;       s    
  u  ⚠️  This will upload the following to a public paste service:
  • System info (OS, Python version, Hermes version, provider, which API keys
    are configured — NOT the actual keys)
  • Recent log lines (agent.log, errors.log, gateway.log, desktop.log — may
    contain conversation fragments and file paths)
  • Full agent.log, gateway.log, and desktop.log (up to 512 KB each — likely
    contains conversation content, tool outputs, and file paths)

Pastes auto-delete after 6 hours.
u  ⚠️ **Privacy notice:** This uploads system info + recent log tails (may contain conversation fragments) to a public paste service. Full logs are NOT included from the gateway — use `hermes debug share` from the CLI for full log uploads.
Pastes auto-delete after 6 hours.r   c                     |                                                      d          } dD ]0}|                     |          r| t          |          d         c S 1dS )zExtract the paste ID from a paste.rs or dpaste.com URL.

    Returns the ID string, or None if the URL doesn't match a known service.
    /)r	   zhttp://paste.rs/N)striprstrip
startswithrR   )r   prefixs     r   r;   r;      sg    
 ))++

S
!
!C; % %>>&!! 	%s6{{||$$$$	%4r   c                 F   t          |           }|st          d|            t           | }t          j                            |dddi          }t          j                            |d          5 }d|j        cxk    od	k     nc cd
d
d
           S # 1 swxY w Y   d
S )zDelete a paste from paste.rs.  Returns True on success.

    Only paste.rs supports unauthenticated DELETE.  dpaste.com pastes
    expire automatically but cannot be deleted via API.
    z7Cannot delete: only paste.rs URLs are supported.  Got: DELETE
User-Agenthermes-agent/debug-share)methodheaders   timeout   i,  N)r;   r%   _PASTE_RS_URLurllibrequestRequesturlopenstatus)r   paste_idtargetreqresps        r   rP   rP      s    !%%H 
KcKK
 
 	
 )x))F
.
 
 x9: !  C 
		R		0	0 (Ddk''''C''''( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (s   4BBBc                 (    t          | |           dS )u  Record *urls* for deletion ``delay_seconds`` from now.

    Previously this spawned a detached Python subprocess per call that slept
    for 6 hours and then issued DELETE requests.  Those subprocesses leaked —
    every ``hermes debug share`` invocation added ~20 MB of resident Python
    interpreters that never exited until the sleep completed.

    The replacement is stateless: we append to ``~/.hermes/pastes/pending.json``
    and the gateway's cron ticker sweeps expired entries once per hour.
    ``hermes debug share`` also runs an opportunistic sweep as a fallback
    for CLI-only users.  If neither runs again, paste.rs's own retention
    policy handles cleanup.
    )r8   N)rI   )r7   r8   s     r   _schedule_auto_deleteru      s     D666666r   contentc                    |                      d          }t          j                            t          |dddd          }t          j                            |d          5 }|                                                    d                                          }d	d	d	           n# 1 swxY w Y   |	                    d
          st          d|d	d                    |S )zvUpload to paste.rs.  Returns the paste URL.

    paste.rs accepts a plain POST body and returns the URL directly.
    r   POSTztext/plain; charset=utf-8rc   zContent-Typerb   r(   rd   re   rf   rg   Nhttpz#Unexpected response from paste.rs: ri   )encoderk   rl   rm   rj   rn   readdecoder\   r^   r%   )rv   r(   rr   rs   r   s        r   _upload_paste_rsr     s   
 >>'""D
.
 
 D74
 
 !  C 
		R		0	0 2Diikk  ))//112 2 2 2 2 2 2 2 2 2 2 2 2 2 2>>&!! LJs4C4yJJKKKJs   ":B((B,/B,   expiry_daysc                 z   ddt           dt           dt           ffd} |d|            |dd          z    |d	t          |                    z   d
 dz                       d          }t          j                            t
          |dd dd          }t          j                            |d          5 }|                                                    d          	                                }ddd           n# 1 swxY w Y   |
                    d          st          d|dd                    |S )z\Upload to dpaste.com.  Returns the paste URL.

    dpaste.com uses multipart form data.
    z----HermesDebugBoundary9f3cnamevaluer
   c                     d d|  d| dS )N--z(
Content-Disposition: form-data; name="z"

z
r   )r   r   boundarys     r   _fieldz"_upload_dpaste_com.<locals>._field   s:      59    	
r   rv   syntaxtextr   r   z--
r   rx   zmultipart/form-data; boundary=rc   ry   rz   rf   rg   Nr{   z%Unexpected response from dpaste.com: ri   )strr|   rk   rl   rm   _DPASTE_COM_URLrn   r}   r~   r\   r^   r%   )rv   r   r   bodyrr   rs   r   r   s          @r   _upload_dpaste_comr     s   
 -H
S 
 
 
 
 
 
 
 
 	y'""
&6
"
"	#
&K 0 0
1
1	2  x


	  fWoo 	 .
 
 d6GXGG4
 
 !  C 
		R		0	0 2Diikk  ))//112 2 2 2 2 2 2 2 2 2 2 2 2 2 2>>&!! NLTcTLLMMMJs   ;:DDDc                 P   g }	 t          |           S # t          $ r"}|                    d|            Y d}~nd}~ww xY w	 t          | |          S # t          $ r"}|                    d|            Y d}~nd}~ww xY wt	          dd                    |          z             )zUpload *content* to a paste service, trying paste.rs then dpaste.com.

    Returns the paste URL on success, raises on total failure.
    z
paste.rs: Nr   zdpaste.com: z)Failed to upload to any paste service:
  z
  )r   rQ   rO   r   RuntimeErrorjoin)rv   r   errorsexcs       r   upload_to_pastebinr   =  s    
 F*((( * * *(3(())))))))*,!'{CCCC , , ,*S**++++++++, 4v{{67J7JJ  s(    
?:?A 
B A;;B c                   J    e Zd ZU dZee         ed<   eed<   ee         ed<   dS )LogSnapshotz7Single-read snapshot of a log file used by debug-share.r'   	tail_text	full_textN)__name__
__module____qualname____doc__r   r   __annotations__r   r   r   r   r   r   Z  sA         AA
4.NNN}r   r   log_namec                 h    ddl m} |                    |           }|rt                      dz  |z  ndS )z@Where *log_name* would live if present. Doesn't check existence.r   )	LOG_FILESlogsN)hermes_cli.logsr   rD   r   )r   r   filenames      r   _primary_log_pathr   c  sE    ))))))}}X&&H6>HO&11DHr   c                    t          |           }|dS |                                r|                                j        dk    r|S |j        |j         dz  }|                                r|                                j        dk    r|S dS )zFind the log file for *log_name*, falling back to the .1 rotation.

    Returns the first non-empty candidate (primary, then .1), or None.
    Callers distinguish 'empty primary' from 'truly missing' via
    :func:`_primary_log_path`.
    Nr   z.1)r   r   statst_sizer0   r   )r   primaryrotateds      r   _resolve_log_pathr   k  s      ))Gt~~ GLLNN2Q66n',2222G~~ GLLNN2Q664r   r   c                 f    | s| S ddl m}  || d          } t                              d|           S )a  Run ``redact_sensitive_text`` with ``force=True`` over upload-bound text.

    Uses ``force=True`` so redaction fires regardless of the operator's
    ``security.redact_secrets`` setting. The local on-disk log file is
    not modified; only the in-memory copy headed for the public paste
    service is sanitized. Returns the redacted text (or the original
    when empty / non-string).
    r   )redact_sensitive_textT)forcez[REDACTED_EMAIL])agent.redactr   _EMAIL_ADDRESS_REsub)r   r   s     r   _redact_log_textr     sO      222222  T222D  !3T:::r   T)	max_bytesredact
tail_linesr   r   c                   t          |           }|;t          |           }|r|                                rdnd}t          d|d          S 	 |                                j        }|dk    rt          |dd          S t          |d          5 }||k    r|                                }	d}
nd}|}g }d}d}|dk    r||k     s	||d	z   k    r||d
z  k     rt          ||          }||z  }|	                    |           |                    |          }|
                    d|           |t          |          z  }||                    d          z  }t          |d
z  d          }|dk    r||k     s	||d	z   k    r	||d
z  k     d                    |          }	|dk    }
ddd           n# 1 swxY w Y   |	}|
rht          |          |k    rUt          |          |z
  }|dk    o||d	z
  |         dk    }||d         }|s d|v r|                    dd	          d	         }|	                    dd          }d                    |                    d          | d                                       d          }|                    dd          }|
rd|dz   d| }|rt%          |          }t%          |          }t          |||          S # t&          $ r }t          |d| dd          cY d}~S d}~ww xY w)aM  Capture a log once and derive summary/full-log views from it.

    The report tail and standalone log upload must come from the same file
    snapshot. Otherwise a rotation/truncate between reads can make the report
    look newer than the uploaded ``agent.log`` paste.

    When ``redact`` is True (the default), both ``tail_text`` and
    ``full_text`` are run through ``_redact_log_text`` so the snapshot
    returned is upload-safe. The on-disk log file is never modified.
    Pass ``redact=False`` to capture original log content (used by
    ``hermes debug share --no-redact``).
    Nz(file empty)z(file not found))r'   r   r   r   rbFi    rM   r.      
i   r   r   replace)r   rL   T)keepends
u!   [... truncated — showing last ~i   zKB ...]
z(error reading: ))r   r   r   r   r   r   openr}   minseekinsertrR   countr   splitr~   
splitlinesr]   r   rQ   )r   r   r   r   log_pathr   tailsizefraw	truncated
chunk_sizeposchunkstotalnewline_count	read_sizechunkfull_rawcuton_boundaryall_textr   r   r   s                            r   _capture_log_snapshotr     s   & !**H#H--!(UW^^-=-=U~~CUEEEE:_}}&199HRVWWWW(D!! 	$Qy  ffhh!		
 "
&( !Agg59#4#4VW8W8W]benqrer]r]r #J 4 4I9$CFF3KKKFF9--EMM!U+++SZZ'E!U[[%7%77M!$Z!^U!;!;J Agg59#4#4VW8W8W]benqrer]r]r hhv&&!G	3	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$6  		7X22h--)+C
 'FhsQw}&=&FK~H 75H#4#4#>>%33A6::gi:88GGH///>>
{||LMMTTUYZZ	OOGIO>>	 	dcI<MccXaccI 	4(33I(33IISSSS _ _ _4Ms4M4M4MY]^^^^^^^^^_sJ   0K ?K DF, K ,F00K 3F04D K 
K?K:4K?:K?r   	log_linesc                    t          | d          }t          d| |          t          d||          t          d||          t          d||          dS )zCapture all logs used by debug-share exactly once.

    ``redact`` is forwarded to each ``_capture_log_snapshot`` call so all
    captured logs share the same redaction policy for a given run.
    d   agent)r   r   r   gatewaydesktop)r   r   r   r   )r   r   )r   r   errors_liness      r   _capture_default_log_snapshotsr     s     y#&&L&	&
 
 
 (f
 
 
 ),v
 
 
 ),v
 
 
  r   c                  ,   ddl m}   G d d          }t          j        }t	          j                    xt          _        }	  |  |                       n# t          $ r Y nw xY w|t          _        n# |t          _        w xY w|                                S )z6Run ``hermes dump`` and return its stdout as a string.r   )run_dumpc                       e Zd ZdZdS ) _capture_dump.<locals>._FakeArgsFN)r   r   r   	show_keysr   r   r   	_FakeArgsr     s        			r   r   )hermes_cli.dumpr   sysstdoutioStringIO
SystemExitgetvalue)r   r   
old_stdoutcaptures       r   _capture_dumpr     s    ((((((        J;==(CJ      

Z
s*    A A1 
A!A1  A!!A1 1A?ri   rL   r   	dump_textlog_snapshotsr   r   c                 v   t          j                    }|st                      }|                    |           |t	          |           }|                    d           |                    d|  d           |                    |d         j                   |                    d           t          | d          }|                    d| d           |                    |d         j                   |                    d           |                    d	| d           |                    |d
         j                   |                    d           |                    d| d           |                    |d         j                   |                    d           |                                S )aI  Build the summary debug report: system dump + log tails.

    Parameters
    ----------
    log_lines
        Number of recent lines to include per log file.
    dump_text
        Pre-captured dump output.  If empty, ``hermes dump`` is run
        internally.

    Returns the report as a plain-text string ready for upload.
    N

z--- agent.log (last z lines) ---
r   r   z--- errors.log (last r   z--- gateway.log (last r   z--- desktop.log (last r   r   )r   r   r   writer   r   r   r   )r   r   r   bufr   s        r   collect_debug_reportr     s   $ +--C $!OO	IIi6yAA IIfII=Y===>>>IImG$.///IIfy#&&LIIAlAAABBBIImH%/000IIfIIB|BBBCCCIImI&0111IIfIIB|BBBCCCIImI&0111IIdOOO<<>>r   c                   J    e Zd ZU dZeed<   eed<   eed<   eed<   dZ	e
ed<   dS )	DebugShareResultzStructured outcome of a ``debug share`` upload.

    Returned by :func:`build_debug_share` so non-CLI callers (the dashboard
    web server, gateway) can render the uploaded paste URLs as real links
    instead of scraping printed text.
    r7   failuresredactedauto_delete_secondsrL   reportN)r   r   r   r   r   r   r#   boolintr   r   r   r   r   r   r   L  sU           JJJNNNNNNFCr   r   r   expiryr   r   c                    t                       t                      }t          | |          }|rt                              d           t          | ||          }|d         j        }|d         j        }|d         j        }|r|dz   |z   }|r|dz   |z   }|r|d	z   |z   }|r.t          |z   }|r
t          |z   }|r
t          |z   }|r
t          |z   }i }	g }
t          ||
          |	d<   d|fd|fd|ffD ]N\  }}|s	 t          ||
          |	|<   # t          $ r$}|

                    | d|            Y d}~Gd}~ww xY wt          t          |	                                                     t          |	|
|t          |          S )u  Collect the debug report + full logs, upload each, return the URLs.

    This is the shared core behind ``hermes debug share`` (CLI) and the
    dashboard ``POST /api/ops/debug-share`` endpoint. It performs blocking
    network I/O (paste uploads) — callers inside an event loop must run it in
    a worker thread.

    The summary report upload is required: on failure this raises
    ``RuntimeError``. Full-log uploads are best-effort; their errors are
    collected into ``failures`` rather than raised.
    r   zOhermes debug share: applied force-mode redaction to log snapshots before uploadr   r   r   r   

--- full agent.log ---


--- full gateway.log ---


--- full desktop.log ---
r   Reportz	agent.logzgateway.logzdesktop.log: N)r7   r   r   r   r   )rY   r   r   loggerinfor   r   _REDACTION_BANNERr   rQ   rO   ru   r#   valuesr   _AUTO_DELETE_SECONDS)r   r   r   r   r   r   	agent_loggateway_logdesktop_logr7   r   labelrv   r   s                 r   build_debug_sharer  \  s<   " &''' I29VLLLM 
]	
 	
 	
 "#  F
 g&0I	*4K	*4K  K >>J	 Q"BB[P Q"BB[P  :"V+ 	6)I5I 	:+k9K 	:+k9KDH (FCCCDN 
i 	$	$ 
/ 
/w
  		/,W&IIIDKK 	/ 	/ 	/OOu----........	/ $t{{}}--...0   s   =D
E D;;E c                    t          | dd          }t          | dd          }t          | dd          }t          | dd           }|r)t                       t          d           t                      }t	          ||	          }t          |||
          }|d         j        }|d         j        }	|d         j        }
|r|dz   |z   }|	r|dz   |	z   }	|
r|dz   |
z   }
|r.t          |z   }|r
t          |z   }|	r
t          |	z   }	|
r
t          |
z   }
t          |           d|fd|	fd|
ffD ]I\  }}|rBt          dd            t          |           t          d d           t          |           JdS t          t                     t          d           t          d           	 t          |||          }nX# t          $ rK}t          d| t          j                   t          d           t          j        d           Y d}~nd}~ww xY wt          d |j        D                       }t          d           |j                                        D ]\  }}t          d |d!| d |            |j        r+t          d"d#                    |j                   d$           |j        d%z  }t          d&| d'           t          d(           t          d)           dS )*z:Collect debug report + full logs, upload each, print URLs.linesri   expirer   localF	no_redactzCollecting debug report...r   r   r   r   r   r  r  r  zFULL agent.logzFULL gateway.logzFULL desktop.logr   z<============================================================r   NzUploading...r   z
Upload failed: )filez?
Run `hermes debug share --local` to print the report instead.
rM   c              3   4   K   | ]}t          |          V  d S N)rR   )r   ks     r   	<genexpr>z"run_debug_share.<locals>.<genexpr>  s(      22c!ff222222r   z
Debug report uploaded:z  <z
  (failed to upload: z, r   i  u!   
⏱  Pastes will auto-delete in z hours.z)To delete now:  hermes debug delete <url>z4
Share these links with the Hermes team for support.)getattrrY   printr   r   r   r   r	  _PRIVACY_NOTICEr  r   r   stderrexitrC   r7   rE   r   r   r   )argsr   r   
local_onlyr   r   r   r   r  r  r  titler   resultr   label_widthr  r   hourss                      r   run_debug_sharer'    s   gs++IT8Q''Fw..J{E222F ( 	*+++*+++!OO	6yPPP%'
 
 

 "'*4	#I.8#I.8 	O!$BBYNI 	U#&FFTK 	U#&FFTK 	>&/F :-	9	 >/+= >/+=fy)--
 		 		KE4
  'X''(((eooo&&&d	/	
&'''	.	"
 
 

    '#''cj9999QRRR 22fk22222K	
%&&&k'')) 2 2
s050;00003001111 GE		&/(B(BEEEFFF&$.E	
=u
=
=
=>>> 

6777	
BCCCCCs   %F8 8
HAHHc                    t          | dg           }|s t          d           t          d           dS |D ]}	 t          |          }|rt          d|            nt          d| d           ;# t          $ r}t          d|            Y d}~\d}~wt          $ r}t          d	| d
|            Y d}~d}~ww xY wdS )z1Delete one or more paste URLs uploaded by /debug.r7   z,Usage: hermes debug delete <url> [<url> ...]z;  Deletes paste.rs pastes uploaded by 'hermes debug share'.Nu     ✓ Deleted: u     ✗ Failed to delete: z (unexpected response)u     ✗ u     ✗ Could not delete r  )r  r  rP   r%   rQ   )r!  r7   r   okr   s        r   run_debug_deleter*    s-   4$$D <===KLLL 
: 
:		:c""B N---....LLLLMMM 	" 	" 	".3..!!!!!!!! 	: 	: 	:8C8838899999999	:
: 
:s#   7A11
B>;BB>B99B>c                 b   	 t                       n# t          $ r Y nw xY wt          | dd          }|dk    rt          |            dS |dk    rt	          |            dS t          d           t                       t          d           t          d           t          d           t                       t          d	           t          d
           t          d           t          d           t          d           t                       t          d           t          d           dS )zRoute debug subcommands.debug_commandNsharedeletezUsage: hermes debug <command>z	Commands:z?  share    Upload debug report to a paste service and print URLz-  delete   Delete a previously uploaded pastezOptions (share):z<  --lines N    Number of log lines to include (default: 200)z0  --expire N   Paste expiry in days (default: 7)z8  --local      Print report locally instead of uploadingzE  --no-redact  Disable upload-time secret redaction (default: redact)zOptions (delete):z/  <url> ...    One or more paste URLs to delete)rW   rQ   r  r'  r*  r  )r!  subcmds     r   	run_debugr0    sN       T?D11F	8		 	-...kOPPP=>>> !!!LMMM@AAAHIIIUVVV!"""?@@@@@s    
r  )r
   N)r   )?r   r   r    loggingrer   rB   urllib.requestrk   dataclassesr   pathlibr   typingr   hermes_constantsr   utilsr   	getLoggerr   r  r	  compiler   rj   r   _MAX_LOG_BYTESr  r   r#   r   r)   r6   r   r   rI   r>   tuplerW   rY   r  _GATEWAY_PRIVACY_NOTICEr;   r   rP   ru   r   r   r   r   r   r   r   r   r   r   r   r   r  r'  r*  r0  r   r   r   <module>r>     s    
			   				 



      ! ! ! ! ! !             , , , , , ,            		8	$	$) 
 BJ   $+   9t 9 9 9 9"tDz    "
4: 
$ 
 
 
 
 ;O  $s) C SW    (,% ,%x ,%%S/ ,% ,% ,% ,%^   
( 	3 	8C= 	 	 	 	(c (d ( ( ( (* AU 7 7S	 7# 7 7 7 7"c c    (! ! !# !c ! ! ! !H  # c    :        I I I I I I     *;3 ;3 ; ; ; ;* $S_ S_ S_S_ S_ 	S_
 S_ S_ S_ S_ S_n '+  #	#{
   :s    * 6:	. . .. . Dk!123	.
 	. . . .j        " 	W W WW W 	W
 W W W WtOD OD ODd: : :* A  A  A  A  Ar   