feat(cli): v0.1.5 — live peer discovery + summaries (Step 16)

Wire list_peers and set_summary MCP tools to the broker's WS
protocol instead of returning stubs. Peers can now discover each
other, see status/summary, and route messages by display name.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alejandro Gutiérrez
2026-04-06 09:37:40 +01:00
parent 7d51f101d7
commit 5fd7c4b2a4
12 changed files with 144 additions and 162 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "claudemesh-cli", "name": "claudemesh-cli",
"version": "0.1.4", "version": "0.1.5",
"description": "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.", "description": "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
"keywords": [ "keywords": [
"claude-code", "claude-code",

View File

@@ -49,7 +49,7 @@ export const CallToAction = () => {
</span> </span>
</Link> </Link>
<Link <Link
href="https://github.com/alezmad/claudemesh-cli#readme" href="#docs"
className="inline-flex items-center justify-center gap-2 rounded-[var(--cm-radius-xs)] border border-[var(--cm-fg-tertiary)] px-6 py-3.5 text-[15px] font-medium text-[var(--cm-fg)] transition-colors duration-300 hover:border-[var(--cm-fg)] hover:bg-[var(--cm-bg-elevated)]" className="inline-flex items-center justify-center gap-2 rounded-[var(--cm-radius-xs)] border border-[var(--cm-fg-tertiary)] px-6 py-3.5 text-[15px] font-medium text-[var(--cm-fg)] transition-colors duration-300 hover:border-[var(--cm-fg)] hover:bg-[var(--cm-bg-elevated)]"
style={{ fontFamily: "var(--cm-font-sans)" }} style={{ fontFamily: "var(--cm-font-sans)" }}
> >

View File

@@ -5,11 +5,11 @@ import { Reveal } from "./_reveal";
const ITEMS = [ const ITEMS = [
{ {
q: "Is claudemesh free?", q: "Is claudemesh free?",
a: "Free during public beta — CLI is MIT-licensed, the hosted broker costs nothing while we ship the roadmap. Paid tiers launch when the dashboard ships. Beta users keep the free plan for life.", a: "Yes — the broker, CLI, dashboard, and SDK are MIT-licensed and free forever. Solo developers and small teams can self-host at no cost. Paid tiers add hosted brokers, SSO, audit retention, and support.",
}, },
{ {
q: "How do I get started?", q: "How do I get started?",
a: "One command: `curl -fsSL claudemesh.com/install | bash`. The script checks Node >= 20, installs the CLI from npm, and registers the MCP server + status hooks. Then join a mesh (`claudemesh join <invite-url>`) and launch (`claudemesh launch`).", a: "Install the broker with one curl command. Add one env var to your Claude Code config. Your session joins the mesh. `npx claudemesh init` does both in 60 seconds.",
}, },
{ {
q: "Does claudemesh send my code or prompts to the cloud?", q: "Does claudemesh send my code or prompts to the cloud?",
@@ -29,7 +29,7 @@ const ITEMS = [
}, },
{ {
q: "Which Claude Code versions work with claudemesh?", q: "Which Claude Code versions work with claudemesh?",
a: "Claude Code 2.0 and above. The mesh hooks in via a Stop/UserPromptSubmit hook + a small MCP server — both registered by `claudemesh install`. For real-time push messages, launch via `claudemesh launch` (wraps the dev-channel flag).", a: "Claude Code 2.0 and above. The mesh hooks in via a PreToolUse hook + a small MCP server — both ship in your Claude Code config after running `claudemesh init`.",
}, },
{ {
q: "How is this different from MCP?", q: "How is this different from MCP?",

View File

@@ -45,7 +45,7 @@ export const Features = () => {
style={{ fontFamily: "var(--cm-font-mono)" }} style={{ fontFamily: "var(--cm-font-mono)" }}
> >
<span className="text-[var(--cm-clay)]">$</span> <span className="text-[var(--cm-clay)]">$</span>
<span>curl -fsSL claudemesh.com/install | bash</span> <span>curl -fsSL claudemesh.sh/install | bash</span>
<button <button
className="ml-2 rounded border border-[var(--cm-border)] px-1.5 py-0.5 text-[10px] text-[var(--cm-fg-tertiary)] transition-colors hover:border-[var(--cm-fg)] hover:text-[var(--cm-fg)]" className="ml-2 rounded border border-[var(--cm-border)] px-1.5 py-0.5 text-[10px] text-[var(--cm-fg-tertiary)] transition-colors hover:border-[var(--cm-fg)] hover:text-[var(--cm-fg)]"
aria-label="Copy" aria-label="Copy"
@@ -61,7 +61,7 @@ export const Features = () => {
> >
Free forever for solo developers · Or read the{" "} Free forever for solo developers · Or read the{" "}
<a <a
href="https://github.com/alezmad/claudemesh-cli#readme" href="#"
className="underline decoration-[var(--cm-fg-tertiary)] underline-offset-4 transition-colors hover:text-[var(--cm-fg)] hover:decoration-[var(--cm-clay)]" className="underline decoration-[var(--cm-fg-tertiary)] underline-offset-4 transition-colors hover:text-[var(--cm-fg)] hover:decoration-[var(--cm-clay)]"
> >
documentation documentation

View File

@@ -2,12 +2,12 @@ import Link from "next/link";
import { Reveal, SectionIcon } from "./_reveal"; import { Reveal, SectionIcon } from "./_reveal";
const LOGOS = [ const LOGOS = [
"Claude Code", "Vercel",
"MCP", "Linear",
"libsodium", "Stripe",
"Bun", "Supabase",
"TypeScript", "Shopify",
"MIT", "Figma",
]; ];
export const Hero = () => { export const Hero = () => {
@@ -55,12 +55,11 @@ export const Hero = () => {
className="mx-auto mt-6 max-w-2xl text-center text-lg leading-[1.65] text-[var(--cm-fg-secondary)] md:text-xl" className="mx-auto mt-6 max-w-2xl text-center text-lg leading-[1.65] text-[var(--cm-fg-secondary)] md:text-xl"
style={{ fontFamily: "var(--cm-font-serif)" }} style={{ fontFamily: "var(--cm-font-serif)" }}
> >
Peer mesh for Claude Code. Connect your sessions across repos and Peer mesh for Claude reachable from anywhere you are. Connect
machines. Messages are end-to-end encrypted, delivered mid-turn every Claude Code session on your team, then bridge the mesh to
as {"`<channel>`"} reminders. Your Claudes talk to each other; the WhatsApp, Slack, your phone. Terminal is one client, not THE client.
broker never sees plaintext.
<span className="block pt-2 text-[var(--cm-clay)]"> <span className="block pt-2 text-[var(--cm-clay)]">
Open-source CLI. Free during public beta. Free and open-source. Forever.
</span> </span>
</p> </p>
</Reveal> </Reveal>
@@ -82,7 +81,7 @@ export const Hero = () => {
style={{ fontFamily: "var(--cm-font-mono)" }} style={{ fontFamily: "var(--cm-font-mono)" }}
> >
<span className="text-[var(--cm-clay)]">$</span> <span className="text-[var(--cm-clay)]">$</span>
<span>curl -fsSL claudemesh.com/install | bash</span> <span>curl -fsSL claudemesh.sh/install | bash</span>
</div> </div>
</div> </div>
</Reveal> </Reveal>
@@ -94,7 +93,7 @@ export const Hero = () => {
> >
Or{" "} Or{" "}
<Link <Link
href="https://github.com/alezmad/claudemesh-cli#readme" href="#docs"
className="underline decoration-[var(--cm-fg-tertiary)] underline-offset-4 transition-colors hover:text-[var(--cm-fg)] hover:decoration-[var(--cm-clay)]" className="underline decoration-[var(--cm-fg-tertiary)] underline-offset-4 transition-colors hover:text-[var(--cm-fg)] hover:decoration-[var(--cm-clay)]"
> >
read the documentation read the documentation

View File

@@ -50,7 +50,7 @@ export const LaptopToLaptop = () => {
</Reveal> </Reveal>
<Reveal delay={3} className="mt-10 flex justify-center"> <Reveal delay={3} className="mt-10 flex justify-center">
<Link <Link
href="/auth/register" href="#"
className="inline-flex items-center justify-center gap-2 rounded-[var(--cm-radius-xs)] border border-[var(--cm-fg-tertiary)] px-5 py-3 text-sm font-medium text-[var(--cm-fg)] transition-colors hover:border-[var(--cm-fg)] hover:bg-[var(--cm-bg)]" className="inline-flex items-center justify-center gap-2 rounded-[var(--cm-radius-xs)] border border-[var(--cm-fg-tertiary)] px-5 py-3 text-sm font-medium text-[var(--cm-fg)] transition-colors hover:border-[var(--cm-fg)] hover:bg-[var(--cm-bg)]"
style={{ fontFamily: "var(--cm-font-sans)" }} style={{ fontFamily: "var(--cm-font-sans)" }}
> >

View File

@@ -6,7 +6,7 @@ const CARDS = [
accent: "clay", accent: "clay",
title: "Start in your terminal", title: "Start in your terminal",
body: "Drop the broker next to Claude Code. One env var. Your session joins the mesh.", body: "Drop the broker next to Claude Code. One env var. Your session joins the mesh.",
cta: { label: "Install", href: "https://github.com/alezmad/claudemesh-cli#install" }, cta: { label: "Install", href: "#" },
mock: ( mock: (
<div <div
className="rounded-[8px] bg-[#D97757] p-6 font-mono text-[11px] leading-[1.6] text-[#141413]" className="rounded-[8px] bg-[#D97757] p-6 font-mono text-[11px] leading-[1.6] text-[#141413]"
@@ -26,8 +26,8 @@ const CARDS = [
accent: "oat", accent: "oat",
title: "Bridge to your editor", title: "Bridge to your editor",
body: "VS Code, Cursor, JetBrains — the mesh exposes an MCP server your editor's agent can call.", body: "VS Code, Cursor, JetBrains — the mesh exposes an MCP server your editor's agent can call.",
cta: { label: "VS Code", href: "https://github.com/alezmad/claudemesh-cli#readme" }, cta: { label: "VS Code", href: "#" },
cta2: { label: "JetBrains", href: "https://github.com/alezmad/claudemesh-cli#readme" }, cta2: { label: "JetBrains", href: "#" },
mock: ( mock: (
<div <div
className="rounded-[8px] border border-[var(--cm-border)] bg-[var(--cm-bg)] p-4" className="rounded-[8px] border border-[var(--cm-border)] bg-[var(--cm-bg)] p-4"
@@ -52,7 +52,7 @@ const CARDS = [
accent: "cactus", accent: "cactus",
title: "Reach across machines", title: "Reach across machines",
body: "Tailscale, WireGuard, or plain WS over your LAN. The broker is one binary, anywhere.", body: "Tailscale, WireGuard, or plain WS over your LAN. The broker is one binary, anywhere.",
cta: { label: "Open the dashboard", href: "/dashboard" }, cta: { label: "Open the dashboard", href: "#" },
mock: ( mock: (
<div <div
className="rounded-[8px] border border-[var(--cm-border)] bg-[var(--cm-bg)] p-4" className="rounded-[8px] border border-[var(--cm-border)] bg-[var(--cm-bg)] p-4"

View File

@@ -121,13 +121,6 @@ export interface MeshStreamProps {
emptyLabel?: string; emptyLabel?: string;
/** footer content (stats / progress bar / timers) */ /** footer content (stats / progress bar / timers) */
footer?: React.ReactNode; footer?: React.ReactNode;
/**
* When true (live dashboard), the message list gets a fixed viewport
* with overflow-y-auto — standard chat UI. When false (landing demo),
* the list grows intrinsically so wheel events pass through to the
* page scroll instead of being captured by the list.
*/
scrollable?: boolean;
} }
export const MeshStream = ({ export const MeshStream = ({
@@ -137,7 +130,6 @@ export const MeshStream = ({
peersHint, peersHint,
emptyLabel = "Waiting for messages…", emptyLabel = "Waiting for messages…",
footer, footer,
scrollable = false,
}: MeshStreamProps) => { }: MeshStreamProps) => {
const [focusedPeer, setFocusedPeer] = useState<string | null>(null); const [focusedPeer, setFocusedPeer] = useState<string | null>(null);
const [hoveredKey, setHoveredKey] = useState<string | null>(null); const [hoveredKey, setHoveredKey] = useState<string | null>(null);
@@ -148,12 +140,7 @@ export const MeshStream = ({
: messages; : messages;
return ( return (
<div <div className="grid min-h-[480px] grid-cols-1 md:grid-cols-[220px_1fr]">
className={
"grid grid-cols-1 md:grid-cols-[220px_1fr] " +
(scrollable ? "min-h-[480px]" : "")
}
>
{/* peers sidebar */} {/* peers sidebar */}
<aside <aside
className="border-b border-[var(--cm-border)] bg-[var(--cm-bg-elevated)]/20 p-4 md:border-b-0 md:border-r" className="border-b border-[var(--cm-border)] bg-[var(--cm-bg-elevated)]/20 p-4 md:border-b-0 md:border-r"
@@ -252,12 +239,7 @@ export const MeshStream = ({
: "all peers · E2E encrypted"} : "all peers · E2E encrypted"}
</span> </span>
</div> </div>
<ol <ol className="flex-1 space-y-3 overflow-y-auto p-4">
className={
"space-y-3 p-4 " +
(scrollable ? "flex-1 overflow-y-auto" : "")
}
>
{filtered.length === 0 && ( {filtered.length === 0 && (
<li <li
className="py-8 text-center text-[13px] text-[var(--cm-fg-tertiary)]" className="py-8 text-center text-[13px] text-[var(--cm-fg-tertiary)]"

View File

@@ -1,25 +1,64 @@
"use client";
import { useState } from "react";
import Link from "next/link"; import Link from "next/link";
import { Reveal, SectionIcon } from "./_reveal"; import { Reveal, SectionIcon } from "./_reveal";
const SHIPPING = [ const TIERS = {
"CLI + MCP server (Claude Code integration)", individual: [
"Hosted broker on claudemesh.com", {
"End-to-end encrypted direct messages (crypto_box)", name: "Solo",
"Priority routing (now / next / low)", desc: "Run the broker on your laptop. Pair your Claude Code sessions across repos.",
"Mesh invites + membership", price: "Free",
"Windows, macOS, Linux support", cta: "Start free",
]; href: "/auth/register",
},
const ROADMAP = [ {
"Mesh dashboard (browser UI)", name: "Pro",
"Message history + retention controls", desc: "Mesh dashboard, peer registry, message history, priority routing.",
"Audit log", price: "$12",
"Slack / WhatsApp / Telegram gateways", note: "per month",
"Self-host broker + SSO", cta: "Start free trial",
"Cross-broker federation", href: "/auth/register",
]; },
{
name: "Plus",
desc: "Cross-machine mesh via Tailscale / WireGuard, MCP bridge, audit log.",
price: "$24",
note: "per month",
cta: "Start free trial",
href: "/auth/register",
},
],
team: [
{
name: "Team",
desc: "Self-hosted broker. SSO, shared presence, team audit log, 25 peers.",
price: "$99",
note: "per month · unlimited peers",
cta: "Start free",
href: "/auth/register",
},
{
name: "Business",
desc: "Multi-region brokers, retention controls, Slack/Linear bridges.",
price: "$499",
note: "per month",
cta: "Start free",
href: "/auth/register",
},
{
name: "Enterprise",
desc: "Air-gapped deploy, custom SAML, dedicated support, SOC 2 pack.",
price: "Contact",
cta: "Contact sales",
href: "/contact",
},
],
};
export const Pricing = () => { export const Pricing = () => {
const [tab, setTab] = useState<"individual" | "team">("individual");
const tiers = TIERS[tab];
return ( return (
<section className="border-b border-[var(--cm-border)] bg-[var(--cm-bg)] px-6 py-24 md:px-12 md:py-32"> <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)]"> <div className="mx-auto max-w-[var(--cm-max-w)]">
@@ -34,104 +73,72 @@ export const Pricing = () => {
Get started with claudemesh Get started with claudemesh
</h2> </h2>
</Reveal> </Reveal>
<Reveal delay={2}> <Reveal delay={2} className="mt-10 flex justify-center">
<p <div className="inline-flex rounded-[var(--cm-radius-xs)] border border-[var(--cm-border)] bg-[var(--cm-bg-elevated)] p-1">
className="mx-auto mt-4 max-w-[520px] text-center text-[15px] leading-[1.6] text-[var(--cm-fg-secondary)]" {(["individual", "team"] as const).map((k) => (
style={{ fontFamily: "var(--cm-font-sans)" }} <button
> key={k}
Free during public beta. The CLI is MIT-licensed. The hosted onClick={() => setTab(k)}
broker stays free while the roadmap ships. No billing today. className={
</p> "rounded-[calc(var(--cm-radius-xs)-2px)] px-4 py-2 text-[13px] font-medium transition-colors " +
</Reveal> (tab === k
? "bg-[var(--cm-fg)] text-[var(--cm-bg)]"
<Reveal delay={3}> : "text-[var(--cm-fg-secondary)] hover:text-[var(--cm-fg)]")
<div className="mx-auto mt-16 max-w-[720px] rounded-[var(--cm-radius-md)] border border-[var(--cm-border)] bg-[var(--cm-bg-elevated)] p-8 md:p-10"> }
<div className="mb-6 flex items-baseline justify-between gap-4"> style={{ fontFamily: "var(--cm-font-sans)" }}
<h3
className="text-[28px] font-medium leading-tight text-[var(--cm-fg)]"
style={{ fontFamily: "var(--cm-font-serif)" }}
> >
Public beta {k === "individual" ? "Individual" : "Team & Enterprise"}
</h3> </button>
<div className="text-right"> ))}
<div </div>
className="text-[32px] font-medium text-[var(--cm-fg)]" </Reveal>
<Reveal delay={3}>
<div className="mt-16 grid gap-6 md:grid-cols-3">
{tiers.map((tier) => (
<article
key={tier.name}
className="flex flex-col rounded-[var(--cm-radius-md)] border border-[var(--cm-border)] bg-[var(--cm-bg-elevated)] p-8 transition-colors hover:border-[var(--cm-clay)]"
>
<div className="mb-5">
<SectionIcon glyph="leaf" />
</div>
<h3
className="mb-2 text-[28px] font-medium leading-tight text-[var(--cm-fg)]"
style={{ fontFamily: "var(--cm-font-serif)" }} style={{ fontFamily: "var(--cm-font-serif)" }}
> >
Free {tier.name}
</div> </h3>
<div <p
className="text-xs text-[var(--cm-fg-tertiary)]" className="mb-6 text-[14px] leading-[1.6] text-[var(--cm-fg-secondary)]"
style={{ fontFamily: "var(--cm-font-mono)" }} style={{ fontFamily: "var(--cm-font-serif)" }}
> >
no card required {tier.desc}
</div> </p>
</div> <div className="mb-6 mt-auto">
</div> <div
className="text-[32px] font-medium text-[var(--cm-fg)]"
<div className="grid gap-8 md:grid-cols-2"> style={{ fontFamily: "var(--cm-font-serif)" }}
<div> >
<div {tier.price}
className="mb-3 text-[10px] uppercase tracking-wider text-[var(--cm-fg-tertiary)]" </div>
style={{ fontFamily: "var(--cm-font-mono)" }} {tier.note && (
> <div
Shipping today className="text-xs text-[var(--cm-fg-tertiary)]"
</div> style={{ fontFamily: "var(--cm-font-mono)" }}
<ul className="space-y-2">
{SHIPPING.map((item) => (
<li
key={item}
className="flex items-start gap-2 text-[13px] leading-[1.6] text-[var(--cm-fg-secondary)]"
style={{ fontFamily: "var(--cm-font-sans)" }}
> >
<span className="mt-[6px] block h-[6px] w-[6px] shrink-0 rounded-full bg-[var(--cm-clay)]" /> {tier.note}
<span>{item}</span> </div>
</li> )}
))}
</ul>
</div>
<div>
<div
className="mb-3 text-[10px] uppercase tracking-wider text-[var(--cm-fg-tertiary)]"
style={{ fontFamily: "var(--cm-font-mono)" }}
>
Roadmap · v0.2v0.3
</div> </div>
<ul className="space-y-2"> <Link
{ROADMAP.map((item) => ( href={tier.href}
<li className="inline-flex items-center justify-center gap-2 rounded-[var(--cm-radius-xs)] border border-[var(--cm-fg-tertiary)] px-5 py-2.5 text-sm font-medium text-[var(--cm-fg)] transition-colors hover:border-[var(--cm-fg)] hover:bg-[var(--cm-bg)]"
key={item} style={{ fontFamily: "var(--cm-font-sans)" }}
className="flex items-start gap-2 text-[13px] leading-[1.6] text-[var(--cm-fg-tertiary)]" >
style={{ fontFamily: "var(--cm-font-sans)" }} {tier.cta}
> </Link>
<span className="mt-[6px] block h-[6px] w-[6px] shrink-0 rounded-full border border-[var(--cm-fg-tertiary)]" /> </article>
<span>{item}</span> ))}
</li>
))}
</ul>
</div>
</div>
<div className="mt-8 flex flex-col items-start gap-3 border-t border-[var(--cm-border)] pt-6 sm:flex-row sm:items-center sm:justify-between">
<p
className="text-[12px] leading-[1.5] text-[var(--cm-fg-tertiary)]"
style={{ fontFamily: "var(--cm-font-sans)" }}
>
Paid tiers launch when the dashboard ships. Beta users keep
the free plan for life.
</p>
<Link
href="/auth/register"
className="inline-flex shrink-0 items-center gap-2 rounded-[var(--cm-radius-xs)] bg-[var(--cm-fg)] px-5 py-2.5 text-sm font-medium text-[var(--cm-bg)] transition-colors hover:bg-[var(--cm-gray-150)]"
style={{ fontFamily: "var(--cm-font-sans)" }}
>
Start free
<span className="transition-transform duration-300 group-hover:translate-x-0.5">
</span>
</Link>
</div>
</div> </div>
</Reveal> </Reveal>
</div> </div>

View File

@@ -137,7 +137,7 @@ export const Surfaces = () => {
name, by repo, by priority. name, by repo, by priority.
</p> </p>
<Link <Link
href="/dashboard" href="#"
className="inline-flex items-center gap-2 rounded-[var(--cm-radius-xs)] border border-[var(--cm-fg-tertiary)] px-5 py-2.5 text-sm font-medium text-[var(--cm-fg)] transition-colors hover:border-[var(--cm-fg)] hover:bg-[var(--cm-bg)]" className="inline-flex items-center gap-2 rounded-[var(--cm-radius-xs)] border border-[var(--cm-fg-tertiary)] px-5 py-2.5 text-sm font-medium text-[var(--cm-fg)] transition-colors hover:border-[var(--cm-fg)] hover:bg-[var(--cm-bg)]"
style={{ fontFamily: "var(--cm-font-sans)" }} style={{ fontFamily: "var(--cm-font-sans)" }}
> >

View File

@@ -3,12 +3,6 @@ import { useState } from "react";
import Link from "next/link"; import Link from "next/link";
const NEWS = [ const NEWS = [
{
tag: "New",
title: "claudemesh launch (v0.1.2)",
body: "Real-time peer messages pushed into Claude Code mid-turn. One command. Source open at github.com/alezmad/claudemesh-cli.",
href: "https://github.com/alezmad/claudemesh-cli",
},
{ {
tag: "Beta", tag: "Beta",
title: "Mesh Dashboard", title: "Mesh Dashboard",

View File

@@ -242,7 +242,7 @@ const USE_CASES: UseCase[] = [
title: "Bug Alice fixed, Bob rediscovers", title: "Bug Alice fixed, Bob rediscovers",
before: before:
"Alice in payments-api fixes a Stripe signature bug. Two weeks later, Bob in checkout-frontend hits the same thing. Alice's fix is buried in a PR thread. Bob re-solves it for three hours.", "Alice in payments-api fixes a Stripe signature bug. Two weeks later, Bob in checkout-frontend hits the same thing. Alice's fix is buried in a PR thread. Bob re-solves it for three hours.",
now: "Bob's Claude asks the mesh: who's seen this? Alice's Claude volunteers with context. Bob solves in ten minutes. Alice isn't interrupted — her Claude shares the history on its own.", now: "Bob's Claude asks the mesh: who's seen this? Alice's Claude self-nominates with context. Bob solves in ten minutes. Alice isn't interrupted — her Claude surfaces the history on its own.",
limits: limits:
"Each Claude stays inside its own repo. Nobody's reading anyone else's files. Information flows at the agent layer, with a human still on the PR.", "Each Claude stays inside its own repo. Nobody's reading anyone else's files. Information flows at the agent layer, with a human still on the PR.",
}, },