huskies: merge 1066

This commit is contained in:
dave
2026-05-14 23:39:56 +00:00
parent bf813d910b
commit bb6a6063e8
15 changed files with 361 additions and 120 deletions
@@ -72,6 +72,38 @@ pub(crate) fn spawn_worktree_cleanup_subscriber(project_root: PathBuf) {
});
}
/// Reconcile worktree creation: for each story currently in `Stage::Coding`, ensure its worktree exists.
///
/// Idempotent — creates worktrees for Coding stories that have no worktree yet, and is
/// a no-op for stories whose worktree already exists. Called by the periodic reconciler
/// so that Lagged events on the broadcast channel never leave Coding stories without worktrees.
pub(crate) async fn reconcile_worktree_create(project_root: &Path, port: u16) {
for item in crate::pipeline_state::read_all_typed() {
if matches!(item.stage, crate::pipeline_state::Stage::Coding { .. }) {
on_coding_transition(project_root, port, &item.story_id.0).await;
}
}
}
/// Reconcile worktree cleanup: for each story in a terminal stage, ensure its worktree is removed.
///
/// Idempotent — removes worktrees for terminal stories that still have one, and is a no-op
/// for stories with no worktree. Called by the periodic reconciler so that Lagged events on
/// the broadcast channel never leave terminal stories with dangling worktrees.
pub(crate) async fn reconcile_worktree_cleanup(project_root: &Path) {
for item in crate::pipeline_state::read_all_typed() {
if matches!(
item.stage,
crate::pipeline_state::Stage::Done { .. }
| crate::pipeline_state::Stage::Archived { .. }
| crate::pipeline_state::Stage::Abandoned { .. }
| crate::pipeline_state::Stage::Superseded { .. }
) {
on_terminal_transition(project_root, &item.story_id.0).await;
}
}
}
/// Create the worktree and feature branch for `story_id` when it enters `Stage::Coding`.
pub(crate) async fn on_coding_transition(project_root: &Path, port: u16, story_id: &str) {
let config = match crate::config::ProjectConfig::load(project_root) {