// ingestion/internal/wiki/index.go package wiki import ( "fmt" "strings" "github.com/mathiasbq/hyperguild/ingestion/internal/brainfs" "github.com/mathiasbq/hyperguild/ingestion/internal/textutil" ) // RebuildIndex writes brain/wiki/index.md from the current wiki contents. func RebuildIndex(brainDir, date string) error { inv, err := LoadInventory(brainDir) if err != nil { return fmt.Errorf("load inventory: %w", err) } bfs, err := brainfs.Open(brainDir) if err != nil { return fmt.Errorf("open brain: %w", err) } defer func() { _ = bfs.Close() }() total := len(inv[PageTypeConcept]) + len(inv[PageTypeEntity]) + len(inv[PageTypeSource]) var sb strings.Builder fmt.Fprintf(&sb, "# Wiki Index\n\n") fmt.Fprintf(&sb, "_Updated: %s — %d pages (%d concepts, %d entities, %d sources)_\n\n", date, total, len(inv[PageTypeConcept]), len(inv[PageTypeEntity]), len(inv[PageTypeSource])) for _, pt := range []PageType{PageTypeConcept, PageTypeEntity, PageTypeSource} { entries := inv[pt] if len(entries) == 0 { continue } label := strings.ToUpper(string(pt)[:1]) + string(pt)[1:] fmt.Fprintf(&sb, "## %s\n\n", label) for _, e := range entries { summary := pageFirstSentence(bfs, e) if summary != "" { fmt.Fprintf(&sb, "- [[%s|%s]] — %s\n", e.Slug, e.Title, summary) } else { fmt.Fprintf(&sb, "- [[%s|%s]]\n", e.Slug, e.Title) } } sb.WriteString("\n") } // Written through the brain root, never through a symlink (#158). return bfs.PutRegular("wiki/index.md", []byte(sb.String())) } // pageFirstSentence reads the page through the brain root, regular files // only (hyperguild#157). func pageFirstSentence(bfs *brainfs.Brain, e Entry) string { content, err := bfs.ReadRegular("wiki/" + string(e.Type) + "/" + e.Slug + ".md") if err != nil { return "" } parts := strings.SplitN(string(content), "---", 3) body := string(content) if len(parts) == 3 { body = parts[2] } for _, line := range strings.Split(body, "\n") { line = strings.TrimSpace(line) if line == "" || strings.HasPrefix(line, "#") { continue } return textutil.Truncate(line, 100) } return "" }