Skip to content

Commit cfaf3c9

Browse files
feat(tui): manage story in-progress state from TUI on EventStoryStarted
The TUI now owns the inProgress lifecycle instead of relying on the agent to write it to prd.json (which was a timing race — the event fires before the agent updates the file). On EventStoryStarted the TUI marks the story in-progress, saves the PRD, and auto-selects it. InProgress is cleared on completion, error, or max iterations.
1 parent 2b21b2a commit cfaf3c9

2 files changed

Lines changed: 62 additions & 6 deletions

File tree

embed/prompt.txt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@ You are an autonomous coding agent working on a software project.
77
1. Read the PRD at `{{PRD_PATH}}`
88
2. Read `progress.md` if it exists (check Codebase Patterns section first)
99
3. Pick the **highest priority** user story where `passes: false` -- After determining which story to work on, output exact story id, e.g.: <ralph-status>US-056</ralph-status>
10-
4. Mark the story as `inProgress: true` in the PRD
11-
5. Implement that single user story
12-
6. Run quality checks (e.g., typecheck, lint, test - use whatever your project requires)
13-
7. If checks pass, commit ALL changes with message: `feat: [Story ID] - [Story Title]`
14-
8. Update the PRD to set `passes: true` and `inProgress: false` for the completed story
15-
9. Append your progress to `progress.md`
10+
4. Implement that single user story
11+
5. Run quality checks (e.g., typecheck, lint, test - use whatever your project requires)
12+
6. If checks pass, commit ALL changes with message: `feat: [Story ID] - [Story Title]`
13+
7. Update the PRD to set `passes: true` for the completed story
14+
8. Append your progress to `progress.md`
1615

1716
## Progress Report Format
1817

internal/tui/app.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,17 @@ func (a App) handleLoopEvent(prdName string, event loop.Event) (tea.Model, tea.C
876876
a.prd = p
877877
}
878878
}
879+
880+
// Mark the story as in-progress in the PRD and auto-select it
881+
if event.Type == loop.EventStoryStarted && event.StoryID != "" {
882+
a.markStoryInProgress(event.StoryID)
883+
a.selectStoryByID(event.StoryID)
884+
}
885+
886+
// Clear in-progress when the PRD completes or the loop stops
887+
if event.Type == loop.EventComplete || event.Type == loop.EventError || event.Type == loop.EventMaxIterationsReached {
888+
a.clearInProgress()
889+
}
879890
}
880891

881892
// Refresh tab bar to show updated state
@@ -1926,6 +1937,49 @@ func (a *App) GetSelectedStory() *prd.UserStory {
19261937
return nil
19271938
}
19281939

1940+
// markStoryInProgress clears any existing in-progress flags and marks the
1941+
// given story as in-progress, then saves the PRD to disk.
1942+
func (a *App) markStoryInProgress(storyID string) {
1943+
for i := range a.prd.UserStories {
1944+
a.prd.UserStories[i].InProgress = a.prd.UserStories[i].ID == storyID
1945+
}
1946+
_ = a.prd.Save(a.prdPath)
1947+
}
1948+
1949+
// clearInProgress clears all in-progress flags and saves the PRD to disk.
1950+
func (a *App) clearInProgress() {
1951+
dirty := false
1952+
for i := range a.prd.UserStories {
1953+
if a.prd.UserStories[i].InProgress {
1954+
a.prd.UserStories[i].InProgress = false
1955+
dirty = true
1956+
}
1957+
}
1958+
if dirty {
1959+
_ = a.prd.Save(a.prdPath)
1960+
}
1961+
}
1962+
1963+
// selectStoryByID sets the selected index to the story with the given ID.
1964+
func (a *App) selectStoryByID(storyID string) {
1965+
for i, story := range a.prd.UserStories {
1966+
if story.ID == storyID {
1967+
a.selectedIndex = i
1968+
return
1969+
}
1970+
}
1971+
}
1972+
1973+
// selectInProgressStory sets the selected index to the first in-progress story.
1974+
func (a *App) selectInProgressStory() {
1975+
for i, story := range a.prd.UserStories {
1976+
if story.InProgress {
1977+
a.selectedIndex = i
1978+
return
1979+
}
1980+
}
1981+
}
1982+
19291983
// GetState returns the current app state.
19301984
func (a *App) GetState() AppState {
19311985
return a.state
@@ -2011,6 +2065,9 @@ func (a App) handlePRDUpdate(msg PRDUpdateMsg) (tea.Model, tea.Cmd) {
20112065
a.selectedIndex = 0
20122066
}
20132067
}
2068+
2069+
// Auto-select the in-progress story so the user sees its details
2070+
a.selectInProgressStory()
20142071
}
20152072

20162073
// Continue listening for changes

0 commit comments

Comments
 (0)