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 <noreply@anthropic.com>
This commit is contained in:
Dave
2026-02-23 18:50:41 +00:00
parent 5374ee316e
commit 1539e52b19

View File

@@ -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 // Spawn the agent process
let wt_path_str = wt_info.path.to_string_lossy().to_string(); let wt_path_str = wt_info.path.to_string_lossy().to_string();
let (command, args, mut prompt) = let (command, args, mut prompt) =
config.render_agent_args(&wt_path_str, story_id, Some(&resolved_name), Some(&wt_info.base_branch))?; 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. // Append resume context if this is a restart with failure information.
if let Some(ctx) = resume_context { if let Some(ctx) = resume_context {
prompt.push_str(ctx); 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/). /// 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<String> {
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 { fn item_source_dir(project_root: &Path, _item_id: &str) -> PathBuf {
project_root.join(".story_kit").join("work").join("1_upcoming") project_root.join(".story_kit").join("work").join("1_upcoming")
} }