Skip to content

Commit b5b49ca

Browse files
committed
fix(learnings): filter search to bullet lines, add path traversal guard, git user config, and human-readable list
1 parent 8713d2e commit b5b49ca

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

service/learnings/store.go

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,27 @@ func (s *Store) Init() error {
3838
if out, err := cmd.CombinedOutput(); err != nil {
3939
return fmt.Errorf("git init: %s: %w", out, err)
4040
}
41+
s.ensureGitUser()
4142
return nil
4243
}
4344

45+
func (s *Store) ensureGitUser() {
46+
for _, key := range []string{"user.name", "user.email"} {
47+
check := exec.Command("git", "config", key)
48+
check.Dir = s.dir
49+
if out, err := check.Output(); err == nil && len(out) > 0 {
50+
continue
51+
}
52+
val := "openbotkit"
53+
if key == "user.email" {
54+
val = "bot@local"
55+
}
56+
set := exec.Command("git", "config", key, val)
57+
set.Dir = s.dir
58+
set.Run()
59+
}
60+
}
61+
4462
func (s *Store) Save(topic string, bullets []string) error {
4563
s.mu.Lock()
4664
defer s.mu.Unlock()
@@ -74,6 +92,9 @@ func (s *Store) Save(topic string, bullets []string) error {
7492
}
7593

7694
func (s *Store) Read(topic string) (string, error) {
95+
if strings.Contains(topic, "..") || strings.ContainsAny(topic, "/\\") {
96+
return "", fmt.Errorf("invalid topic name %q", topic)
97+
}
7798
slug := s.Slug(topic)
7899
path := filepath.Join(s.dir, slug+".md")
79100
data, err := os.ReadFile(path)
@@ -90,12 +111,27 @@ func (s *Store) List() ([]string, error) {
90111
}
91112
var topics []string
92113
for _, e := range entries {
93-
name := strings.TrimSuffix(filepath.Base(e), ".md")
114+
name := s.readTitle(e)
115+
if name == "" {
116+
name = strings.TrimSuffix(filepath.Base(e), ".md")
117+
}
94118
topics = append(topics, name)
95119
}
96120
return topics, nil
97121
}
98122

123+
func (s *Store) readTitle(path string) string {
124+
data, err := os.ReadFile(path)
125+
if err != nil {
126+
return ""
127+
}
128+
first, _, _ := strings.Cut(string(data), "\n")
129+
if strings.HasPrefix(first, "# ") {
130+
return strings.TrimPrefix(first, "# ")
131+
}
132+
return ""
133+
}
134+
99135
func (s *Store) Search(query string) ([]SearchResult, error) {
100136
entries, err := filepath.Glob(filepath.Join(s.dir, "*.md"))
101137
if err != nil {
@@ -110,6 +146,9 @@ func (s *Store) Search(query string) ([]SearchResult, error) {
110146
}
111147
topic := strings.TrimSuffix(filepath.Base(e), ".md")
112148
for _, line := range strings.Split(string(data), "\n") {
149+
if !strings.HasPrefix(line, "- ") {
150+
continue
151+
}
113152
if strings.Contains(strings.ToLower(line), lower) {
114153
results = append(results, SearchResult{Topic: topic, Line: line})
115154
}

0 commit comments

Comments
 (0)