mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-11 12:03:31 +08:00
feat: add ecc2 harness compatibility env
This commit is contained in:
@@ -3018,6 +3018,7 @@ fn build_agent_command(
|
||||
if let Some(runner) = cfg.harness_runner(&SessionHarnessInfo::runner_key(agent_type)) {
|
||||
return build_configured_harness_command(
|
||||
runner,
|
||||
agent_type,
|
||||
agent_program,
|
||||
task,
|
||||
session_id,
|
||||
@@ -3028,7 +3029,7 @@ fn build_agent_command(
|
||||
|
||||
let task = normalize_task_for_harness(harness, task, profile);
|
||||
let mut command = Command::new(agent_program);
|
||||
command.env("ECC_SESSION_ID", session_id);
|
||||
apply_shared_harness_runtime_env(&mut command, agent_type, session_id, working_dir, profile);
|
||||
match harness {
|
||||
HarnessKind::Claude => {
|
||||
command
|
||||
@@ -3125,6 +3126,7 @@ fn build_agent_command(
|
||||
|
||||
fn build_configured_harness_command(
|
||||
runner: &crate::config::HarnessRunnerConfig,
|
||||
agent_type: &str,
|
||||
agent_program: &Path,
|
||||
task: &str,
|
||||
session_id: &str,
|
||||
@@ -3132,7 +3134,7 @@ fn build_configured_harness_command(
|
||||
profile: Option<&SessionAgentProfile>,
|
||||
) -> Command {
|
||||
let mut command = Command::new(agent_program);
|
||||
command.env("ECC_SESSION_ID", session_id);
|
||||
apply_shared_harness_runtime_env(&mut command, agent_type, session_id, working_dir, profile);
|
||||
for (key, value) in &runner.env {
|
||||
if !value.trim().is_empty() {
|
||||
command.env(key, value);
|
||||
@@ -3211,6 +3213,52 @@ fn build_configured_harness_command(
|
||||
command
|
||||
}
|
||||
|
||||
fn apply_shared_harness_runtime_env(
|
||||
command: &mut Command,
|
||||
agent_type: &str,
|
||||
session_id: &str,
|
||||
working_dir: &Path,
|
||||
profile: Option<&SessionAgentProfile>,
|
||||
) {
|
||||
let harness_label = SessionHarnessInfo::runner_key(agent_type);
|
||||
command.env("ECC_SESSION_ID", session_id);
|
||||
command.env("ECC_HARNESS", &harness_label);
|
||||
command.env("ECC_WORKING_DIR", working_dir);
|
||||
command.env("ECC_PROJECT_DIR", working_dir);
|
||||
command.env("CLAUDE_SESSION_ID", session_id);
|
||||
command.env("CLAUDE_PROJECT_DIR", working_dir);
|
||||
command.env("CLAUDE_CODE_ENTRYPOINT", "cli");
|
||||
if let Some(model) = profile.and_then(|profile| profile.model.as_ref()) {
|
||||
command.env("CLAUDE_MODEL", model);
|
||||
}
|
||||
if let Some(plugin_root) = resolve_ecc_plugin_root() {
|
||||
command.env("ECC_PLUGIN_ROOT", &plugin_root);
|
||||
command.env("CLAUDE_PLUGIN_ROOT", &plugin_root);
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_ecc_plugin_root() -> Option<PathBuf> {
|
||||
let mut seeds = Vec::new();
|
||||
if let Ok(current_exe) = std::env::current_exe() {
|
||||
seeds.push(current_exe);
|
||||
}
|
||||
seeds.push(PathBuf::from(env!("CARGO_MANIFEST_DIR")));
|
||||
|
||||
for seed in seeds {
|
||||
for candidate in seed.ancestors() {
|
||||
if is_ecc_plugin_root(candidate) {
|
||||
return Some(candidate.to_path_buf());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn is_ecc_plugin_root(candidate: &Path) -> bool {
|
||||
candidate.join("scripts/lib/utils.js").is_file() && candidate.join("hooks/hooks.json").is_file()
|
||||
}
|
||||
|
||||
fn normalize_task_for_harness(
|
||||
harness: HarnessKind,
|
||||
task: &str,
|
||||
@@ -4246,6 +4294,24 @@ mod tests {
|
||||
"System instructions:\nReview thoroughly.\n\nECC execution profile:\n- Allowed tools: Read\n- Disallowed tools: Bash\n- Permission mode: plan\n- Max budget USD: 1.25\n- Token budget: 750\n\nTask:\nreview this change",
|
||||
]
|
||||
);
|
||||
|
||||
let envs = command_env_map(&command);
|
||||
assert_eq!(envs.get("ECC_SESSION_ID"), Some(&"sess-1234".to_string()));
|
||||
assert_eq!(
|
||||
envs.get("CLAUDE_SESSION_ID"),
|
||||
Some(&"sess-1234".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
envs.get("CLAUDE_PROJECT_DIR"),
|
||||
Some(&"/tmp/repo".to_string())
|
||||
);
|
||||
assert_eq!(envs.get("CLAUDE_CODE_ENTRYPOINT"), Some(&"cli".to_string()));
|
||||
assert_eq!(envs.get("ECC_HARNESS"), Some(&"codex".to_string()));
|
||||
assert_eq!(envs.get("CLAUDE_MODEL"), Some(&"gpt-5.4".to_string()));
|
||||
assert!(
|
||||
envs.contains_key("CLAUDE_PLUGIN_ROOT"),
|
||||
"shared compatibility env should expose the ECC plugin root"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -4441,24 +4507,20 @@ mod tests {
|
||||
"System instructions:\nUse repo context carefully.\n\nTask:\nfix callback regression",
|
||||
]
|
||||
);
|
||||
let mut envs = command
|
||||
.as_std()
|
||||
.get_envs()
|
||||
.map(|(key, value)| {
|
||||
(
|
||||
key.to_string_lossy().to_string(),
|
||||
value.map(|value| value.to_string_lossy().to_string()),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
envs.sort();
|
||||
let envs = command_env_map(&command);
|
||||
assert_eq!(envs.get("ECC_SESSION_ID"), Some(&"sess-cur1".to_string()));
|
||||
assert_eq!(
|
||||
envs,
|
||||
vec![
|
||||
("ECC_HARNESS".to_string(), Some("cursor".to_string())),
|
||||
("ECC_SESSION_ID".to_string(), Some("sess-cur1".to_string())),
|
||||
]
|
||||
envs.get("CLAUDE_SESSION_ID"),
|
||||
Some(&"sess-cur1".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
envs.get("CLAUDE_PROJECT_DIR"),
|
||||
Some(&"/tmp/repo".to_string())
|
||||
);
|
||||
assert_eq!(envs.get("CLAUDE_CODE_ENTRYPOINT"), Some(&"cli".to_string()));
|
||||
assert_eq!(envs.get("ECC_HARNESS"), Some(&"cursor".to_string()));
|
||||
assert_eq!(envs.get("CLAUDE_MODEL"), Some(&"gpt-5.4".to_string()));
|
||||
assert_eq!(envs.get("ECC_PLUGIN_ROOT"), envs.get("CLAUDE_PLUGIN_ROOT"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -4806,7 +4868,7 @@ mod tests {
|
||||
let script_path = root.join("fake-claude.sh");
|
||||
let log_path = root.join("fake-claude.log");
|
||||
let script = format!(
|
||||
"#!/usr/bin/env python3\nimport os\nimport pathlib\nimport signal\nimport sys\nimport time\n\nlog_path = pathlib.Path(r\"{}\")\nlog_path.write_text(os.getcwd() + \"\\n\", encoding=\"utf-8\")\nwith log_path.open(\"a\", encoding=\"utf-8\") as handle:\n handle.write(\" \".join(sys.argv[1:]) + \"\\n\")\n handle.write(\"ECC_SESSION_ID=\" + os.environ.get(\"ECC_SESSION_ID\", \"\") + \"\\n\")\n\ndef handle_term(signum, frame):\n raise SystemExit(0)\n\nsignal.signal(signal.SIGTERM, handle_term)\nwhile True:\n time.sleep(0.1)\n",
|
||||
"#!/usr/bin/env python3\nimport os\nimport pathlib\nimport signal\nimport sys\nimport time\n\nlog_path = pathlib.Path(r\"{}\")\nlog_path.write_text(os.getcwd() + \"\\n\", encoding=\"utf-8\")\nwith log_path.open(\"a\", encoding=\"utf-8\") as handle:\n handle.write(\" \".join(sys.argv[1:]) + \"\\n\")\n handle.write(\"ECC_SESSION_ID=\" + os.environ.get(\"ECC_SESSION_ID\", \"\") + \"\\n\")\n handle.write(\"CLAUDE_SESSION_ID=\" + os.environ.get(\"CLAUDE_SESSION_ID\", \"\") + \"\\n\")\n handle.write(\"CLAUDE_PROJECT_DIR=\" + os.environ.get(\"CLAUDE_PROJECT_DIR\", \"\") + \"\\n\")\n handle.write(\"CLAUDE_CODE_ENTRYPOINT=\" + os.environ.get(\"CLAUDE_CODE_ENTRYPOINT\", \"\") + \"\\n\")\n handle.write(\"CLAUDE_PLUGIN_ROOT=\" + os.environ.get(\"CLAUDE_PLUGIN_ROOT\", \"\") + \"\\n\")\n handle.write(\"ECC_HARNESS=\" + os.environ.get(\"ECC_HARNESS\", \"\") + \"\\n\")\n\ndef handle_term(signum, frame):\n raise SystemExit(0)\n\nsignal.signal(signal.SIGTERM, handle_term)\nwhile True:\n time.sleep(0.1)\n",
|
||||
log_path.display()
|
||||
);
|
||||
|
||||
@@ -4834,6 +4896,21 @@ mod tests {
|
||||
anyhow::bail!("timed out waiting for {}", path.display());
|
||||
}
|
||||
|
||||
fn command_env_map(command: &Command) -> BTreeMap<String, String> {
|
||||
command
|
||||
.as_std()
|
||||
.get_envs()
|
||||
.filter_map(|(key, value)| {
|
||||
value.map(|value| {
|
||||
(
|
||||
key.to_string_lossy().to_string(),
|
||||
value.to_string_lossy().to_string(),
|
||||
)
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn create_session_spawns_process_and_marks_session_running() -> Result<()> {
|
||||
let tempdir = TestDir::new("manager-create-session")?;
|
||||
@@ -4869,6 +4946,13 @@ mod tests {
|
||||
assert!(log.contains("--print"));
|
||||
assert!(log.contains("implement lifecycle"));
|
||||
assert!(log.contains(&format!("ECC_SESSION_ID={session_id}")));
|
||||
assert!(log.contains(&format!("CLAUDE_SESSION_ID={session_id}")));
|
||||
assert!(log.contains(&format!(
|
||||
"CLAUDE_PROJECT_DIR={}",
|
||||
repo_root.to_string_lossy()
|
||||
)));
|
||||
assert!(log.contains("CLAUDE_CODE_ENTRYPOINT=cli"));
|
||||
assert!(log.contains("ECC_HARNESS=claude"));
|
||||
|
||||
stop_session_with_options(&db, &session_id, false).await?;
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user