返回 DeepSeek-Reasonix
index.go
根目录 / internal / memory / index.go
1 // The provider-visible memory index: scope-qualified references for every
2 // active fact, override annotations for shadowed global guidance.
3 package memory
4
5 import (
6 "fmt"
7 "sort"
8 "strings"
9 )
10
11 // Index returns the provider-visible index that loads into the cached
12 // prefix: every active fact from both scopes with a scope-qualified
13 // reference, shadowed global facts annotated rather than hidden — the index
14 // agrees with the project-over-global rule recall enforces (#7995). The
15 // per-directory MEMORY.md files keep their unqualified format.
16 func (s Store) Index() string {
17 memories := s.ListAll()
18 if len(memories) == 0 {
19 return ""
20 }
21 shadowed := map[string]string{} // global fact ID -> winning project reference
22 for _, o := range FindOverrides(memories) {
23 shadowed[o.Global.ID] = providerMemoryReference(o.Project)
24 }
25 sort.SliceStable(memories, func(i, j int) bool {
26 if memories[i].Name != memories[j].Name {
27 return memories[i].Name < memories[j].Name
28 }
29 return NormalizeFactScope(string(memories[i].Scope)) == FactScopeProject
30 })
31 var b strings.Builder
32 seen := map[string]bool{} // collapse legacy migration duplicates (same qualified ref)
33 for _, memory := range memories {
34 if ref := providerMemoryReference(memory); seen[ref] {
35 continue
36 } else {
37 seen[ref] = true
38 }
39 b.WriteString(renderQualifiedIndexLine(memory))
40 if winner, ok := shadowed[memory.ID]; ok &&
41 NormalizeFactScope(string(memory.Scope)) == FactScopeGlobal {
42 b.WriteString(" (overridden by " + winner + ")")
43 }
44 b.WriteString("\n")
45 }
46 return b.String()
47 }
48
49 // renderQualifiedIndexLine is the provider-index variant of renderIndexLine:
50 // the link is the scope-qualified reference every memory tool accepts, so a
51 // name collision across scopes can never be misread.
52 func renderQualifiedIndexLine(m Memory) string {
53 marker := ""
54 if ResolveActivation(m) == ActivationPinned {
55 marker = " pinned"
56 }
57 ref := providerMemoryReference(m)
58 return fmt.Sprintf("- [%s](%s) — [%s/%s%s] %s",
59 displayTitle(m.Title, m.Name), ref,
60 NormalizeFactScope(string(m.Scope)), NormalizeType(string(m.Type)), marker, oneLine(m.Description))
61 }
62
62 lines GO