@@ -350,13 +350,25 @@ enum PayloadAction {
350350 Ignore ,
351351}
352352
353+ fn claude_payload_input ( v : & Value ) -> Option < ( & Value , & str ) > {
354+ for key in [ "tool_input" , "input" ] {
355+ if let Some ( input) = v. get ( key) {
356+ if let Some ( cmd) = input
357+ . get ( "command" )
358+ . and_then ( |c| c. as_str ( ) )
359+ . filter ( |c| !c. is_empty ( ) )
360+ {
361+ return Some ( ( input, cmd) ) ;
362+ }
363+ }
364+ }
365+
366+ None
367+ }
368+
353369fn process_claude_payload ( v : & Value ) -> PayloadAction {
354- let cmd = match v
355- . pointer ( "/tool_input/command" )
356- . and_then ( |c| c. as_str ( ) )
357- . filter ( |c| !c. is_empty ( ) )
358- {
359- Some ( c) => c,
370+ let ( input, cmd) = match claude_payload_input ( v) {
371+ Some ( ( input, cmd) ) => ( input, cmd) ,
360372 None => return PayloadAction :: Ignore ,
361373 } ;
362374
@@ -378,7 +390,7 @@ fn process_claude_payload(v: &Value) -> PayloadAction {
378390 } ;
379391
380392 let updated_input = {
381- let mut ti = v . get ( "tool_input" ) . cloned ( ) . unwrap_or_else ( || json ! ( { } ) ) ;
393+ let mut ti = input . clone ( ) ;
382394 if let Some ( obj) = ti. as_object_mut ( ) {
383395 obj. insert ( "command" . into ( ) , Value :: String ( rewritten. clone ( ) ) ) ;
384396 }
@@ -1064,6 +1076,18 @@ mod tests {
10641076 . to_string ( )
10651077 }
10661078
1079+ fn claude_current_input_with_fields ( cmd : & str , timeout : u64 , description : & str ) -> String {
1080+ json ! ( {
1081+ "tool" : "Bash" ,
1082+ "input" : {
1083+ "command" : cmd,
1084+ "timeout" : timeout,
1085+ "description" : description
1086+ }
1087+ } )
1088+ . to_string ( )
1089+ }
1090+
10671091 #[ test]
10681092 fn test_claude_rewrite_git_status ( ) {
10691093 let result = run_claude_inner ( & claude_input ( "git status" ) ) . unwrap ( ) ;
@@ -1086,6 +1110,17 @@ mod tests {
10861110 assert_eq ! ( updated[ "description" ] , "Check repo status" ) ;
10871111 }
10881112
1113+ #[ test]
1114+ fn test_claude_rewrite_accepts_current_tool_input_keys ( ) {
1115+ let input = claude_current_input_with_fields ( "grep -r hello ." , 30000 , "Search repo" ) ;
1116+ let result = run_claude_inner ( & input) . unwrap ( ) ;
1117+ let v: Value = serde_json:: from_str ( & result) . unwrap ( ) ;
1118+ let updated = & v[ "hookSpecificOutput" ] [ "updatedInput" ] ;
1119+ assert_eq ! ( updated[ "command" ] , "rtk grep -r hello ." ) ;
1120+ assert_eq ! ( updated[ "timeout" ] , 30000 ) ;
1121+ assert_eq ! ( updated[ "description" ] , "Search repo" ) ;
1122+ }
1123+
10891124 #[ test]
10901125 fn test_claude_passthrough_no_output ( ) {
10911126 assert ! ( run_claude_inner( & claude_input( "htop" ) ) . is_none( ) ) ;
0 commit comments