huskies: merge 944

This commit is contained in:
dave
2026-05-13 05:02:52 +00:00
parent f2943c7e69
commit 7ca5339450
9 changed files with 168 additions and 118 deletions
+30 -32
View File
@@ -61,7 +61,9 @@ impl std::fmt::Display for Error {
#[derive(Debug, Clone)]
pub struct WorkItemContent {
pub content: String,
pub stage: String,
pub stage: crate::pipeline_state::Stage,
/// Whether the item is frozen — orthogonal to [`Self::stage`].
pub frozen: bool,
pub name: Option<String>,
pub agent: Option<String>,
}
@@ -171,13 +173,24 @@ pub fn get_work_item_content(
project_root: &Path,
story_id: &str,
) -> Result<WorkItemContent, Error> {
use crate::pipeline_state::Stage;
let stages = [
("1_backlog", "backlog"),
("2_current", "current"),
("3_qa", "qa"),
("4_merge", "merge"),
("5_done", "done"),
("6_archived", "archived"),
("1_backlog", Stage::Backlog),
("2_current", Stage::Coding),
("3_qa", Stage::Qa),
(
"4_merge",
Stage::from_dir("merge").expect("merge is a valid stage dir"),
),
(
"5_done",
Stage::from_dir("done").expect("done is a valid stage dir"),
),
(
"6_archived",
Stage::from_dir("archived").expect("archived is a valid stage dir"),
),
];
let work_dir = project_root.join(".huskies").join("work");
@@ -191,11 +204,12 @@ pub fn get_work_item_content(
.as_ref()
.and_then(|v| v.agent().map(str::to_string));
for (stage_dir, stage_name) in &stages {
for (stage_dir, stage) in &stages {
if let Some(content) = io::read_work_item_from_stage(&work_dir, stage_dir, &filename)? {
return Ok(WorkItemContent {
content,
stage: stage_name.to_string(),
stage: stage.clone(),
frozen: false,
name: crdt_name.clone(),
agent: crdt_agent.clone(),
});
@@ -206,31 +220,14 @@ pub fn get_work_item_content(
if let Some(content) = crate::db::read_content(story_id) {
let item = crate::pipeline_state::read_typed(story_id)
.map_err(|e| Error::Io(format!("Pipeline read error: {e}")))?;
let stage = item
.as_ref()
.map(|i| {
// Frozen is now an orthogonal CRDT flag (story 934, stage 4).
if i.is_frozen() {
"frozen"
} else {
match &i.stage {
crate::pipeline_state::Stage::Upcoming => "upcoming",
crate::pipeline_state::Stage::Backlog => "backlog",
crate::pipeline_state::Stage::Coding => "current",
crate::pipeline_state::Stage::Blocked { .. } => "blocked",
crate::pipeline_state::Stage::Qa => "qa",
crate::pipeline_state::Stage::Merge { .. } => "merge",
crate::pipeline_state::Stage::MergeFailure { .. } => "merge_failure",
crate::pipeline_state::Stage::Done { .. } => "done",
crate::pipeline_state::Stage::Archived { .. } => "archived",
}
}
})
.unwrap_or("unknown")
.to_string();
let (stage, frozen) = match item.as_ref() {
Some(i) => (i.stage.clone(), i.is_frozen()),
None => (Stage::Upcoming, false),
};
return Ok(WorkItemContent {
content,
stage,
frozen,
name: crdt_name,
agent: crdt_agent,
});
@@ -364,7 +361,8 @@ max_budget_usd = 5.0
);
let item = get_work_item_content(tmp.path(), "42_story_foo").unwrap();
assert!(item.content.contains("Some content."));
assert_eq!(item.stage, "backlog");
assert_eq!(item.stage, crate::pipeline_state::Stage::Backlog);
assert!(!item.frozen);
assert_eq!(item.name, Some("Foo Story".to_string()));
}