opencode/internal/llm/prompt/prompt.go
Sam Ottenhoff f3dccad54b Handle new Cursor rules format
1. Check if a path ends with a slash (/)
2. If it does, treat it as a directory and read all files within it
3. For directories like .cursor/rules/, it will scan all files and include their content in the prompt
4. Each file from a directory will be prefixed with "# From filename" for clarity
2025-04-27 14:17:06 +02:00

84 lines
2.2 KiB
Go

package prompt
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/opencode-ai/opencode/internal/config"
"github.com/opencode-ai/opencode/internal/llm/models"
)
// contextFiles is a list of potential context files to check for
var contextFiles = []string{
".github/copilot-instructions.md",
".cursorrules",
".cursor/rules/", // Directory containing multiple rule files
"CLAUDE.md",
"CLAUDE.local.md",
"opencode.md",
"opencode.local.md",
"OpenCode.md",
"OpenCode.local.md",
"OPENCODE.md",
"OPENCODE.local.md",
}
func GetAgentPrompt(agentName config.AgentName, provider models.ModelProvider) string {
basePrompt := ""
switch agentName {
case config.AgentCoder:
basePrompt = CoderPrompt(provider)
case config.AgentTitle:
basePrompt = TitlePrompt(provider)
case config.AgentTask:
basePrompt = TaskPrompt(provider)
default:
basePrompt = "You are a helpful assistant"
}
if agentName == config.AgentCoder || agentName == config.AgentTask {
// Add context from project-specific instruction files if they exist
contextContent := getContextFromFiles()
if contextContent != "" {
return fmt.Sprintf("%s\n\n# Project-Specific Context\n%s", basePrompt, contextContent)
}
}
return basePrompt
}
// getContextFromFiles checks for the existence of context files and returns their content
func getContextFromFiles() string {
workDir := config.WorkingDirectory()
var contextContent string
for _, path := range contextFiles {
// Check if path ends with a slash (indicating a directory)
if strings.HasSuffix(path, "/") {
// Handle directory - read all files within it
dirPath := filepath.Join(workDir, path)
files, err := os.ReadDir(dirPath)
if err == nil {
for _, file := range files {
if !file.IsDir() {
filePath := filepath.Join(dirPath, file.Name())
content, err := os.ReadFile(filePath)
if err == nil {
contextContent += fmt.Sprintf("\n# From %s\n%s\n", file.Name(), string(content))
}
}
}
}
} else {
// Handle individual file as before
filePath := filepath.Join(workDir, path)
content, err := os.ReadFile(filePath)
if err == nil {
contextContent += fmt.Sprintf("\n%s\n", string(content))
}
}
}
return contextContent
}