mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-11 02:20:29 +08:00
feat: preserve custom ecc2 harness labels
This commit is contained in:
parent
bcd869d520
commit
4a1f3cbd3f
@ -1230,8 +1230,8 @@ async fn main() -> Result<()> {
|
||||
for s in sessions {
|
||||
let harness = harnesses
|
||||
.get(&s.id)
|
||||
.map(|info| info.primary.to_string())
|
||||
.unwrap_or_else(|| "unknown".to_string());
|
||||
.map(|info| info.primary_label.clone())
|
||||
.unwrap_or_else(|| session::SessionHarnessInfo::runner_key(&s.agent_type));
|
||||
println!("{} [{}] [{}] {}", s.id, s.state, harness, s.task);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2004,10 +2004,11 @@ pub async fn delete_session(db: &StateStore, id: &str) -> Result<()> {
|
||||
|
||||
fn agent_program(cfg: &Config, agent_type: &str) -> Result<PathBuf> {
|
||||
let harness = HarnessKind::from_agent_type(agent_type);
|
||||
if let Some(runner) = cfg.harness_runner(harness.as_str()) {
|
||||
let runner_key = SessionHarnessInfo::runner_key(agent_type);
|
||||
if let Some(runner) = cfg.harness_runner(&runner_key) {
|
||||
let program = runner.program.trim();
|
||||
if program.is_empty() {
|
||||
anyhow::bail!("Configured harness runner for {harness} is missing a program");
|
||||
anyhow::bail!("Configured harness runner for {runner_key} is missing a program");
|
||||
}
|
||||
return Ok(PathBuf::from(program));
|
||||
}
|
||||
@ -2685,7 +2686,7 @@ fn build_agent_command(
|
||||
profile: Option<&SessionAgentProfile>,
|
||||
) -> Command {
|
||||
let harness = HarnessKind::from_agent_type(agent_type);
|
||||
if let Some(runner) = cfg.harness_runner(harness.as_str()) {
|
||||
if let Some(runner) = cfg.harness_runner(&SessionHarnessInfo::runner_key(agent_type)) {
|
||||
return build_configured_harness_command(
|
||||
runner,
|
||||
agent_program,
|
||||
@ -3327,7 +3328,7 @@ impl fmt::Display for SessionStatus {
|
||||
writeln!(f, "Session: {}", s.id)?;
|
||||
writeln!(f, "Task: {}", s.task)?;
|
||||
writeln!(f, "Agent: {}", s.agent_type)?;
|
||||
writeln!(f, "Harness: {}", self.harness.primary)?;
|
||||
writeln!(f, "Harness: {}", self.harness.primary_label)?;
|
||||
writeln!(f, "Detected: {}", self.harness.detected_summary())?;
|
||||
writeln!(f, "State: {}", s.state)?;
|
||||
if let Some(profile) = self.profile.as_ref() {
|
||||
@ -3880,6 +3881,24 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn agent_program_uses_configured_runner_for_unknown_custom_harness() -> Result<()> {
|
||||
let mut cfg = Config::default();
|
||||
cfg.harness_runners.insert(
|
||||
"acme-runner".to_string(),
|
||||
crate::config::HarnessRunnerConfig {
|
||||
program: "acme-agent".to_string(),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
agent_program(&cfg, "acme-runner")?,
|
||||
PathBuf::from("acme-agent")
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_agent_command_uses_configured_runner_for_cursor() {
|
||||
let mut cfg = Config::default();
|
||||
|
||||
@ -109,11 +109,38 @@ impl fmt::Display for HarnessKind {
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct SessionHarnessInfo {
|
||||
pub primary: HarnessKind,
|
||||
pub primary_label: String,
|
||||
pub detected: Vec<HarnessKind>,
|
||||
}
|
||||
|
||||
impl SessionHarnessInfo {
|
||||
pub fn runner_key(agent_type: &str) -> String {
|
||||
let canonical = HarnessKind::canonical_agent_type(agent_type);
|
||||
match HarnessKind::from_agent_type(&canonical) {
|
||||
HarnessKind::Unknown if canonical.is_empty() => {
|
||||
HarnessKind::Unknown.as_str().to_string()
|
||||
}
|
||||
HarnessKind::Unknown => canonical,
|
||||
harness => harness.as_str().to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn primary_label_for(agent_type: &str, primary: HarnessKind) -> String {
|
||||
match primary {
|
||||
HarnessKind::Unknown => {
|
||||
let label = Self::runner_key(agent_type);
|
||||
if label.is_empty() {
|
||||
HarnessKind::Unknown.as_str().to_string()
|
||||
} else {
|
||||
label
|
||||
}
|
||||
}
|
||||
harness => harness.as_str().to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn detect(agent_type: &str, working_dir: &Path) -> Self {
|
||||
let runner_key = Self::runner_key(agent_type);
|
||||
let detected = [
|
||||
HarnessKind::Claude,
|
||||
HarnessKind::Codex,
|
||||
@ -132,12 +159,43 @@ impl SessionHarnessInfo {
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let primary = match HarnessKind::from_agent_type(agent_type) {
|
||||
HarnessKind::Unknown => detected.first().copied().unwrap_or(HarnessKind::Unknown),
|
||||
let primary = match HarnessKind::from_agent_type(&runner_key) {
|
||||
HarnessKind::Unknown if runner_key == HarnessKind::Unknown.as_str() => {
|
||||
detected.first().copied().unwrap_or(HarnessKind::Unknown)
|
||||
}
|
||||
HarnessKind::Unknown => HarnessKind::Unknown,
|
||||
harness => harness,
|
||||
};
|
||||
|
||||
Self { primary, detected }
|
||||
Self {
|
||||
primary,
|
||||
primary_label: Self::primary_label_for(agent_type, primary),
|
||||
detected,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_persisted(
|
||||
harness_label: &str,
|
||||
agent_type: &str,
|
||||
working_dir: &Path,
|
||||
detected: Vec<HarnessKind>,
|
||||
) -> Self {
|
||||
let primary = HarnessKind::from_db_value(harness_label);
|
||||
if primary == HarnessKind::Unknown && detected.is_empty() && harness_label.trim().is_empty()
|
||||
{
|
||||
return Self::detect(agent_type, working_dir);
|
||||
}
|
||||
|
||||
let normalized_label = harness_label.trim().to_ascii_lowercase();
|
||||
Self {
|
||||
primary,
|
||||
primary_label: if normalized_label.is_empty() {
|
||||
Self::primary_label_for(agent_type, primary)
|
||||
} else {
|
||||
normalized_label
|
||||
},
|
||||
detected,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn detected_summary(&self) -> String {
|
||||
@ -510,6 +568,7 @@ mod tests {
|
||||
|
||||
let harness = SessionHarnessInfo::detect("claude", repo.path());
|
||||
assert_eq!(harness.primary, HarnessKind::Claude);
|
||||
assert_eq!(harness.primary_label, "claude");
|
||||
assert_eq!(
|
||||
harness.detected,
|
||||
vec![HarnessKind::Claude, HarnessKind::Codex]
|
||||
@ -519,13 +578,14 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detect_session_harness_falls_back_to_project_markers_for_unknown_agent(
|
||||
fn detect_session_harness_falls_back_to_project_markers_when_agent_unspecified(
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let repo = TestDir::new("session-harness-markers")?;
|
||||
fs::create_dir_all(repo.path().join(".gemini"))?;
|
||||
|
||||
let harness = SessionHarnessInfo::detect("custom-runner", repo.path());
|
||||
let harness = SessionHarnessInfo::detect("", repo.path());
|
||||
assert_eq!(harness.primary, HarnessKind::Gemini);
|
||||
assert_eq!(harness.primary_label, "gemini");
|
||||
assert_eq!(harness.detected, vec![HarnessKind::Gemini]);
|
||||
Ok(())
|
||||
}
|
||||
@ -543,4 +603,38 @@ mod tests {
|
||||
"custom-runner"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detect_session_harness_preserves_custom_agent_label_without_markers() {
|
||||
let harness = SessionHarnessInfo::detect(" custom-runner ", Path::new("."));
|
||||
assert_eq!(harness.primary, HarnessKind::Unknown);
|
||||
assert_eq!(harness.primary_label, "custom-runner");
|
||||
assert!(harness.detected.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detect_session_harness_preserves_custom_agent_label_with_project_markers(
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let repo = TestDir::new("session-harness-custom-markers")?;
|
||||
fs::create_dir_all(repo.path().join(".claude"))?;
|
||||
fs::create_dir_all(repo.path().join(".codex"))?;
|
||||
|
||||
let harness = SessionHarnessInfo::detect("custom-runner", repo.path());
|
||||
assert_eq!(harness.primary, HarnessKind::Unknown);
|
||||
assert_eq!(harness.primary_label, "custom-runner");
|
||||
assert_eq!(
|
||||
harness.detected,
|
||||
vec![HarnessKind::Claude, HarnessKind::Codex]
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn runner_key_uses_canonical_label_for_unknown_harnesses() {
|
||||
assert_eq!(
|
||||
SessionHarnessInfo::runner_key(" custom-runner "),
|
||||
"custom-runner"
|
||||
);
|
||||
assert_eq!(SessionHarnessInfo::runner_key("claude-code"), "claude");
|
||||
}
|
||||
}
|
||||
|
||||
@ -706,7 +706,7 @@ impl StateStore {
|
||||
rusqlite::params![
|
||||
session_id,
|
||||
canonical_agent_type,
|
||||
harness.primary.to_string(),
|
||||
harness.primary_label,
|
||||
detected_json
|
||||
],
|
||||
)?;
|
||||
@ -728,7 +728,7 @@ impl StateStore {
|
||||
session.project,
|
||||
session.task_group,
|
||||
session.agent_type,
|
||||
harness.primary.to_string(),
|
||||
harness.primary_label,
|
||||
detected_json,
|
||||
session.working_dir.to_string_lossy().to_string(),
|
||||
session.state.to_string(),
|
||||
@ -1763,16 +1763,17 @@ impl StateStore {
|
||||
let harnesses = stmt
|
||||
.query_map([], |row| {
|
||||
let session_id: String = row.get(0)?;
|
||||
let primary = HarnessKind::from_db_value(&row.get::<_, String>(1)?);
|
||||
let harness_label: String = row.get(1)?;
|
||||
let detected = serde_json::from_str::<Vec<HarnessKind>>(&row.get::<_, String>(2)?)
|
||||
.unwrap_or_default();
|
||||
let agent_type: String = row.get(3)?;
|
||||
let working_dir = PathBuf::from(row.get::<_, String>(4)?);
|
||||
let info = if primary == HarnessKind::Unknown && detected.is_empty() {
|
||||
SessionHarnessInfo::detect(&agent_type, &working_dir)
|
||||
} else {
|
||||
SessionHarnessInfo { primary, detected }
|
||||
};
|
||||
let info = SessionHarnessInfo::from_persisted(
|
||||
&harness_label,
|
||||
&agent_type,
|
||||
&working_dir,
|
||||
detected,
|
||||
);
|
||||
Ok((session_id, info))
|
||||
})?
|
||||
.collect::<std::result::Result<HashMap<_, _>, _>>()?;
|
||||
@ -1788,16 +1789,17 @@ impl StateStore {
|
||||
)?;
|
||||
|
||||
stmt.query_row([session_id], |row| {
|
||||
let primary = HarnessKind::from_db_value(&row.get::<_, String>(0)?);
|
||||
let harness_label: String = row.get(0)?;
|
||||
let detected = serde_json::from_str::<Vec<HarnessKind>>(&row.get::<_, String>(1)?)
|
||||
.unwrap_or_default();
|
||||
let agent_type: String = row.get(2)?;
|
||||
let working_dir = PathBuf::from(row.get::<_, String>(3)?);
|
||||
let info = if primary == HarnessKind::Unknown && detected.is_empty() {
|
||||
SessionHarnessInfo::detect(&agent_type, &working_dir)
|
||||
} else {
|
||||
SessionHarnessInfo { primary, detected }
|
||||
};
|
||||
let info = SessionHarnessInfo::from_persisted(
|
||||
&harness_label,
|
||||
&agent_type,
|
||||
&working_dir,
|
||||
detected,
|
||||
);
|
||||
Ok(info)
|
||||
})
|
||||
.optional()
|
||||
@ -4191,10 +4193,41 @@ mod tests {
|
||||
.get_session_harness_info("sess-legacy")?
|
||||
.expect("legacy row should be backfilled");
|
||||
assert_eq!(harness.primary, HarnessKind::Gemini);
|
||||
assert_eq!(harness.primary_label, "gemini");
|
||||
assert_eq!(harness.detected, vec![HarnessKind::Codex]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insert_session_preserves_custom_harness_label_for_unknown_agent_types() -> Result<()> {
|
||||
let tempdir = TestDir::new("store-custom-harness-label")?;
|
||||
let db = StateStore::open(&tempdir.path().join("state.db"))?;
|
||||
let now = Utc::now();
|
||||
|
||||
db.insert_session(&Session {
|
||||
id: "sess-custom".to_string(),
|
||||
task: "Run custom harness".to_string(),
|
||||
project: "ecc".to_string(),
|
||||
task_group: "compat".to_string(),
|
||||
agent_type: "acme-runner".to_string(),
|
||||
working_dir: PathBuf::from(tempdir.path()),
|
||||
state: SessionState::Pending,
|
||||
pid: None,
|
||||
worktree: None,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
last_heartbeat_at: now,
|
||||
metrics: SessionMetrics::default(),
|
||||
})?;
|
||||
|
||||
let harness = db
|
||||
.get_session_harness_info("sess-custom")?
|
||||
.expect("custom session should have harness info");
|
||||
assert_eq!(harness.primary, HarnessKind::Unknown);
|
||||
assert_eq!(harness.primary_label, "acme-runner");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_profile_round_trips_with_launch_settings() -> Result<()> {
|
||||
let tempdir = TestDir::new("store-session-profile")?;
|
||||
|
||||
@ -6347,7 +6347,7 @@ impl Dashboard {
|
||||
if let Some(harness) = self.session_harnesses.get(&session.id) {
|
||||
lines.push(format!(
|
||||
"Harness {} | Detected {}",
|
||||
harness.primary,
|
||||
harness.primary_label,
|
||||
harness.detected_summary()
|
||||
));
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user