buildmymcpserver/apps/web/app/(marketing)/changelog/page.tsx
Marco Sadjadi 09688c1114 feat(web): real 3-step wizard, settings, audit, docs, marketing pages
Sprint 3.5: close every dead link and replace the single-step wizard with the
spec-mandated 3-step flow.

Wizard:
- Step 1 collects prompt + name + slug, calls /v1/servers/preview.
- Step 2 renders parsed tools (name, description, input schema as copyable JSON)
  + a credential field per requiredSecret Claude actually identified. Self-contained
  servers see 'No credentials needed' instead of generic Notion placeholders.
- Step 3 streams the live build over WebSocket and shows install snippets.

New dashboard pages:
- /settings — org, plan/usage, members table, API keys + billing stubs (Sprint 4),
  encryption status. Reads /v1/me/org.
- /audit — filterable table over /v1/audit with action pills, resource refs, IP,
  metadata JSON.

Docs site (/docs + 6 sub-pages):
- Sticky 240px sidebar, max-w-prose article column, shared DocsTitle/H2/Code primitives.
- Quickstart, MCP concepts, OAuth 2.1 flow (full walkthrough with curl), Authoring
  tools, Self-hosting, API reference, FAQ.

Marketing pages:
- /changelog with tagged release timeline.
- /security with 8 pillars + disclosure.
- /privacy with GDPR-aware sections.
- /terms (10 clauses).
- /pricing full page (nav now points here instead of /#pricing anchor).
- /status with live 10s probes against /api/health and /login.

Footer 'system status' badge now links to /status.

All 20 routes 200 OK in smoke crawl. Typecheck clean across packages.
2026-05-19 18:20:31 +02:00

103 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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>
);
}