startLoopForPRD starts the agent loop for a specific PRD.
(prdName string)
| 724 | |
| 725 | // startLoopForPRD starts the agent loop for a specific PRD. |
| 726 | func (a App) startLoopForPRD(prdName string) (tea.Model, tea.Cmd) { |
| 727 | // Get the PRD directory |
| 728 | prdDir := filepath.Join(a.baseDir, ".chief", "prds", prdName) |
| 729 | |
| 730 | if !git.IsGitRepo(a.baseDir) { |
| 731 | return a.doStartLoop(prdName, prdDir) |
| 732 | } |
| 733 | |
| 734 | branch, err := git.GetCurrentBranch(a.baseDir) |
| 735 | if err != nil { |
| 736 | return a.doStartLoop(prdName, prdDir) |
| 737 | } |
| 738 | |
| 739 | worktreePath := git.WorktreePathForPRD(a.baseDir, prdName) |
| 740 | relWorktreePath := fmt.Sprintf(".chief/worktrees/%s/", prdName) |
| 741 | |
| 742 | // Determine dialog context |
| 743 | isProtected := git.IsProtectedBranch(branch) |
| 744 | anotherRunningInSameDir := a.isAnotherPRDRunningInSameDir(prdName) |
| 745 | |
| 746 | if !isProtected && !anotherRunningInSameDir { |
| 747 | // No conflicts: skip the dialog entirely and start the loop directly |
| 748 | return a.doStartLoop(prdName, prdDir) |
| 749 | } |
| 750 | |
| 751 | var dialogCtx DialogContext |
| 752 | if isProtected { |
| 753 | dialogCtx = DialogProtectedBranch |
| 754 | } else { |
| 755 | dialogCtx = DialogAnotherPRDRunning |
| 756 | } |
| 757 | |
| 758 | // Show the dialog only for protected branch or another PRD running |
| 759 | a.branchWarning.SetSize(a.width, a.height) |
| 760 | a.branchWarning.SetContext(branch, prdName, relWorktreePath) |
| 761 | a.branchWarning.SetDialogContext(dialogCtx) |
| 762 | a.branchWarning.Reset() |
| 763 | a.pendingStartPRD = prdName |
| 764 | a.pendingWorktreePath = worktreePath |
| 765 | a.viewMode = ViewBranchWarning |
| 766 | return a, nil |
| 767 | } |
| 768 | |
| 769 | // isAnotherPRDRunningInSameDir checks if another PRD is running in the project root (no worktree). |
| 770 | func (a *App) isAnotherPRDRunningInSameDir(prdName string) bool { |
no test coverage detected