-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrules.go
More file actions
90 lines (83 loc) · 1.99 KB
/
rules.go
File metadata and controls
90 lines (83 loc) · 1.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package sight
import (
"os"
"path/filepath"
"strings"
)
// LoadProjectRules scans a directory for project-specific coding rules and
// standards. It looks for:
// - .cursor/rules/*.md
// - CLAUDE.md
// - CONTRIBUTING.md
// - .sight/rules/*.md
//
// Found rules are concatenated with section headers and returned as a single
// string suitable for injection into an LLM system prompt. Returns an empty
// string if no rule files are found.
func LoadProjectRules(dir string) string {
type ruleSource struct {
label string
paths []string
}
sources := []ruleSource{
{
label: "Cursor Rules",
paths: globFiles(filepath.Join(dir, ".cursor", "rules", "*.md")),
},
{
label: "Claude Rules",
paths: fileIfExists(filepath.Join(dir, "CLAUDE.md")),
},
{
label: "Contributing Guidelines",
paths: fileIfExists(filepath.Join(dir, "CONTRIBUTING.md")),
},
{
label: "Sight Rules",
paths: globFiles(filepath.Join(dir, ".sight", "rules", "*.md")),
},
}
var b strings.Builder
for _, src := range sources {
for _, path := range src.paths {
data, err := os.ReadFile(path)
if err != nil {
continue
}
content := strings.TrimSpace(string(data))
if content == "" {
continue
}
if b.Len() > 0 {
b.WriteString("\n\n")
}
b.WriteString("### ")
b.WriteString(src.label)
b.WriteString(" (")
// Show relative path for clarity
rel, err := filepath.Rel(dir, path)
if err != nil {
rel = filepath.Base(path)
}
b.WriteString(rel)
b.WriteString(")\n\n")
b.WriteString(content)
}
}
return b.String()
}
// globFiles returns matching file paths for a glob pattern, or nil on error.
func globFiles(pattern string) []string {
matches, err := filepath.Glob(pattern)
if err != nil || len(matches) == 0 {
return nil
}
return matches
}
// fileIfExists returns a single-element slice if the file exists, or nil.
func fileIfExists(path string) []string {
if _, err := os.Stat(path); err == nil {
return []string{path}
}
return nil
}