package web import ( "context" "net/url" "sourcecraft.dev/bigbes/sr-ht-dolt/beads" "sourcecraft.dev/bigbes/sr-ht-dolt/browse" "sourcecraft.dev/bigbes/sr-ht-dolt/core" ) // memoryView renders the memories `bd remember` writes: config rows keyed // kv.memory., each with the revision its value was last written at. The // row itself is (key, value) and carries no timestamp, so the date comes out of // the history — see beads.BuildMemories for the walk that finds it. // // The reading is not here. It lives in the beads package, which the MCP // surface's list_memories shares; this type is only the View adapter — slug, // label, template, and the hand-off of the request's ref and query. type memoryView struct{} // init registers the Memory view, and registers it *after* Milestones, which is // where the design puts the tab: registration order is tab order (views.go). // // Getting that order is not free here, and the extra line is the whole reason // this comment exists. A package's init functions run in lexical file-name // order, and "memory.go" sorts before "milestones.go" — so registering only // memoryView would put this tab between Beads and Milestones. Registering // milestonesView first claims the slot ahead of it; milestones.go's own init // then re-registers the same view, which RegisterView resolves in place (same // Name), leaving the order alone. Both calls name real views, so a rename or a // removal on either side is a compile error rather than a silently reordered // tab bar. func init() { RegisterView(&milestonesView{}) RegisterView(&memoryView{}) } func (*memoryView) Name() string { return "memory" } func (*memoryView) Label() string { return "Memory" } func (*memoryView) Template() string { return "memory.html" } // Applies is the beads fingerprint plus a config table carrying key and value; // see beads.AppliesMemories. Applies sees table shapes and never rows, so a // tracker that has never had a memory written into it still gets the tab and // renders an empty state — the same contract Milestones has. func (*memoryView) Applies(tables []browse.TableInfo) bool { return beads.AppliesMemories(tables) } // Build reads the memories and dates them from the history. The result is a // *beads.MemoryView, handed to memory.html as its .Data. // // The clock is passed in rather than read inside the projection: staleness is // the one thing on this page that depends on when it was rendered, and timeNow // is the same swappable clock the freshness line uses, so a test pins both at // once. func (*memoryView) Build(ctx context.Context, sess BrowseSession, _ *core.Repo, ref string, query url.Values) (any, error) { data, err := beads.BuildMemories(ctx, sess, ref, query, timeNow()) if err != nil { return nil, err } return data, nil }