diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-20 20:42:14 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-20 20:42:14 +0300 |
| commit | f7b26a911772dab16a49d982002d2bbe58e0956b (patch) | |
| tree | 78a24e14adb7cdd5e99b99c6688c84d416e8c5ef /src/integration/mod.rs | |
| parent | 05e44d003962cee6be4e289ac16038a72441ce7e (diff) | |
fix: stop claude subagent completion reviving working
refs #198
Diffstat (limited to 'src/integration/mod.rs')
| -rw-r--r-- | src/integration/mod.rs | 65 |
1 files changed, 46 insertions, 19 deletions
diff --git a/src/integration/mod.rs b/src/integration/mod.rs index ae3756b0..8b6b854c 100644 --- a/src/integration/mod.rs +++ b/src/integration/mod.rs @@ -16,7 +16,7 @@ const PI_INTEGRATION_VERSION: u32 = 1; const PI_CODING_AGENT_DIR_ENV_VAR: &str = "PI_CODING_AGENT_DIR"; const CLAUDE_HOOK_INSTALL_NAME: &str = "herdr-agent-state.sh"; const CLAUDE_HOOK_ASSET: &str = include_str!("assets/claude/herdr-agent-state.sh"); -const CLAUDE_INTEGRATION_VERSION: u32 = 2; +const CLAUDE_INTEGRATION_VERSION: u32 = 3; const CLAUDE_CONFIG_DIR_ENV_VAR: &str = "CLAUDE_CONFIG_DIR"; const CODEX_HOOK_INSTALL_NAME: &str = "herdr-agent-state.sh"; const CODEX_HOOK_ASSET: &str = include_str!("assets/codex/herdr-agent-state.sh"); @@ -591,6 +591,11 @@ pub(crate) fn install_claude() -> io::Result<ClaudeInstallPaths> { "PostToolUseFailure", &format!("bash {quoted_hook_path} working"), )?; + remove_command_hook( + hooks, + "SubagentStop", + &format!("bash {quoted_hook_path} working"), + )?; ensure_command_hook( hooks, "UserPromptSubmit", @@ -614,13 +619,6 @@ pub(crate) fn install_claude() -> io::Result<ClaudeInstallPaths> { )?; ensure_command_hook( hooks, - "SubagentStop", - format!("bash {quoted_hook_path} working"), - 10, - Some("*"), - )?; - ensure_command_hook( - hooks, "Stop", format!("bash {quoted_hook_path} idle"), 10, @@ -1680,10 +1678,7 @@ mod tests { ); assert!(settings["hooks"].get("PostToolUse").is_none()); assert!(settings["hooks"].get("PostToolUseFailure").is_none()); - assert!(settings["hooks"]["SubagentStop"][0]["hooks"][0]["command"] - .as_str() - .unwrap() - .contains(" working")); + assert!(settings["hooks"].get("SubagentStop").is_none()); assert!(settings["hooks"]["Stop"][0]["hooks"][0]["command"] .as_str() .unwrap() @@ -1749,10 +1744,7 @@ mod tests { ); assert!(settings["hooks"].get("PostToolUse").is_none()); assert!(settings["hooks"].get("PostToolUseFailure").is_none()); - assert_eq!( - settings["hooks"]["SubagentStop"].as_array().unwrap().len(), - 1 - ); + assert!(settings["hooks"].get("SubagentStop").is_none()); assert_eq!(settings["hooks"]["Stop"].as_array().unwrap().len(), 1); assert_eq!(settings["hooks"]["SessionEnd"].as_array().unwrap().len(), 1); @@ -1761,7 +1753,7 @@ mod tests { } #[test] - fn install_claude_removes_deprecated_post_tool_hooks_and_preserves_user_hooks() { + fn install_claude_removes_deprecated_completion_hooks_and_preserves_user_hooks() { let _lock = integration_env_lock(); let base = unique_base(); let home = base.join("home"); @@ -1772,7 +1764,8 @@ mod tests { fs::write( claude_dir.join("settings.json"), format!( - r#"{{"hooks":{{"PostToolUse":[{{"matcher":"*","hooks":[{{"type":"command","command":"bash '{}' working","timeout":10}},{{"type":"command","command":"echo keep-post","timeout":10}}]}}],"PostToolUseFailure":[{{"matcher":"*","hooks":[{{"type":"command","command":"bash '{}' working","timeout":10}},{{"type":"command","command":"echo keep-failure","timeout":10}}]}}]}}}}"#, + r#"{{"hooks":{{"PostToolUse":[{{"matcher":"*","hooks":[{{"type":"command","command":"bash '{}' working","timeout":10}},{{"type":"command","command":"echo keep-post","timeout":10}}]}}],"PostToolUseFailure":[{{"matcher":"*","hooks":[{{"type":"command","command":"bash '{}' working","timeout":10}},{{"type":"command","command":"echo keep-failure","timeout":10}}]}}],"SubagentStop":[{{"matcher":"*","hooks":[{{"type":"command","command":"bash '{}' working","timeout":10}},{{"type":"command","command":"echo keep-subagent","timeout":10}}]}}]}}}}"#, + hook_path.display(), hook_path.display(), hook_path.display(), ), @@ -1794,6 +1787,10 @@ mod tests { "echo keep-failure" ); assert_eq!( + settings["hooks"]["SubagentStop"][0]["hooks"][0]["command"], + "echo keep-subagent" + ); + assert_eq!( settings["hooks"]["UserPromptSubmit"] .as_array() .unwrap() @@ -1830,7 +1827,37 @@ mod tests { assert_eq!(claude.path, hook_path); assert_eq!(claude.installed_version, Some(1)); - assert_eq!(claude.expected_version, 2); + assert_eq!(claude.expected_version, 3); + assert_eq!(claude.state, IntegrationStatusKind::Outdated); + + std::env::remove_var("HOME"); + let _ = fs::remove_dir_all(base); + } + + #[test] + fn claude_v2_integration_status_is_outdated() { + let _lock = integration_env_lock(); + let base = unique_base(); + let home = base.join("home"); + let claude_hooks_dir = home.join(".claude").join("hooks"); + fs::create_dir_all(&claude_hooks_dir).unwrap(); + let hook_path = claude_hooks_dir.join(CLAUDE_HOOK_INSTALL_NAME); + fs::write( + &hook_path, + "#!/bin/sh\n# HERDR_INTEGRATION_ID=claude\n# HERDR_INTEGRATION_VERSION=2\n", + ) + .unwrap(); + std::env::set_var("HOME", &home); + + let statuses = installed_integration_statuses(); + let claude = statuses + .iter() + .find(|status| status.target == crate::api::schema::IntegrationTarget::Claude) + .unwrap(); + + assert_eq!(claude.path, hook_path); + assert_eq!(claude.installed_version, Some(2)); + assert_eq!(claude.expected_version, 3); assert_eq!(claude.state, IntegrationStatusKind::Outdated); std::env::remove_var("HOME"); |
