`) + b.WriteString(fmt.Sprintf(`

Memory (%d files)

`, data.TotalFiles)) + + idx := 0 + + // Section 1: Global Instructions + if len(data.Global) > 0 { + b.WriteString(`
`) + b.WriteString(fmt.Sprintf(`

Global Instructions (%d)

`, len(data.Global))) + b.WriteString(`
`) + for _, f := range data.Global { + renderMemoryFileCard(&b, f, idx) + idx++ + } + b.WriteString(`
`) + } + + // Section 2: User Rules + if len(data.Rules) > 0 { + b.WriteString(`
`) + b.WriteString(fmt.Sprintf(`

User Rules (%d)

`, len(data.Rules))) + b.WriteString(`
`) + for _, f := range data.Rules { + renderMemoryFileCard(&b, f, idx) + idx++ + } + b.WriteString(`
`) + } + + // Section 3: Per-Project Memory + if len(data.Projects) > 0 { + totalProjectFiles := 0 + for _, p := range data.Projects { + totalProjectFiles += len(p.Files) + } + b.WriteString(`
`) + b.WriteString(fmt.Sprintf(`

Project Memory (%d projects, %d files)

`, len(data.Projects), totalProjectFiles)) + + for _, proj := range data.Projects { + badge := `CC` + if proj.Provider == "codex" { + badge = `CX` + } + b.WriteString(`
`) + b.WriteString(fmt.Sprintf(`
%s %s %s
`, + html.EscapeString(proj.Name), badge, html.EscapeString(proj.Path))) + b.WriteString(`
`) + for _, f := range proj.Files { + renderMemoryFileCard(&b, f, idx) + idx++ + } + b.WriteString(`
`) + } + b.WriteString(`
`) + } + + // Section 4: Codex Memories + if len(data.CodexMem) > 0 { + b.WriteString(`
`) + b.WriteString(fmt.Sprintf(`

Codex Memories (%d)

`, len(data.CodexMem))) + b.WriteString(`
`) + for _, f := range data.CodexMem { + renderMemoryFileCard(&b, f, idx) + idx++ + } + b.WriteString(`
`) + } + + if data.TotalFiles == 0 { + b.WriteString(`
No memory or instruction files found.
`) + } + + b.WriteString(`