From 1539e52b19f86d0793bf1f997792bbff86ee7ef1 Mon Sep 17 00:00:00 2001 From: Dave Date: Mon, 23 Feb 2026 18:50:41 +0000 Subject: [PATCH] Inject story content into agent prompts so coders know what to build The worktree doesn't have .story_kit/work/ so agents had no access to the story requirements. Read the story file from the project root and prepend it to the prompt. Without this, coders would start, read CLAUDE.md, have nothing to implement, and exit with no code. Co-Authored-By: Claude Opus 4.6 --- server/src/agents.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/server/src/agents.rs b/server/src/agents.rs index 7861bf9..325630e 100644 --- a/server/src/agents.rs +++ b/server/src/agents.rs @@ -249,11 +249,21 @@ impl AgentPool { } } + // Read story content from the project root (the worktree may not have + // .story_kit/work/) and inject it into the agent prompt so the coder + // knows what to implement. + let story_content = read_story_content(project_root, story_id); + // Spawn the agent process let wt_path_str = wt_info.path.to_string_lossy().to_string(); let (command, args, mut prompt) = config.render_agent_args(&wt_path_str, story_id, Some(&resolved_name), Some(&wt_info.base_branch))?; + // Prepend story content so the agent sees the requirements first. + if let Some(content) = story_content { + prompt = format!("## Story Requirements\n\n{content}\n\n---\n\n{prompt}"); + } + // Append resume context if this is a restart with failure information. if let Some(ctx) = resume_context { prompt.push_str(ctx); @@ -1359,6 +1369,20 @@ fn item_type_from_id(item_id: &str) -> &'static str { } /// Return the source directory path for a work item (always work/1_upcoming/). +/// Read story/bug content from any pipeline stage directory. +/// Returns the file contents if found, or None if the file doesn't exist anywhere. +fn read_story_content(project_root: &Path, story_id: &str) -> Option { + let sk = project_root.join(".story_kit").join("work"); + let filename = format!("{story_id}.md"); + for stage in &["2_current", "1_upcoming", "3_qa", "4_merge"] { + let path = sk.join(stage).join(&filename); + if let Ok(content) = std::fs::read_to_string(&path) { + return Some(content); + } + } + None +} + fn item_source_dir(project_root: &Path, _item_id: &str) -> PathBuf { project_root.join(".story_kit").join("work").join("1_upcoming") }