aboutsummaryrefslogtreecommitdiff
path: root/src/agent_resume.rs
diff options
context:
space:
mode:
authorEric Yue <yue1995pro@gmail.com>2026-06-15 21:50:24 +0800
committerGitHub <noreply@github.com>2026-06-15 16:50:24 +0300
commit07261e09be60ac0c145685fd11f94351cc0e5ba6 (patch)
tree771b0180c7a1560189547e6d23ef004ec1cf6d5c /src/agent_resume.rs
parent08bb0768ae224c8db04bbe016b050353ce13eee7 (diff)
feat: add devin cli detection and restore support (#622)
* feat: add devin cli detection and restore support refs #606 * fix: keep devin integration session-only --------- Co-authored-by: Ogulcan Celik <ogulcancelik@gmail.com>
Diffstat (limited to 'src/agent_resume.rs')
-rw-r--r--src/agent_resume.rs38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/agent_resume.rs b/src/agent_resume.rs
index cea4a641..4a97f207 100644
--- a/src/agent_resume.rs
+++ b/src/agent_resume.rs
@@ -82,6 +82,7 @@ pub fn is_reserved_native_state_source(source: &str, agent: &str) -> bool {
("herdr:claude", "claude")
| ("herdr:codex", "codex")
| ("herdr:copilot", "copilot")
+ | ("herdr:devin", "devin")
| ("herdr:droid", "droid")
| ("herdr:qodercli", "qodercli")
| ("herdr:cursor", "cursor")
@@ -128,6 +129,9 @@ pub fn plan(source: &str, agent: &str, session_ref: &AgentSessionRef) -> Option<
("herdr:copilot", "copilot", AgentSessionRefKind::Id) => {
vec!["copilot".into(), format!("--resume={}", session_ref.value)]
}
+ ("herdr:devin", "devin", AgentSessionRefKind::Id) => {
+ vec!["devin".into(), "--resume".into(), session_ref.value.clone()]
+ }
("herdr:droid", "droid", AgentSessionRefKind::Id) => {
vec!["droid".into(), "--resume".into(), session_ref.value.clone()]
}
@@ -191,6 +195,7 @@ fn is_official_agent_source(source: &str, agent: &str) -> bool {
("herdr:claude", "claude")
| ("herdr:codex", "codex")
| ("herdr:copilot", "copilot")
+ | ("herdr:devin", "devin")
| ("herdr:droid", "droid")
| ("herdr:kimi", "kimi")
| ("herdr:pi", "pi")
@@ -229,6 +234,7 @@ mod tests {
fn native_state_reservation_excludes_full_lifecycle_sources() {
assert!(is_reserved_native_state_source("herdr:claude", "claude"));
assert!(is_reserved_native_state_source("herdr:codex", "codex"));
+ assert!(is_reserved_native_state_source("herdr:devin", "devin"));
assert!(!is_reserved_native_state_source("herdr:kimi", "kimi"));
assert!(!is_reserved_native_state_source(
"herdr:opencode",
@@ -271,6 +277,16 @@ mod tests {
);
assert_eq!(
plan(
+ "herdr:devin",
+ "devin",
+ &AgentSessionRef::id("devin-session").unwrap()
+ )
+ .unwrap()
+ .argv,
+ vec!["devin", "--resume", "devin-session"]
+ );
+ assert_eq!(
+ plan(
"herdr:droid",
"droid",
&AgentSessionRef::id("droid-session").unwrap()
@@ -404,6 +420,11 @@ mod tests {
);
let session_ref =
+ session_ref_from_report("herdr:devin", "devin", Some("devin-id".into()), None).unwrap();
+ assert_eq!(session_ref.kind, AgentSessionRefKind::Id);
+ assert_eq!(session_ref.value, "devin-id");
+
+ let session_ref =
session_ref_from_report("herdr:droid", "droid", Some("droid-id".into()), None).unwrap();
assert_eq!(session_ref.kind, AgentSessionRefKind::Id);
assert_eq!(session_ref.value, "droid-id");
@@ -474,6 +495,9 @@ mod tests {
)
.unwrap();
assert_eq!(copilot_plan.argv, vec!["copilot", "--resume=abc; rm -rf /"]);
+
+ let devin_plan = plan("herdr:devin", "devin", &AgentSessionRef::id(id).unwrap()).unwrap();
+ assert_eq!(devin_plan.argv, vec!["devin", "--resume", id]);
}
#[test]
@@ -482,6 +506,7 @@ mod tests {
let opencode_session = absolute_test_path("opencode-session");
let kilo_session = absolute_test_path("kilo-session");
let copilot_session = absolute_test_path("copilot-session");
+ let devin_session = absolute_test_path("devin-session");
assert!(plan(
"herdr:hermes",
"hermes",
@@ -506,6 +531,12 @@ mod tests {
&AgentSessionRef::path(&copilot_session).unwrap()
)
.is_none());
+ assert!(plan(
+ "herdr:devin",
+ "devin",
+ &AgentSessionRef::path(&devin_session).unwrap()
+ )
+ .is_none());
assert!(session_ref_from_snapshot(
"herdr:hermes",
"hermes",
@@ -534,5 +565,12 @@ mod tests {
"copilot-session"
)
.is_some());
+ assert!(session_ref_from_snapshot(
+ "herdr:devin",
+ "devin",
+ AgentSessionRefKind::Id,
+ "devin-session"
+ )
+ .is_some());
}
}