mirror of
https://github.com/instructkr/claw-code.git
synced 2026-04-06 16:14:49 +08:00
wip: telemetry progress
This commit is contained in:
@@ -64,7 +64,7 @@ impl HookRunner {
|
||||
|
||||
#[must_use]
|
||||
pub fn run_pre_tool_use(&self, tool_name: &str, tool_input: &str) -> HookRunResult {
|
||||
self.run_commands(
|
||||
Self::run_commands(
|
||||
HookEvent::PreToolUse,
|
||||
self.config.pre_tool_use(),
|
||||
tool_name,
|
||||
@@ -82,7 +82,7 @@ impl HookRunner {
|
||||
tool_output: &str,
|
||||
is_error: bool,
|
||||
) -> HookRunResult {
|
||||
self.run_commands(
|
||||
Self::run_commands(
|
||||
HookEvent::PostToolUse,
|
||||
self.config.post_tool_use(),
|
||||
tool_name,
|
||||
@@ -93,7 +93,6 @@ impl HookRunner {
|
||||
}
|
||||
|
||||
fn run_commands(
|
||||
&self,
|
||||
event: HookEvent,
|
||||
commands: &[String],
|
||||
tool_name: &str,
|
||||
@@ -114,19 +113,19 @@ impl HookRunner {
|
||||
"tool_result_is_error": is_error,
|
||||
})
|
||||
.to_string();
|
||||
let invocation = HookInvocation {
|
||||
event,
|
||||
tool_name,
|
||||
tool_input,
|
||||
tool_output,
|
||||
is_error,
|
||||
payload: &payload,
|
||||
};
|
||||
|
||||
let mut messages = Vec::new();
|
||||
|
||||
for command in commands {
|
||||
match self.run_command(
|
||||
command,
|
||||
event,
|
||||
tool_name,
|
||||
tool_input,
|
||||
tool_output,
|
||||
is_error,
|
||||
&payload,
|
||||
) {
|
||||
match Self::run_command(command, &invocation) {
|
||||
HookCommandOutcome::Allow { message } => {
|
||||
if let Some(message) = message {
|
||||
messages.push(message);
|
||||
@@ -149,29 +148,23 @@ impl HookRunner {
|
||||
HookRunResult::allow(messages)
|
||||
}
|
||||
|
||||
fn run_command(
|
||||
&self,
|
||||
command: &str,
|
||||
event: HookEvent,
|
||||
tool_name: &str,
|
||||
tool_input: &str,
|
||||
tool_output: Option<&str>,
|
||||
is_error: bool,
|
||||
payload: &str,
|
||||
) -> HookCommandOutcome {
|
||||
fn run_command(command: &str, invocation: &HookInvocation<'_>) -> HookCommandOutcome {
|
||||
let mut child = shell_command(command);
|
||||
child.stdin(std::process::Stdio::piped());
|
||||
child.stdout(std::process::Stdio::piped());
|
||||
child.stderr(std::process::Stdio::piped());
|
||||
child.env("HOOK_EVENT", event.as_str());
|
||||
child.env("HOOK_TOOL_NAME", tool_name);
|
||||
child.env("HOOK_TOOL_INPUT", tool_input);
|
||||
child.env("HOOK_TOOL_IS_ERROR", if is_error { "1" } else { "0" });
|
||||
if let Some(tool_output) = tool_output {
|
||||
child.env("HOOK_EVENT", invocation.event.as_str());
|
||||
child.env("HOOK_TOOL_NAME", invocation.tool_name);
|
||||
child.env("HOOK_TOOL_INPUT", invocation.tool_input);
|
||||
child.env(
|
||||
"HOOK_TOOL_IS_ERROR",
|
||||
if invocation.is_error { "1" } else { "0" },
|
||||
);
|
||||
if let Some(tool_output) = invocation.tool_output {
|
||||
child.env("HOOK_TOOL_OUTPUT", tool_output);
|
||||
}
|
||||
|
||||
match child.output_with_stdin(payload.as_bytes()) {
|
||||
match child.output_with_stdin(invocation.payload.as_bytes()) {
|
||||
Ok(output) => {
|
||||
let stdout = String::from_utf8_lossy(&output.stdout).trim().to_string();
|
||||
let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
|
||||
@@ -189,8 +182,9 @@ impl HookRunner {
|
||||
},
|
||||
None => HookCommandOutcome::Warn {
|
||||
message: format!(
|
||||
"{} hook `{command}` terminated by signal while handling `{tool_name}`",
|
||||
event.as_str()
|
||||
"{} hook `{command}` terminated by signal while handling `{}`",
|
||||
invocation.event.as_str(),
|
||||
invocation.tool_name
|
||||
),
|
||||
},
|
||||
}
|
||||
@@ -198,13 +192,23 @@ impl HookRunner {
|
||||
Err(error) => HookCommandOutcome::Warn {
|
||||
message: format!(
|
||||
"{} hook `{command}` failed to start for `{tool_name}`: {error}",
|
||||
event.as_str()
|
||||
invocation.event.as_str(),
|
||||
tool_name = invocation.tool_name
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct HookInvocation<'a> {
|
||||
event: HookEvent,
|
||||
tool_name: &'a str,
|
||||
tool_input: &'a str,
|
||||
tool_output: Option<&'a str>,
|
||||
is_error: bool,
|
||||
payload: &'a str,
|
||||
}
|
||||
|
||||
enum HookCommandOutcome {
|
||||
Allow { message: Option<String> },
|
||||
Deny { message: Option<String> },
|
||||
|
||||
Reference in New Issue
Block a user