Sub-classify a shell command by inspecting the command string. Falls back to `Execution` if the command can't be extracted or doesn't match any known pattern.
(
tool_input: Option<&serde_json::Value>,
_tool_output: Option<&str>,
)
| 185 | /// Falls back to `Execution` if the command can't be extracted or doesn't |
| 186 | /// match any known pattern. |
| 187 | fn classify_shell_command( |
| 188 | tool_input: Option<&serde_json::Value>, |
| 189 | _tool_output: Option<&str>, |
| 190 | ) -> NodeKind { |
| 191 | let cmd = extract_command(tool_input); |
| 192 | let cmd = cmd.trim(); |
| 193 | |
| 194 | if cmd.is_empty() { |
| 195 | return NodeKind::Execution; |
| 196 | } |
| 197 | |
| 198 | // Order matters: check test first (most specific), then lint, then build. |
| 199 | // Some commands overlap (e.g., `cargo clippy` is both lint and build-ish). |
| 200 | if is_test_command(cmd) { |
| 201 | return NodeKind::Verification; |
| 202 | } |
| 203 | if is_lint_command(cmd) { |
| 204 | return NodeKind::Verification; |
| 205 | } |
| 206 | if is_typecheck_command(cmd) { |
| 207 | return NodeKind::Verification; |
| 208 | } |
| 209 | if is_build_command(cmd) { |
| 210 | return NodeKind::Verification; |
| 211 | } |
| 212 | |
| 213 | // Read-like shell commands → Exploration |
| 214 | if is_read_command(cmd) { |
| 215 | return NodeKind::Exploration; |
| 216 | } |
| 217 | |
| 218 | NodeKind::Execution |
| 219 | } |
| 220 | |
| 221 | /// Extract the command string from tool input JSON. |
| 222 | /// |
no test coverage detected