RunEdit edits an existing PRD by launching an interactive Claude session.
(opts EditOptions)
| 19 | |
| 20 | // RunEdit edits an existing PRD by launching an interactive Claude session. |
| 21 | func RunEdit(opts EditOptions) error { |
| 22 | // Set defaults |
| 23 | if opts.Name == "" { |
| 24 | opts.Name = "main" |
| 25 | } |
| 26 | if opts.BaseDir == "" { |
| 27 | cwd, err := os.Getwd() |
| 28 | if err != nil { |
| 29 | return fmt.Errorf("failed to get current directory: %w", err) |
| 30 | } |
| 31 | opts.BaseDir = cwd |
| 32 | } |
| 33 | |
| 34 | // Validate name |
| 35 | if !isValidPRDName(opts.Name) { |
| 36 | return fmt.Errorf("invalid PRD name %q: must contain only letters, numbers, hyphens, and underscores", opts.Name) |
| 37 | } |
| 38 | |
| 39 | // Build the PRD directory path |
| 40 | prdDir := filepath.Join(opts.BaseDir, ".chief", "prds", opts.Name) |
| 41 | prdMdPath := filepath.Join(prdDir, "prd.md") |
| 42 | |
| 43 | // Check if prd.md exists |
| 44 | if _, err := os.Stat(prdMdPath); os.IsNotExist(err) { |
| 45 | return fmt.Errorf("PRD not found at %s. Use 'chief new %s' to create it first", prdMdPath, opts.Name) |
| 46 | } |
| 47 | |
| 48 | // Get the edit prompt with the PRD directory path |
| 49 | prompt := embed.GetEditPrompt(prdDir) |
| 50 | if opts.Provider == nil { |
| 51 | return fmt.Errorf("edit command requires Provider to be set") |
| 52 | } |
| 53 | |
| 54 | // Launch interactive agent session |
| 55 | fmt.Printf("Editing PRD at %s...\n", prdDir) |
| 56 | fmt.Printf("Launching %s to help you edit your PRD...\n", opts.Provider.Name()) |
| 57 | fmt.Println() |
| 58 | |
| 59 | if err := runInteractiveAgent(opts.Provider, opts.BaseDir, prompt); err != nil { |
| 60 | return fmt.Errorf("%s session failed: %w", opts.Provider.Name(), err) |
| 61 | } |
| 62 | |
| 63 | fmt.Println("\nPRD editing complete!") |
| 64 | |
| 65 | // Validate the edited prd.md can be parsed |
| 66 | if _, err := prd.ParseMarkdownPRD(prdMdPath); err != nil { |
| 67 | fmt.Printf("Warning: prd.md could not be parsed: %v\n", err) |
| 68 | } |
| 69 | |
| 70 | fmt.Printf("\nYour PRD is updated! Run 'chief' or 'chief %s' to continue working on it.\n", opts.Name) |
| 71 | return nil |
| 72 | } |