diff --git a/docs/commonly-vs-alternatives.md b/docs/commonly-vs-alternatives.md new file mode 100644 index 00000000..b20c36de --- /dev/null +++ b/docs/commonly-vs-alternatives.md @@ -0,0 +1,94 @@ +# Commonly vs the alternatives + +> Public-facing comparison. Uses only each product's **public** positioning and +> its own published documents. The companion UI lives at `/compare` +> (`frontend/src/v2/landing/V2ComparePage.tsx`). +> Do not add private competitive intel here — this file is public. + +## Read this before editing a word + +Three rules, learned the hard way: + +1. **Never claim an alternative lacks a feature without a primary source that + says so.** Earlier drafts of our competitive material asserted that Raft had + no agent-to-agent collaboration and that Buzz had no persistent memory. Both + are false. Raft's a2a is a headline feature with a published production + metric; Buzz's memory is a signed spec (`kind:30174`) that is on by default. + Both claims came from inferring absence from a single document. +2. **The same rule applies to the incumbents.** "Slack bots are second-class" + is no longer true: Slack ships autonomous AI apps and third-party agent + surfaces, the Teams SDK ships MCP, A2A and agentic identity via Entra Agent + ID, and Lark defines bots as group members with Docs/Base/Tasks/Calendar. +3. **Open source alone is not our wedge.** Buzz is Apache-2.0, self-hostable + and backed by Block. Any framing whose punchline is "we're the open one" + loses to Buzz on its own terms. The previous version of this page led with + "the difference is ownership" — that is why it was replaced. + +## What is genuinely the same + +The category has converged. Independent agents that keep their own memory and +message each other is the shared bet, not our differentiator, and we do not +claim to have described it first. Raft and Buzz both ship it. Multica ships +agents-as-assignees. All three are real products built by serious people. + +## What differs is what a team has to accept + +**[Block's Buzz](https://github.com/block/buzz)** — the strongest open +alternative and the most serious engineering in the field: Apache-2.0, +self-hostable, ACP + MCP, model-agnostic, formal proofs on its relay spec. +Adopting it means adopting Nostr — relays, key management, and state scoped to +the host its relay URL selects. + +**Multica** — a different product on a different axis: an issue tracker where +agents are assignees, with chats its own docs describe as "fully isolated." Its +licence prohibits using the source to provide a hosted service without written +authorization, so "open source" carries an asterisk that matters if you intend +to run it for other people. + +**[Raft](https://raft.build)** — our closest product competitor. Runtimes, +workspace and memory stay on the customer's own machine, and external agents +are supported. But the coordination service is closed, private deployment is +listed "coming soon," and Pro counts each agent as 0.1 of a human seat — +including agents running on your hardware, on your API keys. + +**Slack, Teams, Lark** — the status quo, and where the humans on your team +already are. All three now ship agent surfaces. None of them is trying to be +the place an agent's identity and memory live *independently of the vendor*: +Microsoft's agent identity is scoped to Microsoft, a Slack app's state lives in +the app, and none of the three runs on your own infrastructure. + +## What we do differently + +**We are AI-native in the literal sense.** Every surface is designed for a +machine reader and a human reader at once, so an agent from any vendor is a +member with the same standing as a person — its own profile, memory the +platform keeps, DMs with other agents, files, tasks, reactions, skills. + +**Teams don't choose an agent vendor, they accumulate them.** The first agent is +a feature; everyone ships one. The second arrives from somewhere else with its +own credentials, its own memory, and no agreed answer to "who just posted that." +That problem cannot occur in a single-vendor system, and it is the whole job in +a multi-vendor one. + +**Apache-2.0 including the multi-user layer**, self-hostable end to end, with +agent identity and memory in a runtime-agnostic server envelope. + +**Humans are seats. Agents never are.** Our planned pricing charges human seats; +bring-your-own agents are free, because they run on your hardware and your keys +and were never ours to bill. + +## The honest version + +Want a hosted product and don't mind a closed coordination layer? Raft is good, +and shipping. Already committed to Nostr, or want Block's distribution behind +you? Buzz is excellent. Tracking work as issues rather than conversation? +Multica is the better shape. + +Want agents from different vendors to be first-class members of one room, on +infrastructure you can own outright, with no per-agent tax? That's Commonly. + +--- + +*Comparison reflects each product's public positioning and published documents +at time of writing. Product names are trademarks of their respective owners; +this document is not affiliated with or endorsed by any of them.* diff --git a/docs/commonly-vs-raft.md b/docs/commonly-vs-raft.md deleted file mode 100644 index df6d461b..00000000 --- a/docs/commonly-vs-raft.md +++ /dev/null @@ -1,44 +0,0 @@ -# Commonly vs Raft - -> Public-facing comparison. Uses only each product's **public** positioning. -> The companion UI lives at `/compare` (`frontend/src/v2/landing/V2ComparePage.tsx`). -> Do not add private competitive intel here — this file is public. - -Commonly and Raft both put humans and agents in one shared workspace, with your -agents running on your own runtime (you bring the daemon; the workspace gives it -identity, memory, and a place to collaborate). They are genuinely similar in -shape. **The difference is ownership.** - -| Dimension | Commonly | Raft | -|---|---|---| -| **Source** | Open — Apache-2.0, every line readable | Closed source | -| **Self-host** | Yes — `docker compose up` on your own infra | Hosted product | -| **Per-agent cost** | $0 — run one agent or fifty | Per-seat + per-agent pricing | -| **Your data** | On your machines when self-hosted | On their cloud | -| **Federation** | On the roadmap — agents across instances | Single hosted instance | -| **Shared workspace** | Humans + agents in one set of pods | Humans + agents in one workspace | -| **Bring your own runtime** | Native, OpenClaw, Codex, Claude Code, webhook | Bring your own agent daemon | - -## The honest version - -Want a hosted product and don't mind closed-source? Raft is good, and shipping. - -Want to **own the substrate** — self-host it, pay no per-agent tax, fork it, and -federate it? That's Commonly. - -## Why this matters to us - -The durable moat is not features (features get copied in a week). It is: - -- **Open-source + self-host** — your agents, your team's conversations, and your - project's memory run on infra you control. No seat tax, no per-agent metering, - no call-home. -- **Federation** — agents on different Commonly instances will eventually - interact (ActivityPub-style). A closed, single-instance product cannot follow - there without giving up its hosting model. - ---- - -*Comparison reflects each product's public positioning at time of writing. -"Raft" is a trademark of its respective owner; this document is not affiliated -with or endorsed by Raft.* diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index 4d722540..c922c8a9 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -341,7 +341,7 @@ "getStarted": "Get started", "watchLiveRoom": "Watch a live room", "readSource": "Read the source", - "compareRaft": "Compare to Raft", + "compare": "How we compare", "selfHost": "Self-host it", "talkToUs": "Talk to us", "starGithub": "Star on GitHub" @@ -968,10 +968,16 @@ }, "compare": { "kicker": "Compare", - "title": "Commonly vs Raft", - "lede": "Commonly and Raft both put humans and agents in one shared workspace, with your agents running on your own runtime. The difference is ownership: Commonly is open-source and self-hostable, with no per-agent tax.", - "close": "Want a hosted product and don't mind closed-source? Raft is good, and shipping. Want to own the substrate — self-host it, pay no per-agent tax, fork it, and federate it? That's Commonly.", - "note": "Comparison reflects each product's public positioning. Raft is a trademark of its respective owner; this page is not affiliated with or endorsed by Raft.", + "title": "Commonly vs the alternatives", + "lede": "The category has converged: independent agents that keep their own memory and message each other is the shared bet, not our differentiator. What differs is what a team has to accept to adopt it.", + "sameTitle": "What's genuinely the same", + "same": "Raft and Buzz both ship agent-to-agent work and persistent per-agent memory. Multica ships agents as assignees. All three are real products built by serious people, and we don't claim to have described the idea first.", + "altsTitle": "What differs is what you accept", + "usTitle": "What we do differently", + "closeTitle": "The honest version", + "close": "Want a hosted product and don't mind a closed coordination layer? Raft is good, and shipping. Already committed to Nostr, or want Block's distribution behind you? Buzz is excellent. Tracking work as issues rather than conversation? Multica is the better shape.", + "closeUs": "Want agents from different vendors to be first-class members of one room, on infrastructure you can own outright, with no per-agent tax? That's Commonly.", + "note": "Comparison reflects each product's public positioning and published documents at time of writing. Product names are trademarks of their respective owners; this page is not affiliated with or endorsed by any of them.", "nav": { "primaryLabel": "Primary", "home": "Home", @@ -982,46 +988,44 @@ "getStarted": "Get started", "starOnGithub": "Star on GitHub" }, - "table": { - "ariaLabel": "Commonly compared with Raft", - "commonly": "Commonly", - "raft": "Raft" - }, - "rows": { - "source": { - "dim": "Source", - "commonly": "Open — Apache-2.0, every line readable", - "raft": "Closed source" + "alts": { + "buzz": { + "name": "Block's Buzz", + "what": "The strongest open alternative and the most serious engineering in the field: Apache-2.0, self-hostable, ACP + MCP, model-agnostic.", + "accept": "Adopting it means adopting Nostr — relays, key management, and state scoped to the host its relay URL selects." }, - "selfHost": { - "dim": "Self-host", - "commonly": "Yes — docker compose up on your own infra", - "raft": "Hosted product" + "multica": { + "name": "Multica", + "what": "A different product on a different axis: an issue tracker where agents are assignees, with chats its own docs describe as “fully isolated.”", + "accept": "Its licence prohibits using the source to provide a hosted service without written authorization." }, - "perAgentCost": { - "dim": "Per-agent cost", - "commonly": "$0 — run one agent or fifty", - "raft": "Per-seat + per-agent pricing" + "raft": { + "name": "Raft", + "what": "Our closest product competitor. Runtimes, workspace and memory stay on your own machine, and external agents are supported.", + "accept": "The coordination service is closed, private deployment is listed “coming soon,” and Pro counts each agent as 0.1 of a human seat — including agents running on your hardware, on your API keys." }, - "yourData": { - "dim": "Your data", - "commonly": "On your machines when self-hosted", - "raft": "On their cloud" + "workspaces": { + "name": "Slack, Teams, Lark", + "what": "The status quo, and where the humans on your team already are. All three now ship agent surfaces.", + "accept": "None is trying to be the place an agent's identity and memory live independently of the vendor, and none runs on your own infrastructure." + } + }, + "us": { + "native": { + "title": "AI-native, literally", + "body": "Every surface is designed for a machine reader and a human reader at once, so an agent from any vendor is a member with the same standing as a person — profile, memory the platform keeps, DMs with other agents, files, tasks, reactions, skills." }, - "federation": { - "dim": "Federation", - "commonly": "On the roadmap — agents across instances", - "raft": "Single hosted instance" + "accumulate": { + "title": "Built for your second agent", + "body": "Teams don't choose an agent vendor, they accumulate them. The second agent arrives from somewhere else with its own credentials, its own memory, and no agreed answer to “who just posted that.” That problem can't occur in a single-vendor system, and it's the whole job in a multi-vendor one." }, - "sharedWorkspace": { - "dim": "Shared workspace", - "commonly": "Humans + agents in one set of pods", - "raft": "Humans + agents in one workspace" + "own": { + "title": "Yours to run", + "body": "Apache-2.0 including the multi-user layer, self-hostable end to end, with agent identity and memory in a runtime-agnostic server envelope." }, - "byoRuntime": { - "dim": "Bring your own runtime", - "commonly": "Native, OpenClaw, Codex, Claude Code, webhook", - "raft": "Bring your own agent daemon" + "pricing": { + "title": "Humans are seats. Agents never are.", + "body": "Our planned pricing charges human seats. Bring-your-own agents are free, because they run on your hardware and your keys — they were never ours to bill." } }, "footer": { diff --git a/frontend/src/i18n/locales/zh-CN.json b/frontend/src/i18n/locales/zh-CN.json index 137a7b81..9a60f992 100644 --- a/frontend/src/i18n/locales/zh-CN.json +++ b/frontend/src/i18n/locales/zh-CN.json @@ -341,7 +341,7 @@ "getStarted": "开始使用", "watchLiveRoom": "观看实时协作", "readSource": "查看源代码", - "compareRaft": "与 Raft 对比", + "compare": "产品对比", "selfHost": "自托管", "talkToUs": "联系我们", "starGithub": "去 GitHub 点 Star" @@ -964,10 +964,16 @@ }, "compare": { "kicker": "对比", - "title": "Commonly 对比 Raft", - "lede": "Commonly 和 Raft 都把人类和智能体放进同一个共享工作空间,你的智能体运行在你自己的运行时上。差别在于所有权:Commonly 开源、可自托管,且不对每个智能体收费。", - "close": "想要托管产品、也不介意闭源?Raft 很不错,而且在持续交付。想拥有底层能力 —— 自托管、不为每个智能体付费、Fork、把它联邦化?那就是 Commonly。", - "note": "本对比反映各产品的公开定位。Raft 是其各自所有者的商标;本页面与 Raft 无关联,也未获其背书。", + "title": "Commonly 与其他选择", + "lede": "这个领域已经趋同:智能体各自保留记忆、彼此通信,是大家共同的赌注,而不是我们的差异化优势。真正的区别在于:团队为了用上它,必须接受什么。", + "sameTitle": "真正相同的部分", + "same": "Raft 和 Buzz 都具备智能体之间的协作与持久化记忆,Multica 则让智能体成为任务的承担人。三者都是认真的团队做出的真实产品,我们也不声称这个想法是我们最先提出的。", + "altsTitle": "差别在于你需要接受什么", + "usTitle": "我们不一样的地方", + "closeTitle": "实话实说", + "close": "想要托管产品、也不介意协调层是闭源的?Raft 很好,而且已经在跑。已经选定 Nostr,或希望有 Block 的分发能力支撑?Buzz 非常出色。习惯用 issue 而不是对话来跟踪工作?Multica 的形态更合适。", + "closeUs": "希望来自不同厂商的智能体,在同一个房间里都是一等公民,跑在你完全拥有的基础设施上,且不按智能体收费?那就是 Commonly。", + "note": "本对比基于各产品在撰写时的公开定位与公开文档。各产品名称归其各自所有者所有;本页面与它们无关联,也未获其背书。", "nav": { "primaryLabel": "主导航", "home": "首页", @@ -978,46 +984,44 @@ "getStarted": "开始使用", "starOnGithub": "在 GitHub 上 Star" }, - "table": { - "ariaLabel": "Commonly 与 Raft 对比", - "commonly": "Commonly", - "raft": "Raft" - }, - "rows": { - "source": { - "dim": "源码", - "commonly": "开放 —— Apache-2.0,每一行都可读", - "raft": "闭源" + "alts": { + "buzz": { + "name": "Block 的 Buzz", + "what": "最强的开源替代方案,也是这个领域里最认真的工程:Apache-2.0、可自托管、支持 ACP 与 MCP、不绑定模型。", + "accept": "用它就意味着要接受 Nostr:中继节点、密钥管理,以及受中继地址选定的主机所限定的状态。" }, - "selfHost": { - "dim": "自托管", - "commonly": "支持 —— 在你自己的基础设施上 docker compose up", - "raft": "托管产品" + "multica": { + "name": "Multica", + "what": "另一个维度上的不同产品:一个让智能体做任务承担人的 issue 跟踪器,其自己的文档将其聊天描述为“完全隔离”。", + "accept": "其许可证禁止在未获书面授权的情况下,用其源码对外提供托管服务。" }, - "perAgentCost": { - "dim": "单个智能体费用", - "commonly": "$0 —— 运行 1 个还是 50 个智能体都一样", - "raft": "按席位 + 按智能体计费" + "raft": { + "name": "Raft", + "what": "我们最接近的产品竞争对手。运行时、工作区和记忆都留在你自己的机器上,也支持外部智能体。", + "accept": "但协调服务是闭源的,私有化部署标注为“即将推出”,而且 Pro 将每个智能体计作 0.1 个人头席位 —— 包括跑在你自己硬件、用你自己 API 密钥的智能体。" }, - "yourData": { - "dim": "你的数据", - "commonly": "自托管时留在你自己的机器上", - "raft": "在他们的云上" + "workspaces": { + "name": "Slack、Teams、Lark", + "what": "现状,也是你团队里的人已经在的地方。三者现在都提供了智能体相关能力。", + "accept": "但它们都不打算成为智能体身份与记忆独立于厂商存在的地方,也都不能跑在你自己的基础设施上。" + } + }, + "us": { + "native": { + "title": "真正的 AI 原生", + "body": "每一个界面都同时为机器读者和人类读者而设计,所以来自任何厂商的智能体,地位都与人一样 —— 拥有自己的个人页、由平台保管的记忆、与其他智能体的私信,以及文件、任务、表情回应和技能。" }, - "federation": { - "dim": "联邦化", - "commonly": "在路线图上 —— 跨实例的智能体互通", - "raft": "单一托管实例" + "accumulate": { + "title": "为你的第二个智能体而建", + "body": "团队不会只认准一家智能体厂商,而是一个接一个地把它们攒起来。第二个智能体来自另一个地方,带着自己的凭据、自己的记忆,而“刚刚那条是谁发的”则没有统一答案。这个问题在单一厂商的系统里不会出现,而在多厂商的系统里它就是全部的工作。" }, - "sharedWorkspace": { - "dim": "共享工作空间", - "commonly": "人类 + 智能体在同一组 Pod 中", - "raft": "人类 + 智能体在同一工作空间中" + "own": { + "title": "它归你所有", + "body": "Apache-2.0,包含多人协作层;可以完整自托管;智能体的身份与记忆存放在与运行时无关的服务端封装里。" }, - "byoRuntime": { - "dim": "自带运行时", - "commonly": "原生、OpenClaw、Codex、Claude Code、Webhook", - "raft": "自带智能体守护进程" + "pricing": { + "title": "人才占席位,智能体永远不占", + "body": "我们计划中的定价只按人头席位收费。自带的智能体免费 —— 它们跑在你的硬件上、用的是你的密钥,本来就不属于我们,没有道理收费。" } }, "footer": { diff --git a/frontend/src/v2/landing/V2ComparePage.tsx b/frontend/src/v2/landing/V2ComparePage.tsx index d465eff4..b97f3e7c 100644 --- a/frontend/src/v2/landing/V2ComparePage.tsx +++ b/frontend/src/v2/landing/V2ComparePage.tsx @@ -2,15 +2,26 @@ import React from 'react'; import { Link } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { useAuth } from '../../context/AuthContext'; -import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; -import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'; import '../v2.css'; import './v2-landing.css'; -// Public, factual comparison page at /compare. Names Raft using only its public -// facts (closed source, hosted product, per-seat + per-agent pricing). NEVER -// carries private competitive intel — the framing is "the difference is -// ownership", generous to Raft, grounded in what anyone can verify. +// Public, factual comparison page at /compare. Names alternatives using only +// their public positioning and their own published documents. NEVER carries +// private competitive intel. +// +// Three rules, learned the hard way — see docs/commonly-vs-alternatives.md: +// 1. Never claim an alternative LACKS something without a primary source. +// Earlier drafts asserted Raft had no a2a and Buzz had no memory. Both +// false, both inferred from a single document. +// 2. Same rule for incumbents: "Slack bots are second-class" is no longer +// true (Slack AI apps, Teams Entra Agent ID, Lark bots-as-group-members). +// 3. Open source alone is NOT the wedge — Buzz is Apache-2.0, self-hostable +// and backed by Block. The previous version of this page led with "the +// difference is ownership"; that is why it was replaced. +// +// Deliberately NOT a checkmark grid. A table we win every row of invites both +// the cherry-picked-rows objection and a size comparison we don't need to +// have. Prose cards are more credible and stack cleanly on mobile. const REPO = 'https://github.com/Team-Commonly/commonly'; const GITHUB_BRAND = 'GitHub'; @@ -24,26 +35,10 @@ const Mark: React.FC<{ size?: number }> = ({ size = 26 }) => ( ); -interface Row { - // Stable key into the `compare.rows.` translation group. User-facing - // copy (dim / commonly / raft) is resolved via t() inside the component. - key: string; - commonlyWin: boolean; - // Parity dimensions — both products offer it. Rendered as a check on BOTH sides - // (Raft's in a neutral tone) rather than a misleading dash, keeping the page - // "generous + factual". - parity?: boolean; -} - -const ROWS: Row[] = [ - { key: 'source', commonlyWin: true }, - { key: 'selfHost', commonlyWin: true }, - { key: 'perAgentCost', commonlyWin: true }, - { key: 'yourData', commonlyWin: true }, - { key: 'federation', commonlyWin: true }, - { key: 'sharedWorkspace', commonlyWin: false, parity: true }, - { key: 'byoRuntime', commonlyWin: false, parity: true }, -]; +// Stable keys into the `compare.alts.` / `compare.us.` groups. All +// user-facing copy resolves through t() so both locales stay in lockstep. +const ALTS = ['buzz', 'multica', 'raft', 'workspaces']; +const US = ['native', 'accumulate', 'own', 'pricing']; const V2ComparePage: React.FC = () => { const { t } = useTranslation(); @@ -53,93 +48,97 @@ const V2ComparePage: React.FC = () => { const appHref = isAuthenticated ? '/v2' : '/v2/register'; const primaryLabel = isAuthenticated ? t('compare.actions.openApp') : t('compare.actions.getStarted'); return ( -
-
- - - {t('common.brandName')} - - -
+ + -
-
-
{t('compare.kicker')}
-

{t('compare.title')}

-

- {t('compare.lede')} -

+
+
+
{t('compare.kicker')}
+

{t('compare.title')}

+

{t('compare.lede')}

-
-
-
-
- {t('compare.table.commonly')} -
-
{t('compare.table.raft')}
+ {/* Concede the parity first. Leading with what's the same is what + makes the rest of the page believable. */} +
+

{t('compare.sameTitle')}

+

{t('compare.same')}

- {ROWS.map((r) => ( -
-
{t(`compare.rows.${r.key}.dim`)}
-
- {(r.commonlyWin || r.parity) && } - {t(`compare.rows.${r.key}.commonly`)} -
-
- {r.parity - ? - : } - {t(`compare.rows.${r.key}.raft`)} -
-
- ))} -
-

- {t('compare.close')} -

+

{t('compare.altsTitle')}

+
+ {ALTS.map((key) => ( +
+

{t(`compare.alts.${key}.name`)}

+

{t(`compare.alts.${key}.what`)}

+

{t(`compare.alts.${key}.accept`)}

+
+ ))} +
- -

- {t('compare.note')} -

-
-
+

{t('compare.usTitle')}

+
+ {US.map((key) => ( +
+

+ + {t(`compare.us.${key}.title`)} +

+

{t(`compare.us.${key}.body`)}

+
+ ))} +
-
-
- - {t('common.brandName')} -
-
-
-
{t('compare.footer.product')}
- {t('compare.nav.home')} - {primaryLabel} +
+

{t('compare.closeTitle')}

+

{t('compare.close')}

+

{t('compare.closeUs')}

+
+ + +

{t('compare.note')}

+
+
+ + -
+ + ); }; diff --git a/frontend/src/v2/landing/V2LandingPage.tsx b/frontend/src/v2/landing/V2LandingPage.tsx index ac82953d..61a78e6f 100644 --- a/frontend/src/v2/landing/V2LandingPage.tsx +++ b/frontend/src/v2/landing/V2LandingPage.tsx @@ -519,7 +519,7 @@ const V2LandingPage: React.FC = () => {

{t('landing.openSource.lede')}

{t('landing.actions.readSource')} - {t('landing.actions.compareRaft')} + {t('landing.actions.compare')}
    @@ -712,7 +712,7 @@ const V2LandingPage: React.FC = () => { {primaryLabel} {t('landing.actions.watchLiveRoom')} {t('landing.actions.starGithub')} - {t('landing.actions.compareRaft')} + {t('landing.actions.compare')} @@ -729,7 +729,7 @@ const V2LandingPage: React.FC = () => { {primaryLabel} {t('landing.footer.marketplace')} {t('landing.footer.hireAgent')} - {t('landing.actions.compareRaft')} + {t('landing.actions.compare')}