buildmymcpserver/apps/web/app/(marketing)/changelog/page.tsx

103 lines
4.3 KiB
TypeScript
Raw Normal View History

import { CodeBlock } from '@/components/code-block';
export const metadata = { title: 'Changelog — BuildMyMCPServer' };
interface Release {
version: string;
date: string;
tag: 'launch' | 'feature' | 'fix';
title: string;
items: string[];
}
const RELEASES: Release[] = [
{
version: '0.2.0',
date: '2026-05-19',
tag: 'feature',
title: '3-step wizard + filled-in pages',
items: [
'Real 3-step wizard: prompt → confirm parsed spec → build. Step 2 shows the tools Claude actually parsed and only asks for the credentials it identified.',
'Preview endpoint: POST /v1/servers/preview runs Claude once, caches the spec 5 min, build worker reuses it. Saves a second Claude round-trip (~30s).',
'Shared @bmm/llm package — system prompt + generateSpec live in one place, used by api and generator.',
'Audit log: writes for login, logout, server.create, server.iterate, server.delete. /v1/audit endpoint + /audit page.',
'Real /settings page (org info, plan & usage, members, encryption status).',
'Full /docs site: quickstart, MCP concepts, OAuth flow, authoring, self-hosting, API reference, FAQ.',
'Changelog, /security, /privacy, /terms, /pricing, /status pages — all marketing links work.',
],
},
{
version: '0.1.0',
date: '2026-05-18',
tag: 'launch',
title: 'Sprints 13 — initial public dev build',
items: [
'Monorepo: Next.js 15 + Fastify + BullMQ generator + runner-template.',
'Drizzle schema for orgs, servers, builds, secrets, oauth, metrics, audit.',
'Magic-link auth, 30-day sessions, AES-256-GCM secret encryption.',
'OAuth 2.1 Authorization Server: PKCE, RFC 7591 dynamic registration, RFC 8707 resource indicators, RS256 JWKS.',
'Runner template with Streamable HTTP + OAuth 2.1 Resource Server.',
'WebSocket build stream: queued → generating → building → deploying → live.',
'Install snippet generator for Claude Desktop, Cursor, ChatGPT.',
'docker-compose dev environment, pnpm dev bootstraps everything.',
],
},
];
const tagStyle: Record<Release['tag'], string> = {
launch: 'border-[--color-accent]/40 bg-[--color-accent]/10 text-[--color-accent]',
feature: 'border-emerald-400/40 bg-emerald-400/10 text-emerald-300',
fix: 'border-amber-400/40 bg-amber-400/10 text-amber-300',
};
export default function Changelog() {
return (
<div className="mx-auto max-w-3xl px-6 py-16">
<header className="mb-12">
<div className="text-[11px] uppercase tracking-[0.16em] text-[--color-fg-subtle]">
Release notes
</div>
<h1 className="mt-2 text-[32px] font-semibold tracking-tight">Changelog</h1>
<p className="mt-3 text-[14px] leading-relaxed text-[--color-fg-muted]">
What shipped, when, and why.
</p>
</header>
<div className="space-y-12">
{RELEASES.map((r) => (
<article key={r.version} className="relative pl-6">
<div className="absolute left-0 top-2 size-2 rounded-full border border-[--color-border-strong] bg-[--color-bg-elevated]" />
<div className="flex items-baseline gap-3">
<span className="mono text-[13px] text-[--color-fg]">v{r.version}</span>
<span className="text-[12px] text-[--color-fg-subtle]">{r.date}</span>
<span
className={`mono rounded-full border px-2 py-0.5 text-[10.5px] uppercase tracking-wider ${tagStyle[r.tag]}`}
>
{r.tag}
</span>
</div>
<h2 className="mt-2 text-[16px] font-semibold tracking-tight">{r.title}</h2>
<ul className="mt-3 space-y-1.5">
{r.items.map((item) => (
<li
key={item}
className="relative pl-4 text-[13px] leading-relaxed text-[--color-fg-muted] before:absolute before:left-0 before:top-2 before:size-1 before:rounded-full before:bg-[--color-fg-subtle]"
>
{item}
</li>
))}
</ul>
</article>
))}
</div>
<footer className="mt-16">
<CodeBlock
label="subscribe"
code={`Follow @buildmymcp on Mastodon — or watch the GitHub repo for tagged releases.`}
/>
</footer>
</div>
);
}