The site had drifted ~6 months behind the product. Three problems
addressed in one push:
1. Timeline ("Shipped, not promised") topped out at v0.6–0.8 and
claimed "66 npm releases" — both stale. Adds a v0.9 → 1.34 tier
covering daemon, multi-mesh, multi-session correctness train,
refuse-to-kick on control-plane, env-var fallback. Updates count
to "120+ npm releases through v1.34.15." Rewrites the "next"
block from the now-shipped "Daemon redesign · per-topic
encryption" to the actually-pending "HKDF cross-machine identity
· session capabilities · A2A interop · self-host packaging ·
federation."
2. Hero subhead leaned into the original "Claude Code peer mesh"
framing, which is undercut by Anthropic Agent Teams (Feb 2026,
single-machine native mailbox). Now reframes claudemesh as the
encrypted backbone where Claude Code sessions, autonomous
agents, and humans coordinate "across machines, across users,
across organizations" — the four words that distinguish the
product from anything Anthropic structurally can ship from
inside Claude Code.
3. /changelog had three entries from April 2026 (v0.1.2 → v0.1.4)
and was 70+ versions out of date. Replaced with a curated
16-entry timeline from v0.1.0 → v1.34.15, hand-picked to tell
the story (load-bearing ships, not every patch). Adds links
back to docs/roadmap.md, .artifacts/specs/, and GitHub Releases.
New module: apps/web/src/modules/marketing/home/changelog-data.ts
holds the curated entries as a single source of truth. Imported by
both the /changelog page and a new home-page component
LatestReleases (compact 5-entry strip, slotted between Timeline
and Pricing) so they never disagree.
Misc fixes pulled in:
- timeline.tsx had glyph="layers" which isn't in SectionIcon's
valid set; switched to "grid" (changelog-data.ts uses same).
- changelog data extracted to a non-route module so Next.js's
route-export validator stops complaining about exporting
CHANGELOG_ENTRIES from app/.../changelog/page.tsx.
Pre-existing typecheck noise in packages/ui/web/sidebar.tsx
(csstype version mismatch) + billing modules unrelated to this
change. My files all typecheck clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
243 lines
9.2 KiB
TypeScript
243 lines
9.2 KiB
TypeScript
"use client";
|
||
import { useRef } from "react";
|
||
import { Reveal, SectionIcon } from "./_reveal";
|
||
|
||
const MILESTONES = [
|
||
{
|
||
version: "v0.1",
|
||
phase: "Foundation",
|
||
color: "var(--cm-clay)",
|
||
items: [
|
||
"E2E encrypted messaging (libsodium crypto_box)",
|
||
"WSS broker with reconnect + priority routing",
|
||
"ed25519 identity + signed invite links",
|
||
"claudemesh launch with dev-channel push",
|
||
"Named sessions + ephemeral keypairs",
|
||
"Production hardening (stale sweep, sender exclusion)",
|
||
],
|
||
stat: "16 releases",
|
||
},
|
||
{
|
||
version: "v0.2",
|
||
phase: "Groups",
|
||
color: "var(--cm-fig)",
|
||
items: [
|
||
"@group routing with roles (lead, member, observer)",
|
||
"Interactive wizard for launch configuration",
|
||
"Dynamic join/leave groups at runtime",
|
||
"Multicast delivery with sender exclusion",
|
||
],
|
||
stat: "6 coordination patterns",
|
||
},
|
||
{
|
||
version: "v0.3",
|
||
phase: "Shared Intelligence",
|
||
color: "var(--cm-cactus)",
|
||
items: [
|
||
"Shared state — live key-value with push notifications",
|
||
"Memory — persistent knowledge with full-text search",
|
||
"Message status — per-recipient delivery tracking",
|
||
"MCP instructions — dynamic identity + tool guide",
|
||
],
|
||
stat: "Peers learn collectively",
|
||
},
|
||
{
|
||
version: "v0.4",
|
||
phase: "Files & Targeting",
|
||
color: "var(--cm-oat)",
|
||
items: [
|
||
"MinIO file sharing with per-peer access control",
|
||
"Message attachments (ephemeral, 24h TTL)",
|
||
"Multi-target messages with deduplication",
|
||
"Targeted views — per-audience message tailoring",
|
||
],
|
||
stat: "Binary artifacts + text",
|
||
},
|
||
{
|
||
version: "v0.5",
|
||
phase: "Data Platform",
|
||
color: "var(--cm-clay)",
|
||
items: [
|
||
"Per-mesh SQL database (Postgres schema)",
|
||
"Vector search (Qdrant semantic embeddings)",
|
||
"Graph database (Neo4j entity relationships)",
|
||
"Context sharing between peer sessions",
|
||
"Tasks — create, claim, complete work items",
|
||
"Streams — real-time pub/sub data channels",
|
||
],
|
||
stat: "5 persistence backends",
|
||
},
|
||
{
|
||
version: "v0.6–0.8",
|
||
phase: "Platform",
|
||
color: "var(--cm-fig)",
|
||
items: [
|
||
"Mesh MCP proxy — dynamic tool sharing between peers",
|
||
"Skills catalog — publish + discover reusable instructions",
|
||
"Signed hash-chain audit log for mesh events",
|
||
"Inbound webhooks for external integrations",
|
||
"Scheduled messages + cron-based reminders",
|
||
"Mesh services — deploy MCP servers with vault + scopes",
|
||
"Runner container for git/npx service sources",
|
||
"URL watch — broker polls URLs, notifies on change",
|
||
"Telegram bridge with multi-tenant routing",
|
||
"Peer stats reporting (messages, uptime, errors)",
|
||
],
|
||
stat: "43 MCP tools total",
|
||
},
|
||
{
|
||
version: "v0.9 → 1.34",
|
||
phase: "Daemon · multi-mesh · multi-session",
|
||
color: "var(--cm-cactus)",
|
||
items: [
|
||
"Persistent daemon — long-lived broker WS, durable outbox/inbox",
|
||
"Universal multi-mesh daemon — one process, every joined mesh",
|
||
"Per-session IPC tokens — auto-scope to the launched session",
|
||
"Per-session broker presence — sibling sessions see each other",
|
||
"Self-healing daemon lifecycle (auto-spawn, version probe)",
|
||
"Multi-session correctness train — per-recipient SSE demux + inbox scoping",
|
||
"Refuse-to-kick on control-plane (no more no-op kicks)",
|
||
"Caller-stable idempotency on every send",
|
||
"Stale CLAUDEMESH_CONFIG_DIR fallback",
|
||
],
|
||
stat: "1.34.15 shipped",
|
||
},
|
||
];
|
||
|
||
export const Timeline = () => {
|
||
const trackRef = useRef<HTMLDivElement>(null);
|
||
|
||
return (
|
||
<section className="border-b border-[var(--cm-border)] bg-[var(--cm-bg)] px-6 py-24 md:px-12 md:py-32">
|
||
<div className="mx-auto max-w-[var(--cm-max-w)]">
|
||
<Reveal className="mb-6 flex justify-center">
|
||
<SectionIcon glyph="grid" />
|
||
</Reveal>
|
||
<Reveal delay={1}>
|
||
<h2
|
||
className="text-center text-[clamp(2rem,4.5vw,3.25rem)] font-medium leading-[1.1] text-[var(--cm-fg)]"
|
||
style={{ fontFamily: "var(--cm-font-serif)" }}
|
||
>
|
||
Shipped, not promised
|
||
</h2>
|
||
</Reveal>
|
||
<Reveal delay={2}>
|
||
<p
|
||
className="mx-auto mt-4 max-w-xl text-center text-[15px] leading-[1.6] text-[var(--cm-fg-secondary)]"
|
||
style={{ fontFamily: "var(--cm-font-sans)" }}
|
||
>
|
||
120+ npm releases through v1.34.15. Every feature below is in
|
||
production today.
|
||
</p>
|
||
</Reveal>
|
||
|
||
<Reveal delay={3}>
|
||
<div ref={trackRef} className="relative mt-16">
|
||
{/* Vertical line */}
|
||
<div
|
||
className="absolute left-[24px] top-0 hidden h-full w-px md:block"
|
||
style={{ background: "linear-gradient(to bottom, var(--cm-clay), var(--cm-fig), var(--cm-cactus), transparent)" }}
|
||
/>
|
||
|
||
<div className="space-y-12 md:space-y-16">
|
||
{MILESTONES.map((m, idx) => (
|
||
<div key={m.version} className="relative md:pl-16">
|
||
{/* Dot on timeline */}
|
||
<div
|
||
className="absolute left-[17px] top-[6px] hidden h-[15px] w-[15px] rounded-full border-2 md:block"
|
||
style={{
|
||
borderColor: m.color,
|
||
backgroundColor: "var(--cm-bg)",
|
||
}}
|
||
>
|
||
<div
|
||
className="absolute inset-[3px] rounded-full"
|
||
style={{ backgroundColor: m.color }}
|
||
/>
|
||
</div>
|
||
|
||
{/* Content */}
|
||
<div className="rounded-[var(--cm-radius-md)] border border-[var(--cm-border)] bg-[var(--cm-bg-elevated)] p-6 transition-colors hover:border-[color:var(--hover-color)]"
|
||
style={{ "--hover-color": m.color } as React.CSSProperties}
|
||
>
|
||
{/* Header */}
|
||
<div className="mb-4 flex items-baseline justify-between gap-4">
|
||
<div className="flex items-center gap-3">
|
||
<span
|
||
className="rounded-[4px] px-2 py-0.5 text-[11px] font-medium"
|
||
style={{
|
||
fontFamily: "var(--cm-font-mono)",
|
||
backgroundColor: m.color,
|
||
color: "var(--cm-gray-900)",
|
||
}}
|
||
>
|
||
{m.version}
|
||
</span>
|
||
<h3
|
||
className="text-[18px] font-medium text-[var(--cm-fg)]"
|
||
style={{ fontFamily: "var(--cm-font-serif)" }}
|
||
>
|
||
{m.phase}
|
||
</h3>
|
||
</div>
|
||
<span
|
||
className="hidden shrink-0 text-[11px] text-[var(--cm-fg-tertiary)] sm:block"
|
||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
||
>
|
||
{m.stat}
|
||
</span>
|
||
</div>
|
||
|
||
{/* Items grid */}
|
||
<div className="grid gap-x-6 gap-y-1.5 sm:grid-cols-2">
|
||
{m.items.map((item) => (
|
||
<div
|
||
key={item}
|
||
className="flex items-start gap-2 text-[13px] leading-[1.5] text-[var(--cm-fg-secondary)]"
|
||
style={{ fontFamily: "var(--cm-font-sans)" }}
|
||
>
|
||
<span
|
||
className="mt-[7px] block h-[5px] w-[5px] shrink-0 rounded-full"
|
||
style={{ backgroundColor: m.color, opacity: 0.6 }}
|
||
/>
|
||
<span>{item}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{/* Bottom: what's next */}
|
||
<div className="relative mt-12 md:pl-16">
|
||
<div
|
||
className="absolute left-[17px] top-[6px] hidden h-[15px] w-[15px] rounded-full border-2 border-dashed border-[var(--cm-fg-tertiary)] md:block"
|
||
/>
|
||
<div
|
||
className="rounded-[var(--cm-radius-md)] border border-dashed border-[var(--cm-border)] p-6"
|
||
>
|
||
<div className="flex items-center gap-3">
|
||
<span
|
||
className="rounded-[4px] border border-[var(--cm-fg-tertiary)] px-2 py-0.5 text-[11px] text-[var(--cm-fg-tertiary)]"
|
||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
||
>
|
||
next
|
||
</span>
|
||
<span
|
||
className="text-[14px] text-[var(--cm-fg-tertiary)]"
|
||
style={{ fontFamily: "var(--cm-font-serif)" }}
|
||
>
|
||
HKDF cross-machine identity · session capabilities · A2A
|
||
interop · self-host packaging · federation
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Reveal>
|
||
</div>
|
||
</section>
|
||
);
|
||
};
|