Refresh reloads the list of PRDs from the .chief/prds/ directory.
()
| 97 | |
| 98 | // Refresh reloads the list of PRDs from the .chief/prds/ directory. |
| 99 | func (p *PRDPicker) Refresh() { |
| 100 | p.entries = make([]PRDEntry, 0) |
| 101 | |
| 102 | prdsDir := filepath.Join(p.basePath, ".chief", "prds") |
| 103 | |
| 104 | // Read the prds directory |
| 105 | entries, err := os.ReadDir(prdsDir) |
| 106 | if err != nil { |
| 107 | // Directory might not exist - that's okay, but still check for current PRD |
| 108 | entries = nil |
| 109 | } |
| 110 | |
| 111 | // Track names we've added to avoid duplicates |
| 112 | addedNames := make(map[string]bool) |
| 113 | |
| 114 | for _, entry := range entries { |
| 115 | if !entry.IsDir() { |
| 116 | continue |
| 117 | } |
| 118 | |
| 119 | name := entry.Name() |
| 120 | dirPath := filepath.Join(prdsDir, name) |
| 121 | prdPath := filepath.Join(dirPath, "prd.md") |
| 122 | |
| 123 | // Skip directories without prd.md (empty/incomplete) |
| 124 | if _, err := os.Stat(prdPath); os.IsNotExist(err) { |
| 125 | continue |
| 126 | } |
| 127 | |
| 128 | prdEntry := p.loadPRDEntry(name, prdPath) |
| 129 | p.entries = append(p.entries, prdEntry) |
| 130 | addedNames[name] = true |
| 131 | } |
| 132 | |
| 133 | // Also check if there's a "main" PRD directly in .chief/ (legacy location) |
| 134 | mainPrdPath := filepath.Join(p.basePath, ".chief", "prd.md") |
| 135 | if _, err := os.Stat(mainPrdPath); err == nil && !addedNames["main"] { |
| 136 | prdEntry := p.loadPRDEntry("main", mainPrdPath) |
| 137 | p.entries = append(p.entries, prdEntry) |
| 138 | addedNames["main"] = true |
| 139 | } |
| 140 | |
| 141 | // Detect orphaned worktrees - worktrees on disk not tracked by any manager instance |
| 142 | diskWorktrees := git.DetectOrphanedWorktrees(p.basePath) |
| 143 | if len(diskWorktrees) > 0 { |
| 144 | // Build set of tracked worktree dirs from manager |
| 145 | trackedDirs := make(map[string]bool) |
| 146 | if p.manager != nil { |
| 147 | for _, inst := range p.manager.GetAllInstances() { |
| 148 | if inst.WorktreeDir != "" { |
| 149 | trackedDirs[inst.WorktreeDir] = true |
| 150 | } |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | for prdName, absPath := range diskWorktrees { |
| 155 | if trackedDirs[absPath] { |
| 156 | continue // This worktree is tracked by a running/registered PRD |