mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-09 10:53:34 +08:00
feat: wire ecc2 session handoffs into spawn flows
This commit is contained in:
@@ -32,6 +32,9 @@ enum Commands {
|
|||||||
/// Create a dedicated worktree for this session
|
/// Create a dedicated worktree for this session
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
worktree: bool,
|
worktree: bool,
|
||||||
|
/// Source session to delegate from
|
||||||
|
#[arg(long)]
|
||||||
|
from_session: Option<String>,
|
||||||
},
|
},
|
||||||
/// List active sessions
|
/// List active sessions
|
||||||
Sessions,
|
Sessions,
|
||||||
@@ -123,9 +126,14 @@ async fn main() -> Result<()> {
|
|||||||
task,
|
task,
|
||||||
agent,
|
agent,
|
||||||
worktree: use_worktree,
|
worktree: use_worktree,
|
||||||
|
from_session,
|
||||||
}) => {
|
}) => {
|
||||||
let session_id =
|
let session_id =
|
||||||
session::manager::create_session(&db, &cfg, &task, &agent, use_worktree).await?;
|
session::manager::create_session(&db, &cfg, &task, &agent, use_worktree).await?;
|
||||||
|
if let Some(from_session) = from_session {
|
||||||
|
let from_id = resolve_session_id(&db, &from_session)?;
|
||||||
|
send_handoff_message(&db, &from_id, &session_id)?;
|
||||||
|
}
|
||||||
println!("Session started: {session_id}");
|
println!("Session started: {session_id}");
|
||||||
}
|
}
|
||||||
Some(Commands::Sessions) => {
|
Some(Commands::Sessions) => {
|
||||||
@@ -254,6 +262,41 @@ fn short_session(session_id: &str) -> String {
|
|||||||
session_id.chars().take(8).collect()
|
session_id.chars().take(8).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_handoff_message(
|
||||||
|
db: &session::store::StateStore,
|
||||||
|
from_id: &str,
|
||||||
|
to_id: &str,
|
||||||
|
) -> Result<()> {
|
||||||
|
let from_session = db
|
||||||
|
.get_session(from_id)?
|
||||||
|
.ok_or_else(|| anyhow::anyhow!("Session not found: {from_id}"))?;
|
||||||
|
let context = format!(
|
||||||
|
"Delegated from {} [{}] | cwd {}{}",
|
||||||
|
short_session(&from_session.id),
|
||||||
|
from_session.agent_type,
|
||||||
|
from_session.working_dir.display(),
|
||||||
|
from_session
|
||||||
|
.worktree
|
||||||
|
.as_ref()
|
||||||
|
.map(|worktree| format!(
|
||||||
|
" | worktree {} ({})",
|
||||||
|
worktree.branch,
|
||||||
|
worktree.path.display()
|
||||||
|
))
|
||||||
|
.unwrap_or_default()
|
||||||
|
);
|
||||||
|
|
||||||
|
comms::send(
|
||||||
|
db,
|
||||||
|
&from_session.id,
|
||||||
|
to_id,
|
||||||
|
&comms::MessageType::TaskHandoff {
|
||||||
|
task: from_session.task,
|
||||||
|
context,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -305,4 +348,33 @@ mod tests {
|
|||||||
_ => panic!("expected messages send subcommand"),
|
_ => panic!("expected messages send subcommand"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cli_parses_start_with_handoff_source() {
|
||||||
|
let cli = Cli::try_parse_from([
|
||||||
|
"ecc",
|
||||||
|
"start",
|
||||||
|
"--task",
|
||||||
|
"Follow up",
|
||||||
|
"--agent",
|
||||||
|
"claude",
|
||||||
|
"--from-session",
|
||||||
|
"planner",
|
||||||
|
])
|
||||||
|
.expect("start with handoff source should parse");
|
||||||
|
|
||||||
|
match cli.command {
|
||||||
|
Some(Commands::Start {
|
||||||
|
from_session,
|
||||||
|
task,
|
||||||
|
agent,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
|
assert_eq!(task, "Follow up");
|
||||||
|
assert_eq!(agent, "claude");
|
||||||
|
assert_eq!(from_session.as_deref(), Some("planner"));
|
||||||
|
}
|
||||||
|
_ => panic!("expected start subcommand"),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -545,6 +545,39 @@ impl Dashboard {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(source_session) = self.sessions.get(self.selected_session) {
|
||||||
|
let context = format!(
|
||||||
|
"Dashboard handoff from {} [{}] | cwd {}{}",
|
||||||
|
format_session_id(&source_session.id),
|
||||||
|
source_session.agent_type,
|
||||||
|
source_session.working_dir.display(),
|
||||||
|
source_session
|
||||||
|
.worktree
|
||||||
|
.as_ref()
|
||||||
|
.map(|worktree| format!(
|
||||||
|
" | worktree {} ({})",
|
||||||
|
worktree.branch,
|
||||||
|
worktree.path.display()
|
||||||
|
))
|
||||||
|
.unwrap_or_default()
|
||||||
|
);
|
||||||
|
if let Err(error) = comms::send(
|
||||||
|
&self.db,
|
||||||
|
&source_session.id,
|
||||||
|
&session_id,
|
||||||
|
&comms::MessageType::TaskHandoff {
|
||||||
|
task: source_session.task.clone(),
|
||||||
|
context,
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
tracing::warn!(
|
||||||
|
"Failed to send handoff from session {} to {}: {error}",
|
||||||
|
source_session.id,
|
||||||
|
session_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.refresh();
|
self.refresh();
|
||||||
self.sync_selection_by_id(Some(&session_id));
|
self.sync_selection_by_id(Some(&session_id));
|
||||||
self.reset_output_view();
|
self.reset_output_view();
|
||||||
|
|||||||
Reference in New Issue
Block a user