Lossless Changelog
fleet

SortControls land on the ai-labs splash — convention closure modulo llms.txt

The changelog and context-v list pages now carry a Modified / Created / Published / Title chip-group plus a direction toggle, with per-page localStorage persistence and server-pre-sorted defaults so the static HTML reads correctly with JS off. Single follow-up remains for full skill conformance: the /llms.txt + /llms-full.txt endpoints.

Michael StatonMusic Editoraugmented with Claude Code on Claude Opus 4.7 (1M context)

Why Care?

The maintain-splash-pages skill specifies a <SortControls> component on the /changelog/ and /context-v/ list pages: four sort keys (Modified, Created, Published, Title), per-page localStorage persistence, server-pre-sorted default so the static HTML matches the UI default before JS hydrates. The ai-labs splash had a fixed server-side sort and no way for a reader to flip the order. This entry closes that gap, lifted from lfm/splash with the localStorage namespace adapted.

After this lands, the only remaining skill gap is the /llms.txt + /llms-full.txt endpoints — a mechanical port from the two children that already ship them.

What's New?

  • splash/src/components/SortControls.astro — chip-group radio for the four sort keys + a direction toggle that adapts its label to value type (dates flip "Newest first / Oldest first", titles flip "A → Z / Z → A"). Adapted from lfm/splash with one change: localStorage namespace is ai-labs-splash-sort:<name> (matching the splash's existing ai-labs-splash-mode mode-toggle convention).

  • changelog/index.astro carries <SortControls name="changelog" ...> above its <ul>. The <ul> is annotated data-sort-target="changelog". Each <li> carries data-sort-modified, data-sort-created, data-sort-published, data-sort-title — ISO date strings for the three date keys (lex-sort works as time-order), lowercased text for title. Empty values sink to the bottom regardless of direction.

  • context-v/index.astro carries one <SortControls name="context-v" ...> above all five section blocks (specs, explorations, plans, prompts, reminders). Each section's <ul> carries data-sort-target="context-v". The component's JS finds all five lists on click and sorts each independently — so when you sort by title, each section's entries reorder alphabetically within that section and the visual section-grouping stays intact. That's actually a better UX than collapsing everything into one big list.

  • Server pre-sort matches the SortControls default (modified desc) so the page reads correctly with JS off or before hydration. Once JS loads, the component restores any persisted choice from localStorage.

How the data flow works

                  ┌─────────────────────────┐
                  │  /context-v/  page      │
                  └────────┬────────────────┘
                           │
              ┌────────────┼────────────┐
              │            │            │
              ▼            ▼            ▼
    SortControls       counts strip    section blocks
    (one)                              (five <ul>s, all data-sort-target="context-v")
              │
              │  user clicks "Title"
              │  user toggles "A → Z"
              ▼
    document.querySelectorAll('[data-sort-target="context-v"]')
              │
              ▼
    five <ul>s reorder independently
    each <li> sorted by data-sort-title lex
              │
              ▼
    localStorage.setItem('ai-labs-splash-sort:context-v', {key:'title', direction:'asc'})

Next page-load: the JS reads the persisted state, repaints the chip-group + arrow label, and re-runs sortAll() if the persisted state differs from the server-default.

Verification

$ rm -rf dist && pnpm build
... 43 page(s) built in 1.21s
[pagefind] Pagefind indexed 43 pages

$ grep -oE 'data-sort-target="context-v"' dist/context-v/index.html | wc -l
5

$ grep -oE 'data-sort-key="(modified|created|published|title)"' dist/changelog/index.html | wc -l
4

Five data-sort-target markers on the context-v page (one per section); four chips on the changelog page (Modified / Created / Published / Title). The Pagefind index count is unchanged in shape — list pages remain data-pagefind-ignore="all" and stay out of search results.

Skill acceptance status after this entry

✅ splash/ at repo root, astro.config.mjs correct site + base
✅ private:true, name correct, tsconfig path aliases
✅ pnpm install --ignore-workspace && pnpm build succeeds clean
✅ dist/ has /, /search/, /changelog/, /context-v/, detail routes
✅ pagefind/pagefind-entry.json present (38 pages indexed)
✅ .github/workflows/pages.yml exists with deploy-pages@v4 + enablement
✅ First deploy reaches the URL (via master; main env-rule still pending)
✅ Mode toggle works light/dark/vibrant (visual — confirmed earlier)
✅ Search returns results when typing
✅ Sort controls reorder correctly; default date_modified desc (this entry)
⏸️  /llms.txt + /llms-full.txt endpoints — last remaining gap
  • The skill section: Sort controls on list pages in maintain-splash-pages.md.

  • The reference impl that got cribbed: lfm/splash/src/components/SortControls.astro.

  • The Pagefind shipment that landed earlier: 2026-05-11_03.md.