- Release notes are easy to miss. Breaking changes are not.
-
-
- StackPulse is built for developers who need to know when a framework release,
- dependency update, or package changelog contains work that can affect production code.
+ -
+
+ Read every changelog.
+
+
+
+
+ +
+
+ Review what breaks.
+
-
- {releaseSignals.map((signal) => (
-
-
- {signal.label}
-
-
- {signal.title}
-
-
{signal.body}
-
- ))}
-
-
-
- {/* How it works */}
-
-
-
- § how_it_works
-
-
- 3 steps
-
-
-
-
-
- How StackPulse tracks GitHub releases and turns them into AI-summarised digests.
-
+ Track GitHub releases for the libraries you ship with. StackPulse reads every
+ changelog and leaves review comments on the ones that matter: breaking changes,
+ deprecations, and migration notes, each linked to its source.
+
+
+
+
+ Sign in with GitHub
- ))}
+
+ Browse the public feed
+
+
+ Source ↗
+
+
-
- missing one? add any github repo from onboarding
-
- add custom →
-
+
- Free, open-source, no paywall. Sign in with GitHub and start tracking framework
- releases, breaking changes, and deprecation notes in under a minute.
+
+
+
+
+ example}
+ title="Your feed, as a review"
>
- $
- ./browse-public-feed
- →
-
-
+ @@ 5 releases since your last read @@
+ {exampleReleases.map((release, i) => (
+
StackPulse is a non-profit, open-source service that helps developers track GitHub release
notes for the libraries they use. We try to collect as little as possible. This page
diff --git a/src/app/skills/[slug]/page.tsx b/src/app/skills/[slug]/page.tsx
index 7e4f1c2..d604b55 100644
--- a/src/app/skills/[slug]/page.tsx
+++ b/src/app/skills/[slug]/page.tsx
@@ -1,6 +1,6 @@
import type { Metadata } from 'next'
-import Link from 'next/link'
import { notFound } from 'next/navigation'
+import { PageIntro } from '@/components/review/review-ui'
import { SkillDate, SkillPanel, SkillShell, UpdateRows } from '@/components/skills/skill-ui'
import { SKILL_CATALOG, skillSourceUrl } from '@/lib/skill-catalog'
import { getPublicSkill, skillCheckLabel } from '@/lib/public-skills'
@@ -28,14 +28,15 @@ export default async function SkillPage({ params }: Props) {
const { skill, updates } = data
return (
-
- ← all skills
-
-
- {skill.name}
- .
-
-
{skill.description}
+
{skill.repository}
diff --git a/src/app/skills/[slug]/updates/[updateId]/page.tsx b/src/app/skills/[slug]/updates/[updateId]/page.tsx
index ce6b61d..b1f2c01 100644
--- a/src/app/skills/[slug]/updates/[updateId]/page.tsx
+++ b/src/app/skills/[slug]/updates/[updateId]/page.tsx
@@ -1,6 +1,6 @@
import type { Metadata } from 'next'
-import Link from 'next/link'
import { notFound } from 'next/navigation'
+import { PageIntro } from '@/components/review/review-ui'
import { SkillDate, SkillPanel, SkillShell } from '@/components/skills/skill-ui'
import { getPublicSkillUpdate, skillAnalysisLabel } from '@/lib/public-skills'
@@ -37,20 +37,28 @@ export default async function SkillUpdatePage({ params }: Props) {
}
return (
-
- ← {skill.name} history
-
-
+
-
-
-
+
+
+
)
diff --git a/src/app/skills/page.tsx b/src/app/skills/page.tsx
index cb5dfe0..bbe5113 100644
--- a/src/app/skills/page.tsx
+++ b/src/app/skills/page.tsx
@@ -1,5 +1,6 @@
import type { Metadata } from 'next'
import Link from 'next/link'
+import { PageIntro } from '@/components/review/review-ui'
import { SkillDate, SkillPanel, SkillShell, UpdateRows } from '@/components/skills/skill-ui'
import { getPublicSkills, skillCheckLabel } from '@/lib/public-skills'
@@ -19,19 +20,13 @@ export default async function SkillsPage() {
const { skills, updates } = await getPublicSkills()
return (
-
- § agent skill intelligence · phase 1
-
-
- instructions change.
-
- understand the impact.
-
-
- Source changes, potential behavior shifts, and advisory update assessments for ten curated
- skills. Compare immutable revisions before changing your pinned copy.
-
-
+
+
{[
['curated', skills.length],
['baselined', skills.filter((s) => s.baselineRevision).length],
diff --git a/src/app/stacks/[slug]/loading.tsx b/src/app/stacks/[slug]/loading.tsx
index 6cef2f0..de7980a 100644
--- a/src/app/stacks/[slug]/loading.tsx
+++ b/src/app/stacks/[slug]/loading.tsx
@@ -1,10 +1,6 @@
-import Link from 'next/link'
-import { ArrowLeft01Icon } from 'hugeicons-react'
-
-import { Logo } from '@/components/logo'
-import { ThemeSwitcher } from '@/components/theme-switcher'
-import { Skeleton } from '@/components/ui/skeleton'
+import { SiteHeader } from '@/components/site/site-header'
import { PulseLoader } from '@/components/ui/pulse-loader'
+import { Skeleton } from '@/components/ui/skeleton'
// `params` and `searchParams` are URL-specific, so Partial Prefetching shares this App
// Shell across every stack link instead of rendering every slug ahead of time. Chrome and
@@ -12,103 +8,66 @@ import { PulseLoader } from '@/components/ui/pulse-loader'
export default function StackPageLoading() {
return (
+
+ {data.tech.name} releases from GitHub.{' '}
+
+ StackPulse watches {data.tech.name} release notes and keeps the original source link
+ close to every summary.
+
+
+
+ Breaking changes and deprecations.{' '}
+
+ Risky changes are separated from normal feature notes so you can scan upgrade impact
+ before changing production dependencies.
+
+
+
+ Source-backed next steps.{' '}
+
+ Migration steps and recommended actions are only shown when the upstream release
+ notes support them.
+
+
- no releases have been indexed for this stack yet.
-
-
- follow it from the dashboard to start collecting release notes.
-
-
+
+
+ Follow this stack from the dashboard to start collecting its release notes. New
+ releases are fetched at 00:00 and 12:00 UTC.
+
+
) : filteredReleases.length === 0 ? (
-
-
- no releases match the {signalFilter} filter.
-
-
- try viewing all indexed releases for this stack.
-
diff --git a/src/app/stacks/[slug]/upgrade/page.tsx b/src/app/stacks/[slug]/upgrade/page.tsx
index 77eb009..086ad69 100644
--- a/src/app/stacks/[slug]/upgrade/page.tsx
+++ b/src/app/stacks/[slug]/upgrade/page.tsx
@@ -1,10 +1,19 @@
import type { Metadata } from 'next'
import Link from 'next/link'
import { notFound } from 'next/navigation'
-import { ArrowLeft01Icon } from 'hugeicons-react'
+import { GitCompareIcon } from 'hugeicons-react'
-import { Logo } from '@/components/logo'
-import { ThemeSwitcher } from '@/components/theme-switcher'
+import {
+ CardNote,
+ FileCard,
+ MergeBox,
+ PageIntro,
+ StatGrid,
+ button,
+ cx,
+} from '@/components/review/review-ui'
+import { SiteFooter } from '@/components/site/site-footer'
+import { SiteHeader } from '@/components/site/site-header'
import { getUpgradePlan, type UpgradePlanItem } from '@/lib/upgrade-plan'
type Props = {
@@ -48,159 +57,166 @@ export default async function UpgradePlannerPage({ params, searchParams }: Props
if (!plan) notFound()
const hasRange = plan.fromIsValid && plan.fromVersion !== null
+ const latest = plan.latest?.version ?? 'latest'
return (
-
-
-
-
-
-
+
-
-
- #
- stacks/{plan.tech.slug}/upgrade
-
+
+
+ Enter the version you run today. StackPulse lines up every stored breaking change,
+ deprecation, security note, and migration step between it and{' '}
+ {plan.latest ? (
+ {plan.latest.version}
+ ) : (
+ 'the latest release'
+ )}
+ .
+ >
+ }
+ />
-
- upgrade {plan.tech.name.toLowerCase()}
- .
-
-
- Enter the version you run today. StackPulse lines up every stored breaking change,
- deprecation, security note, and migration step between it and{' '}
- {plan.latest ? (
- {plan.latest.version}
- ) : (
- 'the latest release'
- )}
- .
-