Accept story 30: Worktree-based agent orchestration
Add git worktree isolation for concurrent story agents. Each agent now runs in its own worktree with setup/teardown commands driven by .story_kit/project.toml config. Agents stream output via SSE and support start/stop lifecycle with Pending/Running/Completed/Failed statuses. Backend: config.rs (TOML parsing), worktree.rs (git worktree lifecycle), refactored agents.rs (broadcast streaming), agents_sse.rs (SSE endpoint). Frontend: AgentPanel.tsx with Run/Stop buttons and streaming output log. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -158,8 +158,8 @@ fn run_pty_session(
|
||||
eprintln!("[pty-debug] processing: {}...", &trimmed[..trimmed.len().min(120)]);
|
||||
|
||||
// Try to parse as JSON
|
||||
if let Ok(json) = serde_json::from_str::<serde_json::Value>(trimmed) {
|
||||
if let Some(event_type) = json.get("type").and_then(|t| t.as_str()) {
|
||||
if let Ok(json) = serde_json::from_str::<serde_json::Value>(trimmed)
|
||||
&& let Some(event_type) = json.get("type").and_then(|t| t.as_str()) {
|
||||
match event_type {
|
||||
// Streaming deltas (when --include-partial-messages is used)
|
||||
"stream_event" => {
|
||||
@@ -169,15 +169,14 @@ fn run_pty_session(
|
||||
}
|
||||
// Complete assistant message
|
||||
"assistant" => {
|
||||
if let Some(message) = json.get("message") {
|
||||
if let Some(content) = message.get("content").and_then(|c| c.as_array()) {
|
||||
if let Some(message) = json.get("message")
|
||||
&& let Some(content) = message.get("content").and_then(|c| c.as_array()) {
|
||||
for block in content {
|
||||
if let Some(text) = block.get("text").and_then(|t| t.as_str()) {
|
||||
let _ = token_tx.send(text.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Final result with usage stats
|
||||
"result" => {
|
||||
@@ -209,7 +208,6 @@ fn run_pty_session(
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ignore non-JSON lines (terminal escape sequences)
|
||||
|
||||
if got_result {
|
||||
@@ -223,15 +221,14 @@ fn run_pty_session(
|
||||
// Drain remaining lines
|
||||
while let Ok(Some(line)) = line_rx.try_recv() {
|
||||
let trimmed = line.trim();
|
||||
if let Ok(json) = serde_json::from_str::<serde_json::Value>(trimmed) {
|
||||
if let Some(event) = json
|
||||
if let Ok(json) = serde_json::from_str::<serde_json::Value>(trimmed)
|
||||
&& let Some(event) = json
|
||||
.get("type")
|
||||
.filter(|t| t.as_str() == Some("stream_event"))
|
||||
.and_then(|_| json.get("event"))
|
||||
{
|
||||
handle_stream_event(event, &token_tx);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user