1package prompt
2
3import (
4 "fmt"
5 "os"
6 "path/filepath"
7 "strings"
8
9 "github.com/opencode-ai/opencode/internal/config"
10 "github.com/opencode-ai/opencode/internal/llm/models"
11)
12
13// contextFiles is a list of potential context files to check for
14var contextFiles = []string{
15 ".github/copilot-instructions.md",
16 ".cursorrules",
17 ".cursor/rules/", // Directory containing multiple rule files
18 "CLAUDE.md",
19 "CLAUDE.local.md",
20 "opencode.md",
21 "opencode.local.md",
22 "OpenCode.md",
23 "OpenCode.local.md",
24 "OPENCODE.md",
25 "OPENCODE.local.md",
26}
27
28func GetAgentPrompt(agentName config.AgentName, provider models.ModelProvider) string {
29 basePrompt := ""
30 switch agentName {
31 case config.AgentCoder:
32 basePrompt = CoderPrompt(provider)
33 case config.AgentTitle:
34 basePrompt = TitlePrompt(provider)
35 case config.AgentTask:
36 basePrompt = TaskPrompt(provider)
37 default:
38 basePrompt = "You are a helpful assistant"
39 }
40
41 if agentName == config.AgentCoder || agentName == config.AgentTask {
42 // Add context from project-specific instruction files if they exist
43 contextContent := getContextFromFiles()
44 if contextContent != "" {
45 return fmt.Sprintf("%s\n\n# Project-Specific Context\n%s", basePrompt, contextContent)
46 }
47 }
48 return basePrompt
49}
50
51// getContextFromFiles checks for the existence of context files and returns their content
52func getContextFromFiles() string {
53 workDir := config.WorkingDirectory()
54 var contextContent string
55
56 for _, path := range contextFiles {
57 // Check if path ends with a slash (indicating a directory)
58 if strings.HasSuffix(path, "/") {
59 // Handle directory - read all files within it
60 dirPath := filepath.Join(workDir, path)
61 files, err := os.ReadDir(dirPath)
62 if err == nil {
63 for _, file := range files {
64 if !file.IsDir() {
65 filePath := filepath.Join(dirPath, file.Name())
66 content, err := os.ReadFile(filePath)
67 if err == nil {
68 contextContent += fmt.Sprintf("\n# From %s\n%s\n", file.Name(), string(content))
69 }
70 }
71 }
72 }
73 } else {
74 // Handle individual file as before
75 filePath := filepath.Join(workDir, path)
76 content, err := os.ReadFile(filePath)
77 if err == nil {
78 contextContent += fmt.Sprintf("\n%s\n", string(content))
79 }
80 }
81 }
82
83 return contextContent
84}