docs(web): 2-command onboarding — install + launch --join
Simplify getting-started to 2 steps: npm install + launch --join. Remove "claudemesh install" section, update join page to show launch --join as the primary flow, update invite format examples. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import { getMetadata } from "~/lib/metadata";
|
|||||||
export const generateMetadata = getMetadata({
|
export const generateMetadata = getMetadata({
|
||||||
title: "Getting Started",
|
title: "Getting Started",
|
||||||
description:
|
description:
|
||||||
"Install claudemesh, join a mesh, and launch your first peer session in under two minutes.",
|
"Install the CLI and launch your first peer session in two commands.",
|
||||||
});
|
});
|
||||||
|
|
||||||
const STEP = ({
|
const STEP = ({
|
||||||
@@ -59,10 +59,9 @@ const STEP = ({
|
|||||||
const VERIFY_CHECKS = [
|
const VERIFY_CHECKS = [
|
||||||
"Node.js >= 20 installed",
|
"Node.js >= 20 installed",
|
||||||
"claude binary on PATH",
|
"claude binary on PATH",
|
||||||
"claudemesh MCP registered in ~/.claude.json",
|
|
||||||
"Status hooks registered in ~/.claude/settings.json",
|
|
||||||
"~/.claudemesh/config.json parses + chmod 0600",
|
"~/.claudemesh/config.json parses + chmod 0600",
|
||||||
"Mesh keypairs valid",
|
"Mesh keypairs valid",
|
||||||
|
"Broker connectivity",
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function GettingStartedPage() {
|
export default function GettingStartedPage() {
|
||||||
@@ -84,8 +83,7 @@ export default function GettingStartedPage() {
|
|||||||
className="mt-4 max-w-xl text-lg leading-[1.65] text-[var(--cm-fg-secondary)]"
|
className="mt-4 max-w-xl text-lg leading-[1.65] text-[var(--cm-fg-secondary)]"
|
||||||
style={{ fontFamily: "var(--cm-font-serif)" }}
|
style={{ fontFamily: "var(--cm-font-serif)" }}
|
||||||
>
|
>
|
||||||
Install the CLI, join a mesh, and launch Claude Code with real-time peer
|
Install the CLI and launch. Two commands — join is built into launch.
|
||||||
messaging. Three commands.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{/* Prerequisites */}
|
{/* Prerequisites */}
|
||||||
@@ -163,35 +161,33 @@ export default function GettingStartedPage() {
|
|||||||
|
|
||||||
<STEP
|
<STEP
|
||||||
n="2"
|
n="2"
|
||||||
title="Join a mesh"
|
title="Launch"
|
||||||
cmd="claudemesh join https://claudemesh.com/join/eyJ2IjoxLC..."
|
cmd='claudemesh launch --name Alice --join https://claudemesh.com/join/eyJ2IjoxLC...'
|
||||||
note="Replace the URL with your actual invite link. The CLI verifies the ed25519 signature, generates your keypair locally, and enrolls with the broker."
|
note="--join enrolls you in the mesh (first time only). On subsequent launches, drop the --join flag."
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
Paste the invite link you received. Your ed25519 keypair is
|
This does everything: verifies the invite, generates your ed25519
|
||||||
generated and stored in{" "}
|
keypair, enrolls with the broker, and spawns Claude Code with
|
||||||
|
real-time peer messaging. Your keys are stored in{" "}
|
||||||
<code
|
<code
|
||||||
className="rounded bg-[var(--cm-bg-elevated)] px-1.5 py-0.5 text-[12px] text-[var(--cm-fg-secondary)]"
|
className="rounded bg-[var(--cm-bg-elevated)] px-1.5 py-0.5 text-[12px] text-[var(--cm-fg-secondary)]"
|
||||||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
style={{ fontFamily: "var(--cm-font-mono)" }}
|
||||||
>
|
>
|
||||||
~/.claudemesh/config.json
|
~/.claudemesh/config.json
|
||||||
</code>{" "}
|
</code>{" "}
|
||||||
(chmod 0600). You keep your keys — the broker never sees them.
|
(chmod 0600) — the broker never sees them.
|
||||||
</p>
|
</p>
|
||||||
</STEP>
|
</STEP>
|
||||||
|
|
||||||
<STEP
|
<div
|
||||||
n="3"
|
className="py-3 text-center text-xs text-[var(--cm-fg-tertiary)]"
|
||||||
title="Launch with real-time messaging"
|
style={{ fontFamily: "var(--cm-font-mono)" }}
|
||||||
cmd="claudemesh launch --name Alice"
|
|
||||||
note="Wraps `claude` with the mesh dev-channel. Peers can message you in real-time. Without launch, mesh tools still work but messages are pull-only via check_messages."
|
|
||||||
>
|
>
|
||||||
<p>
|
next time, just:
|
||||||
This spawns Claude Code connected to the mesh with push messaging.
|
<code className="ml-2 rounded bg-[var(--cm-bg-elevated)] px-2 py-1 text-[var(--cm-fg-secondary)]">
|
||||||
The interactive wizard asks for your role and groups — or pass them
|
claudemesh launch --name Alice
|
||||||
as flags:
|
</code>
|
||||||
</p>
|
</div>
|
||||||
</STEP>
|
|
||||||
|
|
||||||
<pre
|
<pre
|
||||||
className="overflow-x-auto rounded-[var(--cm-radius-md)] border border-[var(--cm-border)] bg-[var(--cm-bg)] px-6 py-4 text-[13px] leading-[1.7] text-[var(--cm-fg)]"
|
className="overflow-x-auto rounded-[var(--cm-radius-md)] border border-[var(--cm-border)] bg-[var(--cm-bg)] px-6 py-4 text-[13px] leading-[1.7] text-[var(--cm-fg)]"
|
||||||
@@ -200,6 +196,7 @@ export default function GettingStartedPage() {
|
|||||||
<code>{`# Full example with all flags
|
<code>{`# Full example with all flags
|
||||||
claudemesh launch \\
|
claudemesh launch \\
|
||||||
--name Alice \\
|
--name Alice \\
|
||||||
|
--join https://claudemesh.com/join/eyJ2IjoxLC... \\
|
||||||
--role dev \\
|
--role dev \\
|
||||||
--groups "frontend:lead,reviewers" \\
|
--groups "frontend:lead,reviewers" \\
|
||||||
--message-mode push \\
|
--message-mode push \\
|
||||||
@@ -227,83 +224,18 @@ claudemesh launch \\
|
|||||||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
style={{ fontFamily: "var(--cm-font-mono)" }}
|
||||||
>
|
>
|
||||||
<code>{`$ claudemesh doctor
|
<code>{`$ claudemesh doctor
|
||||||
claudemesh doctor (v0.6.8)
|
claudemesh doctor (v0.8.0)
|
||||||
────────────────────────────────────────────────────────────
|
────────────────────────────────────────────────────────────
|
||||||
✓ Node.js >= 20 (v22.15.0)
|
✓ Node.js >= 20 (v22.15.0)
|
||||||
✓ claude binary on PATH
|
✓ claude binary on PATH
|
||||||
✓ claudemesh MCP registered in ~/.claude.json
|
|
||||||
✓ Status hooks registered in ~/.claude/settings.json
|
|
||||||
✓ ~/.claudemesh/config.json parses + chmod 0600
|
✓ ~/.claudemesh/config.json parses + chmod 0600
|
||||||
✓ Mesh keypairs valid (1 mesh(es))
|
✓ Mesh keypairs valid (1 mesh(es))
|
||||||
|
✓ Broker connectivity (wss://ic.claudemesh.com/ws)
|
||||||
|
|
||||||
All checks passed.`}</code>
|
All checks passed.`}</code>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* What install does */}
|
|
||||||
<div className="mt-16">
|
|
||||||
<h2
|
|
||||||
className="mb-4 text-xl font-medium text-[var(--cm-fg)]"
|
|
||||||
style={{ fontFamily: "var(--cm-font-serif)" }}
|
|
||||||
>
|
|
||||||
What <code style={{ fontFamily: "var(--cm-font-mono)" }}>claudemesh install</code> does
|
|
||||||
</h2>
|
|
||||||
<p
|
|
||||||
className="mb-6 text-[14px] leading-[1.6] text-[var(--cm-fg-secondary)]"
|
|
||||||
style={{ fontFamily: "var(--cm-font-serif)" }}
|
|
||||||
>
|
|
||||||
The install command touches two files. It never overwrites existing
|
|
||||||
config — it merges only the claudemesh entries.
|
|
||||||
</p>
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div className="rounded-[var(--cm-radius-md)] border border-[var(--cm-border)] bg-[var(--cm-bg-elevated)] p-5">
|
|
||||||
<div
|
|
||||||
className="mb-2 text-[11px] uppercase tracking-wider text-[var(--cm-fg-tertiary)]"
|
|
||||||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
|
||||||
>
|
|
||||||
~/.claude.json
|
|
||||||
</div>
|
|
||||||
<p
|
|
||||||
className="text-[13px] leading-[1.6] text-[var(--cm-fg-secondary)]"
|
|
||||||
style={{ fontFamily: "var(--cm-font-serif)" }}
|
|
||||||
>
|
|
||||||
Registers{" "}
|
|
||||||
<code
|
|
||||||
className="rounded bg-[var(--cm-bg)] px-1.5 py-0.5 text-[12px] text-[var(--cm-fg)]"
|
|
||||||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
|
||||||
>
|
|
||||||
mcpServers.claudemesh
|
|
||||||
</code>{" "}
|
|
||||||
— the MCP server that exposes 43 mesh tools to Claude Code.
|
|
||||||
Backed up before every write.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="rounded-[var(--cm-radius-md)] border border-[var(--cm-border)] bg-[var(--cm-bg-elevated)] p-5">
|
|
||||||
<div
|
|
||||||
className="mb-2 text-[11px] uppercase tracking-wider text-[var(--cm-fg-tertiary)]"
|
|
||||||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
|
||||||
>
|
|
||||||
~/.claude/settings.json
|
|
||||||
</div>
|
|
||||||
<p
|
|
||||||
className="text-[13px] leading-[1.6] text-[var(--cm-fg-secondary)]"
|
|
||||||
style={{ fontFamily: "var(--cm-font-serif)" }}
|
|
||||||
>
|
|
||||||
Adds two status hooks (Stop + UserPromptSubmit) so the broker
|
|
||||||
knows when your session is working or idle — without polling.
|
|
||||||
Pre-approves all 43 claudemesh tools in{" "}
|
|
||||||
<code
|
|
||||||
className="rounded bg-[var(--cm-bg)] px-1.5 py-0.5 text-[12px] text-[var(--cm-fg)]"
|
|
||||||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
|
||||||
>
|
|
||||||
allowedTools
|
|
||||||
</code>{" "}
|
|
||||||
so they run without --dangerously-skip-permissions.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Invite a teammate */}
|
{/* Invite a teammate */}
|
||||||
<div className="mt-16">
|
<div className="mt-16">
|
||||||
<h2
|
<h2
|
||||||
@@ -336,11 +268,10 @@ All checks passed.`}</code>
|
|||||||
className="rounded bg-[var(--cm-bg-elevated)] px-1.5 py-0.5 text-[12px] text-[var(--cm-fg)]"
|
className="rounded bg-[var(--cm-bg-elevated)] px-1.5 py-0.5 text-[12px] text-[var(--cm-fg)]"
|
||||||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
style={{ fontFamily: "var(--cm-font-mono)" }}
|
||||||
>
|
>
|
||||||
claudemesh join <link>
|
claudemesh launch --name Name --join <link>
|
||||||
</code>{" "}
|
</code>{" "}
|
||||||
— the CLI verifies the signature client-side before enrolling with
|
— joins the mesh and launches in one step. No account creation
|
||||||
the broker. No account creation needed. Identity is the ed25519
|
needed. Identity is the ed25519 keypair.
|
||||||
keypair.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -356,17 +287,18 @@ All checks passed.`}</code>
|
|||||||
className="overflow-x-auto rounded-[var(--cm-radius-md)] border border-[var(--cm-border)] bg-[var(--cm-bg-elevated)] px-6 py-4 text-[13px] leading-[1.9] text-[var(--cm-fg-secondary)]"
|
className="overflow-x-auto rounded-[var(--cm-radius-md)] border border-[var(--cm-border)] bg-[var(--cm-bg-elevated)] px-6 py-4 text-[13px] leading-[1.9] text-[var(--cm-fg-secondary)]"
|
||||||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
style={{ fontFamily: "var(--cm-font-mono)" }}
|
||||||
>
|
>
|
||||||
<code>{`# HTTPS link (clickable, shareable)
|
<code>{`# Join + launch in one step (recommended)
|
||||||
|
claudemesh launch --name Alice --join https://claudemesh.com/join/eyJ2IjoxLC...
|
||||||
|
|
||||||
|
# Or join separately first
|
||||||
claudemesh join https://claudemesh.com/join/eyJ2IjoxLC...
|
claudemesh join https://claudemesh.com/join/eyJ2IjoxLC...
|
||||||
|
claudemesh launch --name Alice
|
||||||
|
|
||||||
# With locale prefix (also works)
|
# All invite formats work with both join and --join:
|
||||||
claudemesh join https://claudemesh.com/en/join/eyJ2IjoxLC...
|
# https://claudemesh.com/join/eyJ2IjoxLC...
|
||||||
|
# https://claudemesh.com/en/join/eyJ2IjoxLC...
|
||||||
# ic:// scheme (legacy, still supported)
|
# ic://join/eyJ2IjoxLC...
|
||||||
claudemesh join ic://join/eyJ2IjoxLC...
|
# eyJ2IjoxLC4uLg (raw token)`}</code>
|
||||||
|
|
||||||
# Raw token (last resort)
|
|
||||||
claudemesh join eyJ2IjoxLC4uLg`}</code>
|
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -445,10 +377,11 @@ claudemesh join eyJ2IjoxLC4uLg`}</code>
|
|||||||
style={{ fontFamily: "var(--cm-font-serif)" }}
|
style={{ fontFamily: "var(--cm-font-serif)" }}
|
||||||
>
|
>
|
||||||
<li>Real-time push messages from peers</li>
|
<li>Real-time push messages from peers</li>
|
||||||
|
<li>Native MCP entries for deployed mesh services</li>
|
||||||
<li>Per-session ephemeral keypair</li>
|
<li>Per-session ephemeral keypair</li>
|
||||||
<li>Display name visible to other peers</li>
|
<li>Display name, groups, and roles</li>
|
||||||
<li>Groups and roles set at launch</li>
|
|
||||||
<li>Session config isolated in tmpdir</li>
|
<li>Session config isolated in tmpdir</li>
|
||||||
|
<li>MCP_TIMEOUT + output limits tuned for mesh</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-[var(--cm-bg-elevated)] p-6">
|
<div className="bg-[var(--cm-bg-elevated)] p-6">
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ interface Props {
|
|||||||
token: string;
|
token: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const LAUNCH_CMD = (token: string) => `claudemesh launch --name YourName --join ${token}`;
|
||||||
const JOIN_CMD = (token: string) => `claudemesh join ${token}`;
|
const JOIN_CMD = (token: string) => `claudemesh join ${token}`;
|
||||||
const INSTALL_CMD = "npm i -g claudemesh-cli";
|
const INSTALL_CMD = "npm i -g claudemesh-cli";
|
||||||
|
|
||||||
@@ -60,7 +61,7 @@ export const InstallToggle = ({ token }: Props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasCli === "yes") {
|
if (hasCli === "yes") {
|
||||||
const cmd = JOIN_CMD(token);
|
const cmd = LAUNCH_CMD(token);
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="rounded-[var(--cm-radius-md)] border border-[var(--cm-clay)]/40 bg-[var(--cm-bg-elevated)] p-5">
|
<div className="rounded-[var(--cm-radius-md)] border border-[var(--cm-clay)]/40 bg-[var(--cm-bg-elevated)] p-5">
|
||||||
@@ -68,7 +69,7 @@ export const InstallToggle = ({ token }: Props) => {
|
|||||||
className="mb-2 text-[11px] uppercase tracking-[0.18em] text-[var(--cm-clay)]"
|
className="mb-2 text-[11px] uppercase tracking-[0.18em] text-[var(--cm-clay)]"
|
||||||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
style={{ fontFamily: "var(--cm-font-mono)" }}
|
||||||
>
|
>
|
||||||
run this in your terminal
|
join + launch in one step
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<code
|
<code
|
||||||
@@ -96,7 +97,7 @@ export const InstallToggle = ({ token }: Props) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const joinCmd = JOIN_CMD(token);
|
const launchCmd = LAUNCH_CMD(token);
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<ol className="space-y-3">
|
<ol className="space-y-3">
|
||||||
@@ -127,7 +128,7 @@ export const InstallToggle = ({ token }: Props) => {
|
|||||||
className="mt-2 text-xs text-[var(--cm-fg-tertiary)]"
|
className="mt-2 text-xs text-[var(--cm-fg-tertiary)]"
|
||||||
style={{ fontFamily: "var(--cm-font-serif)" }}
|
style={{ fontFamily: "var(--cm-font-serif)" }}
|
||||||
>
|
>
|
||||||
Installs the CLI globally. Requires Node.js 20+.
|
Requires Node.js 20+.
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li className="rounded-[var(--cm-radius-md)] border border-[var(--cm-clay)]/40 bg-[var(--cm-bg-elevated)] p-5">
|
<li className="rounded-[var(--cm-radius-md)] border border-[var(--cm-clay)]/40 bg-[var(--cm-bg-elevated)] p-5">
|
||||||
@@ -136,46 +137,28 @@ export const InstallToggle = ({ token }: Props) => {
|
|||||||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
style={{ fontFamily: "var(--cm-font-mono)" }}
|
||||||
>
|
>
|
||||||
<span className="rounded-full bg-[var(--cm-clay)]/20 px-1.5">2</span>
|
<span className="rounded-full bg-[var(--cm-clay)]/20 px-1.5">2</span>
|
||||||
join the mesh
|
join + launch
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<code
|
<code
|
||||||
className="flex-1 overflow-x-auto rounded-[var(--cm-radius-xs)] bg-[var(--cm-bg)] p-3 text-sm text-[var(--cm-fg)]"
|
className="flex-1 overflow-x-auto rounded-[var(--cm-radius-xs)] bg-[var(--cm-bg)] p-3 text-sm text-[var(--cm-fg)]"
|
||||||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
style={{ fontFamily: "var(--cm-font-mono)" }}
|
||||||
>
|
>
|
||||||
{joinCmd}
|
{launchCmd}
|
||||||
</code>
|
</code>
|
||||||
<button
|
<button
|
||||||
onClick={() => copy(joinCmd, "join")}
|
onClick={() => copy(launchCmd, "join")}
|
||||||
className="rounded-[var(--cm-radius-xs)] bg-[var(--cm-clay)] px-3 py-3 text-sm font-medium text-[var(--cm-fg)] transition-colors hover:bg-[var(--cm-clay-hover)]"
|
className="rounded-[var(--cm-radius-xs)] bg-[var(--cm-clay)] px-3 py-3 text-sm font-medium text-[var(--cm-fg)] transition-colors hover:bg-[var(--cm-clay-hover)]"
|
||||||
style={{ fontFamily: "var(--cm-font-sans)" }}
|
style={{ fontFamily: "var(--cm-font-sans)" }}
|
||||||
>
|
>
|
||||||
{copiedKey === "join" ? "Copied ✓" : "Copy"}
|
{copiedKey === "join" ? "Copied ✓" : "Copy"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
|
||||||
<li className="rounded-[var(--cm-radius-md)] border border-[var(--cm-border)] bg-[var(--cm-bg-elevated)] p-5">
|
|
||||||
<div
|
|
||||||
className="mb-2 flex items-center gap-2 text-[11px] uppercase tracking-[0.18em] text-[var(--cm-fg-tertiary)]"
|
|
||||||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
|
||||||
>
|
|
||||||
<span className="rounded-full bg-[var(--cm-border)] px-1.5">3</span>
|
|
||||||
launch with push messaging
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<code
|
|
||||||
className="flex-1 overflow-x-auto rounded-[var(--cm-radius-xs)] bg-[var(--cm-bg)] p-3 text-sm text-[var(--cm-fg)]"
|
|
||||||
style={{ fontFamily: "var(--cm-font-mono)" }}
|
|
||||||
>
|
|
||||||
claudemesh launch --name YourName
|
|
||||||
</code>
|
|
||||||
</div>
|
|
||||||
<p
|
<p
|
||||||
className="mt-2 text-xs text-[var(--cm-fg-tertiary)]"
|
className="mt-2 text-xs text-[var(--cm-fg-tertiary)]"
|
||||||
style={{ fontFamily: "var(--cm-font-serif)" }}
|
style={{ fontFamily: "var(--cm-font-serif)" }}
|
||||||
>
|
>
|
||||||
Spawns Claude Code with mesh connectivity, peer messaging,
|
Joins the mesh and launches Claude Code in one step.
|
||||||
and native access to deployed MCP services.
|
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|||||||
Reference in New Issue
Block a user