From f2c92d40844c5f1321de400ba48fe50178d92551 Mon Sep 17 00:00:00 2001 From: Atish Patel Date: Wed, 5 Aug 2026 16:28:36 -0500 Subject: [PATCH 1/3] feat(agents): default Claude auto-compaction window Set a 200,000-token automatic-compaction default through the environment of Buzz-spawned Claude ACP children. Parent and persona environment values take precedence, preserving user choices without mutating Claude project settings. Co-authored-by: Atish Patel Signed-off-by: Atish Patel --- crates/buzz-acp/src/acp.rs | 39 ++++++++++++++++++++++++++++------- crates/buzz-acp/src/config.rs | 28 ++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/crates/buzz-acp/src/acp.rs b/crates/buzz-acp/src/acp.rs index 93109fa94df..c4082d02f77 100644 --- a/crates/buzz-acp/src/acp.rs +++ b/crates/buzz-acp/src/acp.rs @@ -2970,28 +2970,51 @@ mod tests { #[cfg(unix)] #[tokio::test] async fn spawn_applies_runtime_env_defaults_with_extra_env_precedence() { - const VAR: &str = "HERMES_ACP_SKIP_CONFIGURED_MCP"; - if std::env::var_os(VAR).is_some() { + const HERMES_VAR: &str = "HERMES_ACP_SKIP_CONFIGURED_MCP"; + const CLAUDE_VAR: &str = "CLAUDE_CODE_AUTO_COMPACT_WINDOW"; + if std::env::var_os(HERMES_VAR).is_some() || std::env::var_os(CLAUDE_VAR).is_some() { // Inherited parent values win over both layers; the default and // override behavior below is unobservable in such an environment. return; } assert_eq!( - spawn_named_and_read_child_env("hermes-acp", VAR, &[]).await, + spawn_named_and_read_child_env("hermes-acp", HERMES_VAR, &[]).await, "1", - "Hermes spawns must default {VAR}=1" + "Hermes spawns must default {HERMES_VAR}=1" ); assert_eq!( - spawn_named_and_read_child_env("hermes-acp", VAR, &[(VAR.into(), "0".into())]).await, + spawn_named_and_read_child_env( + "hermes-acp", + HERMES_VAR, + &[(HERMES_VAR.into(), "0".into())] + ) + .await, "0", "an explicit extra_env entry must override the runtime default" ); assert_eq!( - spawn_named_and_read_child_env("other-agent", VAR, &[]).await, - "", - "non-Hermes spawns must not receive Hermes defaults" + spawn_named_and_read_child_env("claude-agent-acp", CLAUDE_VAR, &[]).await, + "200000", + "Claude spawns must default {CLAUDE_VAR}=200000" ); + assert_eq!( + spawn_named_and_read_child_env( + "claude-agent-acp", + CLAUDE_VAR, + &[(CLAUDE_VAR.into(), "300000".into())] + ) + .await, + "300000", + "an explicit extra_env entry must override the runtime default" + ); + for agent in ["goose", "codex-acp", "other-agent"] { + assert_eq!( + spawn_named_and_read_child_env(agent, CLAUDE_VAR, &[]).await, + "", + "non-Claude spawn {agent} must not receive Claude defaults" + ); + } } #[tokio::test] diff --git a/crates/buzz-acp/src/config.rs b/crates/buzz-acp/src/config.rs index d9596858460..38b0b774cec 100644 --- a/crates/buzz-acp/src/config.rs +++ b/crates/buzz-acp/src/config.rs @@ -712,9 +712,17 @@ fn default_agent_args(command: &str) -> Option> { /// startup budget (see block/buzz#3355). Skip that unrelated global startup /// by default; an operator or persona can still opt back in by setting the /// variable explicitly. +/// +/// Claude: set a 200,000-token automatic-compaction window for Buzz-owned +/// children only. Claude Code caps this to the selected model's context +/// capacity. An inherited parent value or explicit persona value wins, so an +/// operator can select a different window without modifying Claude settings. pub(crate) fn default_agent_env(command: &str) -> &'static [(&'static str, &'static str)] { match normalize_agent_command_identity(command).as_str() { "hermes" | "hermes-agent" | "hermes-acp" => &[("HERMES_ACP_SKIP_CONFIGURED_MCP", "1")], + "claude-agent-acp" | "claude-code-acp" | "claude-code" | "claudecode" => { + &[("CLAUDE_CODE_AUTO_COMPACT_WINDOW", "200000")] + } _ => &[], } } @@ -1635,7 +1643,7 @@ mod tests { } #[test] - fn default_agent_env_recognizes_hermes_identities() { + fn default_agent_env_recognizes_runtime_identities() { for command in [ "hermes", "hermes-agent", @@ -1650,10 +1658,24 @@ mod tests { "unexpected env defaults for {command}" ); } - for command in ["goose", "codex-acp", "claude-agent-acp", "buzz-agent", ""] { + for command in [ + "claude-agent-acp", + "claude-code-acp", + "claude-code", + "claudecode", + "/opt/claude/bin/claude-agent-acp", + r"C:\Users\test\AppData\Roaming\npm\CLAUDE-CODE-ACP.cmd", + ] { + assert_eq!( + default_agent_env(command), + &[("CLAUDE_CODE_AUTO_COMPACT_WINDOW", "200000")], + "unexpected env defaults for {command}" + ); + } + for command in ["goose", "codex-acp", "buzz-agent", ""] { assert!( default_agent_env(command).is_empty(), - "non-Hermes command must have no env defaults: {command}" + "unrecognized command must have no env defaults: {command}" ); } } From 84af392b9a9fe8888b94012f774153b7e56c0df8 Mon Sep 17 00:00:00 2001 From: Fast Fizz <3477b86404413a37d7d55365cc85167ad4d52eb8b8b6587df7fd59fc2b6575d8@buzz.block.builderlab.xyz> Date: Wed, 5 Aug 2026 22:06:54 -0500 Subject: [PATCH 2/3] test(desktop): use current attachment label Co-authored-by: Fast Fizz <3477b86404413a37d7d55365cc85167ad4d52eb8b8b6587df7fd59fc2b6575d8@buzz.block.builderlab.xyz> Signed-off-by: Fast Fizz <3477b86404413a37d7d55365cc85167ad4d52eb8b8b6587df7fd59fc2b6575d8@buzz.block.builderlab.xyz> --- desktop/tests/e2e/inbox-edit.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop/tests/e2e/inbox-edit.spec.ts b/desktop/tests/e2e/inbox-edit.spec.ts index e78576d892d..a962056fa65 100644 --- a/desktop/tests/e2e/inbox-edit.spec.ts +++ b/desktop/tests/e2e/inbox-edit.spec.ts @@ -230,7 +230,7 @@ test("editing an immediate attachment reply preserves its media tags", async ({ const detail = page.getByTestId("home-inbox-detail"); await expect(detail).toContainText("Inbox thread root."); - await detail.getByRole("button", { name: "Attach image" }).click(); + await detail.getByRole("button", { name: "Attach file" }).click(); await expect(detail.getByTestId("message-composer")).toContainText( ATTACHMENT_FILENAME, ); From b9b03ff0dddac0899c13b836c92c424d64a138e2 Mon Sep 17 00:00:00 2001 From: Brainy Bumble <0ed7657b57c0e8a9f5288390dd6c8d5d0a3a06abe9b01b9006814f52077d6cdf@buzz.block.builderlab.xyz> Date: Mon, 10 Aug 2026 09:23:52 -0500 Subject: [PATCH 3/3] fix(acp): preserve Claude compaction settings Co-authored-by: Atish Patel Signed-off-by: Atish Patel Signed-off-by: Brainy Bumble <0ed7657b57c0e8a9f5288390dd6c8d5d0a3a06abe9b01b9006814f52077d6cdf@buzz.block.builderlab.xyz> Co-authored-by: Claude Code --- crates/buzz-acp/src/acp.rs | 60 +++++++++++++++++++---------------- crates/buzz-acp/src/config.rs | 25 ++++----------- 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/crates/buzz-acp/src/acp.rs b/crates/buzz-acp/src/acp.rs index c4082d02f77..1cf1282ba2f 100644 --- a/crates/buzz-acp/src/acp.rs +++ b/crates/buzz-acp/src/acp.rs @@ -2969,52 +2969,58 @@ mod tests { /// before `extra_env`, so the later `Command::env` write wins). #[cfg(unix)] #[tokio::test] - async fn spawn_applies_runtime_env_defaults_with_extra_env_precedence() { - const HERMES_VAR: &str = "HERMES_ACP_SKIP_CONFIGURED_MCP"; - const CLAUDE_VAR: &str = "CLAUDE_CODE_AUTO_COMPACT_WINDOW"; - if std::env::var_os(HERMES_VAR).is_some() || std::env::var_os(CLAUDE_VAR).is_some() { - // Inherited parent values win over both layers; the default and - // override behavior below is unobservable in such an environment. + async fn spawn_applies_hermes_env_default_with_extra_env_precedence() { + const VAR: &str = "HERMES_ACP_SKIP_CONFIGURED_MCP"; + if std::env::var_os(VAR).is_some() { + // An inherited parent value wins over both layers, so the default + // and override behavior below is unobservable in this environment. return; } assert_eq!( - spawn_named_and_read_child_env("hermes-acp", HERMES_VAR, &[]).await, + spawn_named_and_read_child_env("hermes-acp", VAR, &[]).await, "1", - "Hermes spawns must default {HERMES_VAR}=1" + "Hermes spawns must default {VAR}=1" ); assert_eq!( - spawn_named_and_read_child_env( - "hermes-acp", - HERMES_VAR, - &[(HERMES_VAR.into(), "0".into())] - ) - .await, + spawn_named_and_read_child_env("hermes-acp", VAR, &[(VAR.into(), "0".into())]).await, "0", "an explicit extra_env entry must override the runtime default" ); assert_eq!( - spawn_named_and_read_child_env("claude-agent-acp", CLAUDE_VAR, &[]).await, - "200000", - "Claude spawns must default {CLAUDE_VAR}=200000" + spawn_named_and_read_child_env("other-agent", VAR, &[]).await, + "", + "non-Hermes spawns must not receive Hermes defaults" + ); + } + + /// Buzz must leave Claude's compaction window unset unless it was supplied + /// by the parent environment or an explicit persona entry. + #[cfg(unix)] + #[tokio::test] + async fn spawn_does_not_default_claude_compaction_window() { + const VAR: &str = "CLAUDE_CODE_AUTO_COMPACT_WINDOW"; + if std::env::var_os(VAR).is_some() { + // An inherited parent value is intentionally forwarded and makes + // the unset behavior below unobservable in this environment. + return; + } + + assert_eq!( + spawn_named_and_read_child_env("claude-agent-acp", VAR, &[]).await, + "", + "Claude spawns must preserve Claude's own effective configuration" ); assert_eq!( spawn_named_and_read_child_env( "claude-agent-acp", - CLAUDE_VAR, - &[(CLAUDE_VAR.into(), "300000".into())] + VAR, + &[(VAR.into(), "300000".into())] ) .await, "300000", - "an explicit extra_env entry must override the runtime default" + "an explicit persona entry must be forwarded" ); - for agent in ["goose", "codex-acp", "other-agent"] { - assert_eq!( - spawn_named_and_read_child_env(agent, CLAUDE_VAR, &[]).await, - "", - "non-Claude spawn {agent} must not receive Claude defaults" - ); - } } #[tokio::test] diff --git a/crates/buzz-acp/src/config.rs b/crates/buzz-acp/src/config.rs index 38b0b774cec..90207e58f43 100644 --- a/crates/buzz-acp/src/config.rs +++ b/crates/buzz-acp/src/config.rs @@ -712,17 +712,9 @@ fn default_agent_args(command: &str) -> Option> { /// startup budget (see block/buzz#3355). Skip that unrelated global startup /// by default; an operator or persona can still opt back in by setting the /// variable explicitly. -/// -/// Claude: set a 200,000-token automatic-compaction window for Buzz-owned -/// children only. Claude Code caps this to the selected model's context -/// capacity. An inherited parent value or explicit persona value wins, so an -/// operator can select a different window without modifying Claude settings. pub(crate) fn default_agent_env(command: &str) -> &'static [(&'static str, &'static str)] { match normalize_agent_command_identity(command).as_str() { "hermes" | "hermes-agent" | "hermes-acp" => &[("HERMES_ACP_SKIP_CONFIGURED_MCP", "1")], - "claude-agent-acp" | "claude-code-acp" | "claude-code" | "claudecode" => { - &[("CLAUDE_CODE_AUTO_COMPACT_WINDOW", "200000")] - } _ => &[], } } @@ -1643,7 +1635,7 @@ mod tests { } #[test] - fn default_agent_env_recognizes_runtime_identities() { + fn default_agent_env_recognizes_hermes_identities() { for command in [ "hermes", "hermes-agent", @@ -1659,23 +1651,18 @@ mod tests { ); } for command in [ + "goose", + "codex-acp", "claude-agent-acp", "claude-code-acp", "claude-code", "claudecode", - "/opt/claude/bin/claude-agent-acp", - r"C:\Users\test\AppData\Roaming\npm\CLAUDE-CODE-ACP.cmd", + "buzz-agent", + "", ] { - assert_eq!( - default_agent_env(command), - &[("CLAUDE_CODE_AUTO_COMPACT_WINDOW", "200000")], - "unexpected env defaults for {command}" - ); - } - for command in ["goose", "codex-acp", "buzz-agent", ""] { assert!( default_agent_env(command).is_empty(), - "unrecognized command must have no env defaults: {command}" + "non-Hermes command must have no env defaults: {command}" ); } }