1package prompt
2
3import (
4 _ "embed"
5 "fmt"
6 "log/slog"
7 "os"
8 "path/filepath"
9 "runtime"
10 "time"
11
12 "github.com/charmbracelet/crush/internal/config"
13 "github.com/charmbracelet/crush/internal/llm/tools"
14)
15
16func CoderPrompt(p string, contextFiles ...string) string {
17 var basePrompt string
18
19 basePrompt = string(baseCoderPrompt)
20 envInfo := getEnvironmentInfo()
21
22 basePrompt = fmt.Sprintf("%s\n\n%s\n%s", basePrompt, envInfo, lspInformation())
23
24 contextContent := getContextFromPaths(config.Get().WorkingDir(), contextFiles)
25 slog.Debug("Context content", "Context", contextContent)
26 if contextContent != "" {
27 return fmt.Sprintf("%s\n\n# Project-Specific Context\n Make sure to follow the instructions in the context below\n%s", basePrompt, contextContent)
28 }
29 return basePrompt
30}
31
32//go:embed coder.md
33var baseCoderPrompt []byte
34
35func getEnvironmentInfo() string {
36 cwd := config.Get().WorkingDir()
37 isGit := isGitRepo(cwd)
38 platform := runtime.GOOS
39 date := time.Now().Format("1/2/2006")
40 output, _ := tools.ListDirectoryTree(cwd, nil)
41 return fmt.Sprintf(`Here is useful information about the environment you are running in:
42<env>
43Working directory: %s
44Is directory a git repo: %s
45Platform: %s
46Today's date: %s
47</env>
48<project>
49%s
50</project>
51 `, cwd, boolToYesNo(isGit), platform, date, output)
52}
53
54func isGitRepo(dir string) bool {
55 _, err := os.Stat(filepath.Join(dir, ".git"))
56 return err == nil
57}
58
59func lspInformation() string {
60 cfg := config.Get()
61 hasLSP := false
62 for _, v := range cfg.LSP {
63 if !v.Disabled {
64 hasLSP = true
65 break
66 }
67 }
68 if !hasLSP {
69 return ""
70 }
71 return `# LSP Information
72Tools that support it will also include useful diagnostics such as linting and typechecking.
73- These diagnostics will be automatically enabled when you run the tool, and will be displayed in the output at the bottom within the <file_diagnostics></file_diagnostics> and <project_diagnostics></project_diagnostics> tags.
74- Take necessary actions to fix the issues.
75- You should ignore diagnostics of files that you did not change or are not related or caused by your changes unless the user explicitly asks you to fix them.
76`
77}
78
79func boolToYesNo(b bool) string {
80 if b {
81 return "Yes"
82 }
83 return "No"
84}