aboutsummaryrefslogtreecommitdiff
path: root/src/agent_resume.rs
diff options
context:
space:
mode:
authorLane <150401101+LaneBirmingham@users.noreply.github.com>2026-06-02 08:32:05 +1000
committerGitHub <noreply@github.com>2026-06-02 01:32:05 +0300
commitf7d315d494b6a3d583574012526d15c1ddc82bfe (patch)
tree327585c6cb27d478bbb1e4b0da782d9bbfd00901 /src/agent_resume.rs
parent99e097c7d3cf76ae2d53bac5e7e2b3fd88b83591 (diff)
feat: add github copilot cli integration (#386)
* feat: add github copilot cli integration refs #232 * docs: restore 0.6.5 changelog and document copilot hook flow * test: cover copilot camelcase hook payloads --------- Co-authored-by: Ogulcan Celik <ogulcancelik@gmail.com>
Diffstat (limited to 'src/agent_resume.rs')
-rw-r--r--src/agent_resume.rs52
1 files changed, 50 insertions, 2 deletions
diff --git a/src/agent_resume.rs b/src/agent_resume.rs
index 8f450088..269b74de 100644
--- a/src/agent_resume.rs
+++ b/src/agent_resume.rs
@@ -106,6 +106,9 @@ pub fn plan(source: &str, agent: &str, session_ref: &AgentSessionRef) -> Option<
("herdr:codex", "codex", AgentSessionRefKind::Id) => {
vec!["codex".into(), "resume".into(), session_ref.value.clone()]
}
+ ("herdr:copilot", "copilot", AgentSessionRefKind::Id) => {
+ vec!["copilot".into(), format!("--resume={}", session_ref.value)]
+ }
("herdr:pi", "pi", AgentSessionRefKind::Path | AgentSessionRefKind::Id) => {
vec!["pi".into(), "--session".into(), session_ref.value.clone()]
}
@@ -145,6 +148,7 @@ fn is_official_agent_source(source: &str, agent: &str) -> bool {
(source, agent),
("herdr:claude", "claude")
| ("herdr:codex", "codex")
+ | ("herdr:copilot", "copilot")
| ("herdr:pi", "pi")
| ("herdr:hermes", "hermes")
| ("herdr:opencode", "opencode")
@@ -190,6 +194,16 @@ mod tests {
);
assert_eq!(
plan(
+ "herdr:copilot",
+ "copilot",
+ &AgentSessionRef::id("copilot-session").unwrap()
+ )
+ .unwrap()
+ .argv,
+ vec!["copilot", "--resume=copilot-session"]
+ );
+ assert_eq!(
+ plan(
"herdr:pi",
"pi",
&AgentSessionRef::path("/tmp/pi-session.jsonl").unwrap()
@@ -261,13 +275,34 @@ mod tests {
Some("/tmp/claude-session".into())
)
.is_none());
+
+ let session_ref =
+ session_ref_from_report("herdr:copilot", "copilot", Some("copilot-id".into()), None)
+ .unwrap();
+ assert_eq!(session_ref.kind, AgentSessionRefKind::Id);
+ assert_eq!(session_ref.value, "copilot-id");
+ assert!(session_ref_from_report(
+ "herdr:copilot",
+ "copilot",
+ None,
+ Some("/tmp/copilot-session".into())
+ )
+ .is_none());
}
#[test]
fn ids_are_data_not_shell_text() {
let id = "abc; rm -rf /";
- let plan = plan("herdr:codex", "codex", &AgentSessionRef::id(id).unwrap()).unwrap();
- assert_eq!(plan.argv, vec!["codex", "resume", id]);
+ let codex_plan = plan("herdr:codex", "codex", &AgentSessionRef::id(id).unwrap()).unwrap();
+ assert_eq!(codex_plan.argv, vec!["codex", "resume", id]);
+
+ let copilot_plan = plan(
+ "herdr:copilot",
+ "copilot",
+ &AgentSessionRef::id(id).unwrap(),
+ )
+ .unwrap();
+ assert_eq!(copilot_plan.argv, vec!["copilot", "--resume=abc; rm -rf /"]);
}
#[test]
@@ -284,6 +319,12 @@ mod tests {
&AgentSessionRef::path("/tmp/opencode-session").unwrap()
)
.is_none());
+ assert!(plan(
+ "herdr:copilot",
+ "copilot",
+ &AgentSessionRef::path("/tmp/copilot-session").unwrap()
+ )
+ .is_none());
assert!(session_ref_from_snapshot(
"herdr:hermes",
"hermes",
@@ -298,5 +339,12 @@ mod tests {
"opencode-session"
)
.is_some());
+ assert!(session_ref_from_snapshot(
+ "herdr:copilot",
+ "copilot",
+ AgentSessionRefKind::Id,
+ "copilot-session"
+ )
+ .is_some());
}
}