
    `gjj7                    D   d Z ddlmZ ddlZddlmZ ddlmZmZm	Z	 d9dZ
d9dZdd	d
idddddd	d
iddddddddg dddddddddddddddgdddiddiddiddi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,d-dd.d/d0d1d2Zd9d3Zd:d4Zd;d5Zd9d6Zd9d7Zd<d8Zy)=u>  hermes hooks — inspect and manage shell-script hooks.

Usage::

    hermes hooks list
    hermes hooks test <event> [--for-tool X] [--payload-file F]
    hermes hooks revoke <command>
    hermes hooks doctor

Consent records live under ``~/.hermes/shell-hooks-allowlist.json`` and
hook definitions come from the ``hooks:`` block in ``~/.hermes/config.yaml``
(the same config read by the CLI / gateway at startup).

This module is a thin CLI shell over :mod:`agent.shell_hooks`; every
shared concern (payload serialisation, response parsing, allowlist
format) lives there.
    )annotationsN)Path)AnyDictListc                    t        | dd      }|st        d       t        d       y|dv rt        |        y|dk(  rt        |        y|dv rt	        |        y|dk(  rt        |        yt        d	|        y)
uH   Entry point for ``hermes hooks`` — dispatches to the requested action.hooks_actionNz-Usage: hermes hooks {list|test|revoke|doctor}z&Run 'hermes hooks --help' for details.>   lslisttest>   rmremoverevokedoctorzUnknown hooks subcommand: )getattrprint	_cmd_list	_cmd_test_cmd_revoke_cmd_doctor)argssubs     C/root/.hermes/venv/lib/python3.12/site-packages/hermes_cli/hooks.pyhooks_commandr      su    
$
-C=>67
n$	$	*	*D	D*3%01    c                   ddl m} ddlm} |j	                   |             }|s-t        d       t        d       t        d       t        d       y i }|D ]-  }|j                  |j                  g       j                  |       / |j                         }|j                  dg       D ch c]4  }t        |t              r"|j                  d	      |j                  d
      f6 }}t        dt        |       d       t        |j                               D ])  }	t        d|	 d       ||	   D ]  }|j                  |j                   f|v }
|
rdnd}|j"                  rd|j"                  nd}t        d|j                    | d|j$                   d| d       |
so|j'                  |j                  |j                         }|s|j                  d      st        d|d           |j)                  |j                         }|j                  d      }|s|s||kD  st        d| d| d        t                , y c c}w )Nr   load_configshell_hooksz3No shell hooks configured in ~/.hermes/config.yaml.zSee `hermes hooks --help` orz-    website/docs/user-guide/features/hooks.mdz*for the config schema and worked examples.	approvalseventcommandzConfigured shell hooks (z	 total):
  []u   ✓ allowedu   ✗ not allowlistedz	 matcher= z    - z
 (timeout=zs, )approved_atz      approved_at: script_mtime_at_approval.         ⚠ script modified since approval (was , now u.   ) — run `hermes hooks doctor` to re-validate)hermes_cli.configr   agentr    iter_configured_hooksr   
setdefaultr"   appendload_allowlistget
isinstancedictlensortedkeysr#   matchertimeoutallowlist_entry_forscript_mtime_iso)_argsr   r    specsby_eventspec	allowlisteapprovedr"   is_approvedstatusmatcher_partentry	mtime_nowmtime_ats                   r   r   r   3   s4   -!--km<ECD,-=>:; "H 9DJJ+22489 **,I {B/a 
wy)*H  
$SZL

;<( E7!nUO 	D::t||4@K&1]7LF;?<<Yt||&67RL|n 5 LL>VHA7
 #77

DLLQUYY}5/m0D/EFG + < <T\\ JI$yy)CDH X)h2F$$,:VI; ?GH!	* 	/s   *9Iterminalr#   z
echo hellotest-sessionz	test-taskz	test-call)	tool_namer   
session_idtask_idtool_call_idz{"output": "hello"}*   )rK   r   rL   rM   rN   resultduration_mszWhat is the weather?Tzgpt-4cli)rL   user_messageconversation_historyis_first_turnmodelplatform)rL   rV   rW   u#   All done — the change is applied.zsrc/app.tsx)rL   rW   rV   codingattemptfinal_responsechanged_pathsrL   zclaude-sonnet-4-6	anthropiczhttps://api.anthropic.comanthropic_messages         i   i    i   )rL   rM   rW   rV   providerbase_urlapi_modeapi_call_countmessage_count
tool_countapprox_input_tokensrequest_char_count
max_tokensgX9v?stopi   )input_tokensoutput_tokensi  )rL   rM   rW   rV   ra   rb   rc   rd   api_durationfinish_reasonre   response_modelusageassistant_content_charsassistant_tool_call_countzparent-sessz Synthetic summary for hooks test	completedi  )parent_session_id
child_rolechild_summarychild_statusrQ   )pre_tool_callpost_tool_callpre_llm_callpost_llm_call
pre_verifyon_session_starton_session_endon_session_finalizeon_session_resetpre_api_requestpost_api_requestsubagent_stopc                   ddl m} ddlm} ddlm} | j                  }||vr5t        d|       t        ddj                  t        |                    y t        t        j                  |dd	i            }t        | d
d       r| j                  |d<   t        | dd       rt	 t        j                   t#        | j$                        j'                  d            }t)        |t              r|j+                  |       nt        d| j$                   d       |j/                   |             }|D 	cg c]  }	|	j                  |k(  s|	 }}	t        | d
d       r8|D 	cg c]-  }	|	j                  dvs|	j1                  | j                        r|	/ }}	|s5t        d|        t        | d
d       rt        d| j                   d       y t        dt3        |       d| d       |D ]A  }
t        d|
j4                          |j7                  |
|      }t9        |       t                C y # t,        $ r}t        d|        Y d }~y d }~ww xY wc c}	w c c}	w )Nr   r   )VALID_HOOKSr   zUnknown event: zValid events: , rL   rJ   for_toolrK   payload_filezutf-8)encodingz	Warning: z is not a JSON object; ignoringzError reading payload file: >   rx   ry   z%No shell hooks configured for event: z (with matcher filter --for-tool=r'   zFiring z hook(s) for event 'z':
u     → )r,   r   hermes_cli.pluginsr   r-   r    r"   r   joinr6   r4   _DEFAULT_PAYLOADSr2   r   r   jsonloadsr   r   	read_textr3   update	Exceptionr.   matches_toolr5   r#   run_once_print_run_result)r   r   r   r    r"   payloadcustomexcr=   sr?   rP   s               r   r   r      s)   -.!JJEKy)*tyy)<=>?@ $((~0NOPGtZ&#}}t^T*	ZZT%6%6 7 A A7 A STF&$'v&	$"3"3!44STU
 --km<E21E!1Q2E2tZ&
wwAA~~dmm, 
 
 5eW=>4T*4T]]O1EF	GCJ<3E7$
?@ t||n%&%%dG4&!	+  	067	
 3
s+   #A3H) 0II2I)	I
2II
c                p   | j                  d      rt        d| d           y | j                  d      rt        d| d    d       y | j                  d      }| j                  dd      }t        d	| d
| d       | j                  d      xs dj                         }| j                  d      xs dj                         }|rt        dt        |d              |rt        dt        |d              | j                  d      }|r"t        dt	        j
                  |              y t        d       y )Nerroru         ✗ error: 	timed_out         ✗ timed out after elapsed_secondsr   
returncoder   z      exit=z
  elapsed=stdoutr&   stderrz      stdout: i  z      stderr: parsedz"      parsed (Hermes wire shape): uC         parsed: <none — hook contributed nothing to the dispatcher>)r2   r   strip	_truncater   dumps)rP   rcelapsedr   r   r   s         r   r   r      s$   zz'!&/!234zz+*62C+D*EQGH	L	!Bjj*A.G	Kt:gYa
01jj"(b//1Fjj"(b//1Fy5678y5678ZZ!F24::f3E2FGHSTr   c                8    t        |       |k  r| S | d |dz
   dz   S )N   z...)r5   )r   ns     r   r   r     s&    A!137QUe!33r   c                    ddl m} |j                  | j                        }|dk(  rt	        d| j                          y t	        d| d| j                          t	        d       y )Nr   r   z&No allowlist entry found for command: zRemoved z allowlist entry/entries for: zkNote: currently running CLI / gateway processes keep their already-registered callbacks until they restart.)r-   r    r   r#   r   )r   r    removeds      r   r   r     s^    !  .G!|6t||nEF	HWI;DLL>
JK		;r   c                Z   ddl m} ddlm} |j	                   |             }|st        d       y t        dt        |       d       d}|D ]@  }t        d|j                   d|j                          |t        ||      z  }t                B |rt        | d	       y t        d
       y )Nr   r   r   u/   No shell hooks configured — nothing to check.z	Checking z configured shell hook(s)...
r$   z] z4 issue(s) found.  Fix before relying on these hooks.zAll shell hooks look healthy.)
r,   r   r-   r    r.   r   r5   r"   r#   _doctor_one)r<   r   r    r=   problemsr?   s         r   r   r   .  s    -!--km<E?@	Ic%j\!?
@AH DJJ<r$,,01Kk22
 
NOP-.r   c                   d}|j                  | j                        rt        d       n|dz  }t        d       |j                  | j                  | j                        }|r t        d|j                  dd       d       n|dz  }t        d	       |rf|j                  d
      rU|j                  | j                        }|d
   }|r|r||kD  r|dz  }t        d| d| d       n|r|r||k(  rt        d       |st        d       |S |j                  | j                        rt        j                  | j                  di i      }|j                  | |      }|j                  d      r&|dz  }t        d|d    d| j                   d       |S |j                  d      r|dz  }t        d|d           |S |j                  d      }|j                  dd      }	|j                  d      xs dj                         }
|
r*	 t        j                  |
       t        d| d|	 d       |S t        d | d|	 d!       |S # t        j                  $ r' |dz  }t        d| d|	 dt        |
d              Y |S w xY w)"Nr   u)         ✓ script exists and is executabler^   uO         ✗ script missing or not executable (chmod +x the file, or fix the path)u          ✓ allowlisted (approved r(   ?r'   ux         ✗ not allowlisted — hook will NOT fire at runtime (run with --accept-hooks once, or confirm at the TTY prompt)r)   r*   r+   uH   ) — review changes, then `hermes hooks revoke` + re-approve to refreshu)         ✓ script unchanged since approvalu         ℹ skipped JSON smoke test — not allowlisted yet. Approve the hook first (via TTY prompt or --accept-hooks), then re-run `hermes hooks doctor`.extrar   r   r   z s on synthetic payload (timeout=zs)r   u         ✗ execution error: r   r   r&   u9         ✓ produced valid JSON on synthetic payload (exit=r   u*         ✗ stdout was not valid JSON (exit=zs): x   u,         ✓ ran clean with empty stdout (exit=u   s) — hook is observer-only)script_is_executabler#   r   r:   r"   r2   r;   r   r   r9   r   r   r   JSONDecodeErrorr   )r?   r    r   rF   rG   rH   r   rP   r   r   r   s              r   r   r   F  s   H ''59:A 5 	6 ++DJJEE0=#1N0OqQRA M 	N 5600>	34i(&:MH "6) 5GH I 8	X(==>  3 	4< O7 
	)	)$,,	7#''

WbMB%%dG4::k"MH.v6G/H.I J337<<.D E, O) ZZ MH/w/@AB$ O! L)Bjj!2A6Gjj*0b779FDJJv& ##%$b	5 6 O  !d"WI-IK L O ++ DMHFrd"$IT)FC*@)AC D ODs   'H? ?6I98I9)returnNone)rP   zDict[str, Any]r   r   )r   strr   intr   r   )r   r   )__doc__
__future__r   r   pathlibr   typingr   r   r   r   r   r   r   r   r   r   r   r    r   r   <module>r      sr  $ #   " "221~  L)$#  L)$#' %. " % %?' &~6#^4(.9%~6$$/(#"  %$/(-"&=#'%&$ +;#WR j2jU44$/0Dr   