我的开源项目发布 8 天,被人用同一个名字"重新发明"了

8 阅读7分钟

三月初我往 npm 发了个包。叫 ClawNexus,做的事情是给 AI agent 提供身份注册——局域网自动发现、命名、加密通信。四个 workspace 包,TypeScript 写的,到现在大概近万行代码,七百多个测试。发布之后一直在密集迭代,半个月从 v0.0.1 推到了 v0.3.x。

3 月 9 号,我在 GitHub 上搜自己的包名想看看索引情况,搜出来一个同名仓库。

不是 fork。不是同一个语言。不是同一个人。但名字一模一样,做的事情也是 AI agent 身份管理。

第一反应不是生气,是懵。

时间线

先摆事实。

我的 npm 发布记录(这东西改不了,npm 时间戳是不可变的):

0.0.1  →  3月1日
0.2.0  →  3月5日
0.2.5  →  3月5日
0.2.8  →  3月8日
0.3.0  →  3月9日

对方的 GitHub 仓库:

首次 commit39日
三天内       →  32commit
贡献者       →  1

我 3 月 1 号发的包,对方 3 月 9 号第一次 commit。中间隔了 8 天。

然后我注意到一个细节:他的第一个 commit,打的版本标签是 v6.0

不是 v0.1.0。不是 v1.0.0。是 v6.0。

一个 3 月 9 号才开始写的项目,上来就是第六个大版本。要么前面五个版本都在某个私有仓库里,要么版本号是 AI 生成 README 的时候顺手补的。

我看了他的代码

不是为了找茬,是好奇。同一个名字、同一个领域,他到底做了什么?

技术栈是 Python + FastAPI + Supabase。表面上看功能列表挺长:身份系统、消息中继、信任评级、Solana 支付、Discord 机器人。README 写得很饱满。

然后我翻了源码。

消息中继——他叫 NexusRelay(对,跟我的 relay 同名)。实现是一个 aiohttp 服务器,内存里存一个 asyncio.Queue。消息进来存队列,客户端轮询取走。没有加密,没有密钥交换,服务重启消息全丢。

我的 relay 用的是 X25519 做 ECDH 密钥协商,AES-256-GCM 端到端加密。服务端看不到消息内容。这不是同一个量级的东西。

Solana 集成——README 上写着"ClawPay Escrow v3 deployed to mainnet"。我去看代码里的 SolanaProvider

class SolanaProvider(PaymentProvider):
    # ...空的
    pass

一个空类。链上合约倒是部署了,但 Python 这边没有任何调用代码。README 说的和代码做的是两件事。

信任系统——一个 Discord 机器人做人工审核。评级从 Iron 到 Challenger,十个等级,有积分公式。这个设计本身没问题,但是——他没有用户。0 star,0 fork,0 issue。一套精密的信任分计算公式,跑在一个没有人用的系统上。

发现机制——没有。不存在。他的架构是中心化的 Supabase 数据库,所有 agent 往里面注册。

他花了大量精力在支付系统、信任评级、Discord 集成上。这些都是"商业化外壳"——看起来重要,但不是这个领域的核心问题。

我的项目有四条发现链路:本地探测、UDP 广播、mDNS、子网扫描。零配置,启动就能找到同一个局域网里的其他实例。这部分的实现细节我之前单独写过一篇,mDNS 的坑、广播地址计算、虚拟网卡过滤这些都在里面。大学宿舍打星际争霸局域网,开局点一下就能看到所有房间——IPX 协议干的就是这个事。我想让 AI agent 也有同样的体验:接上网线,自己就能发现彼此。这是我花时间最多的部分,也是这个项目存在的核心理由。

做 AI agent 身份管理,核心问题就一个:怎么让 agent 在没有中心服务器的情况下找到彼此。他跳过了这个,去做 Solana 支付了。

45 分钟的恐慌

发现同名仓库之后我慌了大概 45 分钟。不是因为怕被"超越"——看了代码之后这个担心就没了。慌的是另一件事:我在 npm 之外什么都没占。

8 天了。npm 上包名是我的,但 PyPI 呢?crates.io 呢?

马上查 PyPI。没人注册。我用最快的速度搞了一个 pyproject.toml

$ pip install twine build
$ python -m build && twine upload dist/*

中间还浪费了 15 分钟搞明白 Python 打包现在到底是用 setup.py 还是 pyproject.toml。这生态两年换一次主意。

crates.io 也查了。也没人注册。注册了四个变体。我的 Rust 占位包里面只有一行:

// placeholder - real implementation coming

这算不算浪费注册表资源?大概算。但另一种选择是看着别人把它抢走。

45 分钟,npm、PyPI、crates.io 全部锁死。如果我在 3 月 1 号 npm publish 的同一天就干这些事,大概只需要 10 分钟,也不用出一身冷汗。

他提醒了我该做的事

说实话,这个人出现的时机对我来说反而是好事。

在他出现之前,我的项目是这样的:代码写得挺扎实,测试覆盖不错,但"生态"这个词跟我无关。我就是一个写 TypeScript 的人,把代码推到 npm 上,觉得 job done。

被同名项目刺激之后,我 48 小时内干了这些事:

动作之前之后
npm 包名✅ 有✅ 有
PyPI 占位❌ 没想过✅ 4 个包
crates.io 占位❌ 没想过✅ 4 个变体
package.json homepage❌ 没填✅ 指向 GitHub
README 首发日期标识❌ 没有✅ 加了
OpenClaw 生态 PR❌ 没提交✅ Community Plugins PR
ClawHub Skill✅ 有✅ 有

这张表的左列才是真正让我不舒服的东西。不是"被抄了"不舒服,是"这些事我居然没做"不舒服。

一个人花 3 天用 AI 生成了一个同名项目,迫使我在 48 小时内把第一天就该做的事情全部补上了。从结果上看,他帮了我。

三天能做出什么

这件事最让我感慨的是时间问题。

从 3 月 1 号 npm publish 到被人同名复刻,中间只有 8 天。但这 8 天里我推了九个版本——设计发现协议、实现四条链路、调 mDNS 跨平台兼容性、写 ECDH 密钥交换、搭 CLI 和 SDK、测试从零堆到几百个。

他花了三天:Discord 机器人 + Supabase CRUD + 空的 Solana 集成 + 一个不加密的 HTTP 队列。三十二个 commit,有 AI 辅助。

两个项目都叫同一个名字。如果你只看 README,他的功能列表其实更长——因为什么都往上写,包括没实现的。如果你看代码,差别就出来了。

AI 可以帮你在 3 天内生成一个项目的所有骨架。但它生成不了工程判断:该做什么、不该做什么、哪个方案试过不行、为什么选 UDP 广播而不是纯 mDNS。

README 可以写得很好看。能不能跑是另一回事。

不生气的理由

我现在对这件事的态度其实挺平和的。

一是因为它验证了方向。AI agent 身份注册这个领域确实有需求——不然不会有人在看到一个 npm 包 8 天之后就冲进来做同样的事。如果没人抄,说不定我还得怀疑自己是不是在解决一个不存在的问题。

二是因为抄不走的东西比抄得走的多。名字可以一样,README 可以更花哨,但四条发现链路的工程实现、端到端加密的正确性、几百个测试覆盖的边界 case——这些不是三天能复制的。

三是因为它实际上加速了我的规划。防御性注册、生态占位、README 标识,这些事本来排在"以后再说"里面。现在全做完了。路线图上的下一步是 v0.4 relay 和 v0.5 registrar,不用再分心去想"万一有人用这个名字怎么办"。

被复刻是一种验证。有人觉得你的方向值得抄,说明你走对了。

给发开源包的人的建议

如果你要发一个有独特名字的开源项目,publish 那天就把这些做了:

  1. 检查 PyPI、crates.io、Docker Hub 有没有同名的。没有就立刻占上
  2. package.json 里把 homepagerepository 填好。Google 索引 npm 包的时候会用这些字段
  3. README 顶部加个首发日期。不用写得像声明,就是一个时间戳
  4. 如果你的项目属于某个大生态(比如 OpenClaw),早点去官方渠道露脸——提 PR、发 Discussion、提交 Skill。别等着别人先去

这些事加起来不超过一个小时。换来的是一个对方三天赶不上的身位。


代码和实现细节都在仓库里,感兴趣可以自己翻:github.com/Silverstrea…

npm 首发日期:2026-03-01。改不了的那种。