Go 73 lines
package memory
import (
"bytes"
"fmt"
"os"
)
// WriteIndex regenerates <MemoryDir>/MEMORY.md from facts. The file is
// overwritten on each call; users are not expected to edit it by hand.
// The index lists facts sorted by name, with pinned facts grouped under
// a "## pinned" heading and disabled facts under a "## disabled"
// heading at the bottom for at-a-glance separation.
func (s *Store) WriteIndex(facts []*Fact) error {
var buf bytes.Buffer
buf.WriteString("# memory index\n\n")
buf.WriteString("Regenerated by eeco; do not edit by hand.\n")
buf.WriteString("Run `eeco gc` to refresh and prune.\n\n")
if len(facts) == 0 {
buf.WriteString("_(empty — no facts recorded yet)_\n")
return os.WriteFile(s.indexPath(), buf.Bytes(), 0o644)
}
// A disabled fact is bucketed regardless of its pin state: every
// muted adaptation belongs in one place so an audit of "what the AI
// has turned off" is a single glance at the "## disabled" section.
var active, pinned, disabled []*Fact
for _, f := range sortedFacts(facts) {
switch {
case f.Disabled:
disabled = append(disabled, f)
case f.Pin:
pinned = append(pinned, f)
default:
active = append(active, f)
}
}
if len(active) == 0 {
buf.WriteString("_(no active facts)_\n")
} else {
for _, f := range active {
writeIndexLine(&buf, f)
}
}
if len(pinned) > 0 {
buf.WriteString("\n## pinned\n\n")
for _, f := range pinned {
writeIndexLine(&buf, f)
}
}
if len(disabled) > 0 {
buf.WriteString("\n## disabled\n\n")
for _, f := range disabled {
writeIndexLine(&buf, f)
}
}
return os.WriteFile(s.indexPath(), buf.Bytes(), 0o644)
}
func (s *Store) indexPath() string {
return s.MemoryDir + "/" + IndexFilename
}
func writeIndexLine(buf *bytes.Buffer, f *Fact) {
fmt.Fprintf(buf, "- **%s** (%s, last_used %s) — %s\n",
f.Name, f.Type, f.LastUsed.UTC().Format(DateLayout), f.Description)
}