Auth routes (/login, /register, /forgot-password, /update-password, /join)
were rendering with the default Geist fonts + shadcn neutral palette +
turbostarter SVG logos — completely off-brand against the marketing
landing. User reported from production.
Rewire auth/layout.tsx to:
- use --cm-bg / --cm-fg / --cm-clay tokens (dark #141413)
- Anthropic Sans for UI, Anthropic Serif for the right-aside tagline
- claudemesh wordmark (mesh glyph + serif) in place of Icons.Logo /
Icons.LogoText
- right aside: mesh glyph + serif tagline "Every Claude Code session,
woven into one mesh." + description paragraph, matching the CTA
copy from the landing
- subtle orange radial glow on the aside for depth
Inner form components (BetterAuth password/social buttons) pick up the
tokens from globals.css, so the forms look native on the dark layout
without per-component rewrites.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New user signs in → /dashboard (user) → hits server-side getMyMeshes → 0
results → redirects to /dashboard/meshes/new?onboarding=1. Create-mesh
page renders a welcome banner explaining what a mesh is. After submit,
if ?onboarding=1 was set, the form bounces to
/dashboard/meshes/[id]/invite?onboarding=1 instead of the mesh detail
page. Invite page renders a "🎉 Mesh created" banner with the
`claudemesh join <link>` CLI snippet.
The onboarding flag is URL-driven — no persistence needed, dismissal
happens naturally when the user navigates away.
Also rewrites the /dashboard (user) home page from the placeholder
"Welcome to your Dashboard" TurboStarter card grid to a claudemesh-
native view: top 6 meshes with badges, All meshes / New mesh CTAs.
Removes the unused Card/Icons imports.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two visible launch-polish issues:
1. BuyCtaDialog popup was firing on an exponential backoff schedule
(15s, 30s, 60s, …) pushing users toward turbostarter.dev/#pricing +
Discord. Wrong product, wrong audience. Fully removed: mount point
in [locale]/layout.tsx + the component file + localStorage keys will
self-prune on next visit.
2. WhatsApp/Slack/Twitter link previews were pulling the TurboStarter
boilerplate opengraph-image.png (from Jan 8). Replaced with a 1200×630
claudemesh OG: "CLAUDEMESH" pixel wordmark left side, hero mesh
composition (6 Claude Code terminals + pixel-crab hub + orange
energy lattice + vaporwave grid floor) right side, "peer mesh for
Claude Code sessions" tagline in mono beneath wordmark.
3. Default metadata description swapped from the dangling
`common:product.description` i18n key (which rendered as the key
itself because the key doesn't exist in our trimmed translations)
to a hardcoded claudemesh description.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Step 16 (account / profile) — landed smaller than scoped because turbo-
starter already ships the full /dashboard/settings flow (avatar, name,
email, language, delete-account) and BetterAuth handles security +
sessions out of the box. Reuses that surface; adds the claudemesh-
specific bits only.
- GET /api/my/export — returns a JSON bundle of the user's profile,
meshes they own, meshes they belong to, invites they've issued, and
audit events from their OWNED meshes (privacy: don't leak events
from meshes merely joined). Limited to 5k audit rows.
- ExportData component on /dashboard/settings — button downloads the
bundle as claudemesh-export-<userId>-<YYYY-MM-DD>.json client-side.
- Sidebar (user group) "settings" label swapped to "account" to match
the Step 16 naming. Same /dashboard/settings route, same existing
i18n key ("account" was already in common.json).
No schema changes: user.name (BetterAuth) IS the mesh display name.
meshMember.displayName is the per-join override that lands from the
CLI at registration time.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Four new routes under /dashboard/(user)/*:
- /dashboard/meshes — card grid of user's meshes with myRole badge,
memberCount, tier, archived state. Empty state with "Create first mesh"
CTA.
- /dashboard/meshes/[id] — mesh detail (members list + active invites)
with "Generate invite link" CTA in header.
- /dashboard/meshes/new — placeholder route for create form (form lands
in next commit).
- /dashboard/meshes/[id]/invite — placeholder route for invite generator
(generator lands in next commit).
- /dashboard/invites — table of invites the user has issued across all
meshes, with derived status (active/revoked/expired/exhausted).
Sidebar nav (user group) extended with Meshes + Invites entries. paths
config extended with dashboard.user.meshes.{index,new,mesh,invite} and
dashboard.user.invites.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Four new admin routes backed by the mesh API modules:
- /admin/meshes — paginated data-table (name, owner, tier, transport,
members, created). Tier + transport multiSelect filters.
- /admin/meshes/[id] — detail page: owner row + 4 live sections
(members, presences, invites, last 50 audit events).
- /admin/sessions — live Claude Code WS presences. Status filter,
pulse dot for working sessions, disconnected badge.
- /admin/invites — invite tokens w/ status derived client-side
(active/revoked/expired/exhausted).
- /admin/audit — metadata-only event log, event-type + mesh + date
filters.
Overview page at /admin rewritten to 6 summary cards (users, orgs,
customers, meshes, sessions, messages 24h) joining the base
/admin/summary and /admin/summary/mesh endpoints.
Sidebar navigation gains a second "mesh" group with the four new entries.
paths.ts extended with admin.meshes / sessions / invites / audit.
All UI reuses @turbostarter/ui-web/data-table — columns.tsx + thin
*-data-table.tsx wrapper per the existing users pattern.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Hono RPC client loses the response shape on /organizations/:id because
the route has no zod response validator on c.json(). Tactical cast at the
callsite unblocks the web Docker build. Proper fix is to add a
getOrganizationResponseSchema in packages/api and wire it into the route.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Step 3 pruned packages/{ai,cms,cognitive-context} but left whole
route groups + feature modules that depended on them. Those files
were unbuildable since that prune. Removes them now so the workspace
can be validated:
Route groups:
- apps/web/src/app/[locale]/(apps)/{chat,image,pdf,tts}/
- apps/web/src/app/[locale]/(marketing)/blog/
Feature modules:
- apps/web/src/modules/{chat,image,pdf,tts,common/ai,marketing/blog}/
- packages/api/src/modules/ai/ (chat, image, pdf, stt, tts, router)
3 stragglers remain (separate handoff to claudemesh-2):
- apps/web/src/app/[locale]/(marketing)/legal/[slug]/page.tsx (cms)
- apps/web/src/app/sitemap.ts (cms)
- apps/web/src/modules/common/layout/credits/index.tsx (ai)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- pgSchema "mesh" with 4 tables isolating the peer mesh domain
- Enums: visibility, transport, tier, role
- audit_log is metadata-only (E2E encryption enforced at broker/client)
- Cascade on mesh delete, soft-delete via archivedAt/revokedAt
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>