package memory import ( "bytes" "fmt" "os" ) // WriteIndex regenerates /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) }