Repository navigation
Redesign livepeer.org - #93
adamsoffer wants to merge 178 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
🔵 Needs a closer look
One or more issues must be addressed before approval.
6 open findings
Unbounded fetch can indefinitely block page rendering Async root layout cannot be a Client Component Notion signature prefix is constructed incorrectly Versioned cover URLs serve mismatched artwork Unauthenticated media lookup enables rate-limit abuse and draft leaks Intro lookup can select a draft over the published entry
🧠 Review effort: Lite
From the Wayback Machine's index of livepeer.org and blog.livepeer.org (748 page addresses), tested against the new site: the 2021 site's locale prefixes (/en/primer, /ko/delegators) drop and resolve; the old on-site docs go to docs.livepeer.org; /jobs/* and the Livepeer.tv pages go home; retired page names (/about, /delegators, /orchestrators, /grants, /pricing, /use-cases/*) go to their successors; the Ghost blog's /rss, tag and author pages go to the feed and the index; and /ecosystem/livepeer-studio, the one address that worked on the old site and not this one, goes to the catalogue. What still 404s is nine old Daydream posts and Ghost's API paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A stack of contributor faces set against the owner's name read as that owner's people, and the register credits people from other bodies on work an organisation owns (Rick Staa, of the Foundation, on Livepeer Inc's network readiness). The card now reads "by Livepeer Inc led by [face] Qiang Han": the one person to ask, named, with what they are to the work. Contributors stay on the record, in their own row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
One or more issues must be addressed before approval.
7 open findings
Exclude placeholder files from roadmap fallback · New Unbounded fetch can indefinitely block page rendering Notion signature prefix is constructed incorrectly Versioned cover URLs serve mismatched artwork Unauthenticated media lookup enables rate-limit abuse and draft leaks Include generated records in sitemap · New Intro lookup can select a draft over the published entry
🧠 Review effort: Lite
| --- | ||
| title: Burn-Mint Equilibrium | ||
| outcome: Connect LPT issuance to network usage, so rewards follow demand rather than a fixed schedule. | ||
| workstream: Protocol | ||
| state: next |
| return [ | ||
| ...staticRoutes, | ||
| ...ecosystemEntries, | ||
| ...categoryEntries, | ||
| ...blogEntries, | ||
| ...changelogEntries, | ||
| ...legalEntries, | ||
| ]; |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The card's credit goes back to its original shape, the owner and a face with the name in a tooltip, but the face is the lead's rather than the contributors', so nobody from another body reads as the owner's staff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A monogram beside the owner's name read as a second, unexplained badge, so a card whose lead has no photograph names the owner alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
One or more issues must be addressed before approval.
8 open findings
Draft posts can expose publicly cached cover images · New Exclude placeholder files from roadmap fallback Unbounded fetch can indefinitely block page rendering Notion signature prefix is constructed incorrectly Versioned cover URLs serve mismatched artwork Unauthenticated media lookup enables rate-limit abuse and draft leaks Include generated records in sitemap Intro lookup can select a draft over the published entry
🧠 Review effort: Lite
| const { id } = await params; | ||
| if (!PAGE_ID.test(id) || !hasNotionCredentials()) { | ||
| return new Response(null, { status: 404 }); | ||
| } | ||
| const file = await getNotionBlogCover(id).catch(() => null); | ||
| if (!file) return new Response(null, { status: 404 }); |
There was a problem hiding this comment.
🟡 Changes recommended
One or more issues must be addressed before approval.
9 open findings
Unauthenticated cover proxy exposes draft post covers · New Draft posts can expose publicly cached cover images Exclude placeholder files from roadmap fallback Unbounded fetch can indefinitely block page rendering Notion signature prefix is constructed incorrectly Versioned cover URLs serve mismatched artwork Unauthenticated media lookup enables rate-limit abuse and draft leaks Include generated records in sitemap Intro lookup can select a draft over the published entry
🧠 Review effort: Lite
| /** | ||
| * A blog post's cover when it was uploaded into Notion rather than taken from | ||
| * the stock library. | ||
| * | ||
| * Notion signs an upload's link for about an hour, and a cover outlives that | ||
| * on the index, the post and every timeline it is shared to. So the site | ||
| * serves the image itself, from an address that carries a version | ||
| * (uploadedCover in lib/notion.ts): fetched fresh from Notion here, cached for | ||
| * good, and replaced by a new address when the cover changes. The image | ||
| * bytes, not a redirect, so next/image can optimize it like any other cover. | ||
| * Only covers of rows in Blog posts are served (getNotionBlogCover). | ||
| */ | ||
|
|
||
| const PAGE_ID = | ||
| /^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$/i; | ||
|
|
||
| export async function GET( | ||
| _request: Request, | ||
| { params }: { params: Promise<{ id: string; version: string }> } | ||
| ) { | ||
| const { id } = await params; | ||
| if (!PAGE_ID.test(id) || !hasNotionCredentials()) { | ||
| return new Response(null, { status: 404 }); | ||
| } | ||
| const file = await getNotionBlogCover(id).catch(() => null); | ||
| if (!file) return new Response(null, { status: 404 }); |
Getting involved is something a visitor comes looking for; the brand kit is for the few who need it, and the footer serves them. Contribute gets its share card's art as its thumbnail and "Propose work and get it funded" as its line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The footer had no link to the product the site leads with, so Network opens on Livepeer Agent (the header, which gives Agent its own item, leaves it out of its Network menu). Brand moves beside Terms and Privacy, which brings Resources back to six that read as one list. "X / Twitter" is "X". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🔵 Needs a closer look
One or more issues must be addressed before approval.
9 open findings
Unauthenticated cover proxy exposes draft post covers Draft posts can expose publicly cached cover images Exclude placeholder files from roadmap fallback Unbounded fetch can indefinitely block page rendering Notion signature prefix is constructed incorrectly Versioned cover URLs serve mismatched artwork Unauthenticated media lookup enables rate-limit abuse and draft leaks Include generated records in sitemap Intro lookup can select a draft over the published entry
🧠 Review effort: Lite
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🔵 Needs a closer look
One or more issues must be addressed before approval.
9 open findings
Unauthenticated cover proxy exposes draft post covers Draft posts can expose publicly cached cover images Exclude placeholder files from roadmap fallback Unbounded fetch can indefinitely block page rendering Notion signature prefix is constructed incorrectly Versioned cover URLs serve mismatched artwork Unauthenticated media lookup enables rate-limit abuse and draft leaks Include generated records in sitemap Intro lookup can select a draft over the published entry
🧠 Review effort: Lite
There was a problem hiding this comment.
🔵 Needs a closer look
Unresolved moderate review findings remain across media access, webhook security, filtering, interaction behavior, and content consistency.
9 open findings
Unauthenticated cover proxy exposes draft post covers Draft posts can expose publicly cached cover images Exclude placeholder files from roadmap fallback Unbounded fetch can indefinitely block page rendering Notion signature prefix is constructed incorrectly Versioned cover URLs serve mismatched artwork Unauthenticated media lookup enables rate-limit abuse and draft leaks Include generated records in sitemap Intro lookup can select a draft over the published entry
🧠 Review effort: Lite
The Faces component, its monogram helpers and the roadmap's tooltip provider go with it; nothing else on the register used them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🔵 Needs a closer look
One or more issues must be addressed before approval.
9 open findings
Unauthenticated cover proxy exposes draft post covers Draft posts can expose publicly cached cover images Exclude placeholder files from roadmap fallback Unbounded fetch can indefinitely block page rendering Notion signature prefix is constructed incorrectly Versioned cover URLs serve mismatched artwork Unauthenticated media lookup enables rate-limit abuse and draft leaks Include generated records in sitemap Intro lookup can select a draft over the published entry
🧠 Review effort: Lite
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🔵 Needs a closer look
One or more issues must be addressed before approval.
9 open findings
Unauthenticated cover proxy exposes draft post covers Draft posts can expose publicly cached cover images Exclude placeholder files from roadmap fallback Unbounded fetch can indefinitely block page rendering Notion signature prefix is constructed incorrectly Versioned cover URLs serve mismatched artwork Unauthenticated media lookup enables rate-limit abuse and draft leaks Include generated records in sitemap Intro lookup can select a draft over the published entry
🧠 Review effort: Lite
Latest Updates shared Ecosystem's office photograph, and Roadmap's waves sat beside Contribute's near-identical ones in the Resources menu (Peace Node's note). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t screen Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
January to May 2026 had rows only because the monthly wrap-ups were once written into them; with those moved to the blog they listed as five empty months. An entry with no roadmap rows is now left out unless it has a headline. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Between sm and lg the field wrapped but kept its 16rem width and auto margin, stranded at the right of an empty line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… screen Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lished entry intros, bounded contributors fetch - /api/notion-media serves only ids a page rendered: the link carries an HMAC keyed from the Notion token and the environment, checked before Notion is called, so random ids cannot spend the shared rate limit and a draft's link from a preview does not open on production. - /api/notion-cover checks its version against the current cover and sends an out-of-date address on to the current one, instead of caching a new cover for good under an old version. - getNotionEntryBody takes the published row where a Draft sits beside it, as getNotionEntries does. - getContributors times out after five seconds, so a stalled endpoint reaches the snapshot instead of holding the home and Contribute renders. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Superseded by #126: the same code (identical final tree to 🤖 Generated with Claude Code |


Rebuilds the marketing site against Peace Node's Livepeer UI registry. The registry theme is now the only token layer.
Pages
Nine linked pages, all built from the mockup set except where noted:
//agent/ecosystem/[slug],/submit— markdown-driven catalog/compute/token/foundation/blog/blog/brand/roadmap/primerstays intact and unlinked with its own scoped legacy slice — the one page deliberately left unmigrated.Content is split on its shape and how often it changes. Page copy is authored in-repo as typed objects matching the registry's content contracts (
lib/site.ts) — versioned and reviewed alongside the design it belongs to. Blog and ecosystem are markdown incontent/.Templated content that gets updated frequently moves to Notion, and the roadmap register is the first of it. It is maintained by people across several organisations who do not open pull requests, and a commitment whose state is a week stale is worse than no page at all. The blog is planned next; scope is those two for now, not a general move of the site into a CMS. So this PR is the pattern as much as the page.
lib/notion.tsreads it over plainfetchwith ISR at a minute;content/roadmap/*.mdis the fallback when no workspace token is present, so a clone still builds. Every record carries an owner, a target and a checkable link, and anything missing one fails the build rather than rendering a card that claims less than it should.Cleanup
globals.css1209 → 585 lines. Removed the second--color-*token layer, the Holographik grid, hero classes,.blog-prose, 19 keyframes and 37 custom properties. Chart/sidebar/radius tokens are kept — unused today, but they're the registry's theme contract.Deleted ~73 files:
components/home/*,components/legacy/*,components/ecosystem/*(superseded bycomponents/livepeer-ui/*), the PascalCasecomponents/ui/*visuals,lib/constants.ts, and the fiveapp/use-cases/*routes — redirects innext.config.tsalready served those URLs, so the pages were unreachable.Share images
Rebuilt on the registry's own
ogitem./renders the brand card verbatim — the lockup centred on#000000. Every other page renders the same canvas with a page title, from one sharedlib/og.tsx. Two bugs fixed along the way:twitter-image, and metadata files cascade — so/foundationand/blogserved their ownog:imagebut the root's Twitter card. Every segment now has a re-export beside itsopengraph-image.generateMetadatadeclares anopenGraphobject withoutimages, which drops the inherited card. All 12 projects now get their own titled card.Incidental fixes
app/not-found.tsxstyled its linktext-green— green as an affordance colour, which the design system explicitly rules out. Rebuilt on the registry type scale.sitemap.tsadvertised the five dead/use-casesURLs and never listed/agentor/compute. Rewritten, with ecosystem projects added.package-lock.jsondeleted. Six deps had been added vianpmin a pnpm-pinned repo, leavingpnpm-lock.yamlstale —pnpm install --frozen-lockfilewas failing, which would have broken the Vercel build. Lockfile regenerated and verified.Verification
pnpm typecheck,pnpm lint(0 warnings) andpnpm build(130 static pages) all clean, against both the Notion register and the markdown fallback. Pages verified in light and dark at 390px, sm, md and wide desktop.Open items
None of these block the merge; each is a content or configuration change rather than code.
agentAppOrigin(lib/site.ts) points atearlyaccess.livepeer.org, the console's own address. The Agent playbooks link is the one product link left onlivepeer.peaceno.de: the console has no playbooks page, and a mockup beats a 404.forum.livepeer.org/or similar rather than a permalink.🤖 Generated with Claude Code