mcpField
P
project-naming

project-naming

github.com/vivswan营销与增长118 次安装2 天前更新
代码仓库

关于 project-naming

project-naming 是一项技能,根据项目所有者的偏好和计划注册的平台来提出并评估名称。流程结合并行命名思路、可用性与含义检查,并以附有依据的排名表供所有者审阅。

主要功能

  1. 01访谈所有者并整理命名简报
  2. 02按不同风格生成候选名称
  3. 03检查注册平台可用性及控制项
  4. 04审查含义和发音风险
  5. 05提供附依据的候选排名表

适用场景

  1. 01发布项目前为其命名
  2. 02重新评估被否决的产品或包名
  3. 03依据目标注册平台比较候选名称

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/vivswan/skills --skill project-naming

安装后在 Claude Code 中输入/project-naming确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE.md
README.md
.codex-plugin/
plugin.json
agents/
openai.yaml
scripts/
check-name.mts
scripts/columns/
say.mts
typosquat.mts
scripts/columns/registries/
readers.mts
table.mts
wiktionary.mts
scripts/core/
cache.mts
cells.mts

详细介绍

项目命名

名称从表格中选出,而不是从列表中挑选。每个候选名称都会连同其注册信息行、含义检查结果,以及它与所有者已有心仪名称的匹配分数,一起提交给所有者。先询问所有者的喜好,绝不猜测。

1 interview -> 2 brief -> 3 lanes (parallel) -> 4 machine check -> 5 meaning check
                   ^                                                      |
                   |                                                      v
              7 rejection round  <--  6 one table to the owner  <--  verdicts
                                              |
                                              v  (owner picks)
                                8 re-verify same day -> 9 record and "not checked"

何时使用

  • “给这个项目起个名字” / “有没有更好的名字?” / “这个包该叫什么?”
  • 名称被拒绝:难以发音、已被占用,或会误导读者
  • 论文、工具或数据集需要在发布前取名

工作流

1. 访谈

在生成任何内容之前先提问。所有者的回答就是命名简报;没有这些信息,各个方向最终都会趋同于生成器自己的喜好。

Which two or three existing names do you like the SOUND of? (any product, any field)
What killed the last name, in your words?
What must this project be able to grow into?
Where will the name be claimed? (PyPI, npm, crates, Homebrew, Docker Hub, Maven, Hugging Face, GitHub, Bluesky, which domains, arXiv)
Which languages do your users read?
2. 简报

将回答整理成一页内容,供所有方向参考。生成任何名称之前,必须先由所有者批准。

exemplars:   <the names the owner likes>, scored 1 to 5 by closeness
vector:      <per exemplar: letters, syllables, stress, open or closed vowels, Latinate or Germanic, hard letters>
grows into:  <scope in one line>
claims:      pypi npm docker hf github dns:com,ai
languages:   <the languages the users read, from the interview>
hard gate:   the table under Conditions, plus anything the owner added
soft scores: exemplar closeness, elegance, room to grow

硬性门槛是通用的。所有者的喜好体现在示例中,因此,同一套技能会根据不同所有者的偏好进行不同的搜索。

向量会对每个示例只进行一次分解,因此每个方向都根据相同的六项事实评估接近程度,而不是凭各自的印象打分。以下是一个示例,针对一位喜欢 vercel 和 linear 的所有者:

vercel:  6 letters, 2 syllables, stress on the first, closed vowels, Latinate, no hard letters
linear:  6 letters, 3 syllables, stress on the first, open vowels, Latinate, no hard letters
3. 命名方向

每种风格设一个方向,并行运行(若已安装,/orchestrator-mode 技能负责分发任务)。每个方向构思 50 到 100 个名称,目测剔除未通过门槛的名称,再用第 4 步中的脚本检查最好的 20 个。

方向生成内容
真实单词一个现有单词,可以常见,也可以生僻
创造词一个具有示例名称语感的造词
拉丁语或罗曼语族语言源自拉丁语、意大利语、西班牙语、葡萄牙语词根的形式
隐喻一个能让人联想到这项工作的物品或地点
两个短词由两个真实单词组成的复合词
借词一个来自指定语言、含义直白的词

如果简报排除了某个方向,就将其移除。如果所有者的示例有共同风格,而表格中尚无对应方向,就添加该方向。

如果执行框架包含流水线或工作流工具,第 3 至第 6 步应作为一次运行执行,而不是在各个 Agent 之间传递散文。每个方向都按固定格式返回各行(名称、读法、三项分数、注册信息、含义判定、最终判定),并附上已剔除的名称。如果某个方向没有留下任何候选项,就用收紧后的提示词重跑一次。

合并时会根据简报中的拒绝列表去重,并统一检查一次 arXiv 和 github-repo 列。

驳回意见轮(第 7 步)安排在各次运行之间:重写简报,只重跑受改动影响的方向。以消息形式传递的方向报告会被截断;符合固定结构的行则不会。

4. 机器检查
bun "<skill-dir>/scripts/check-name.mts" <name> <name> ...
bun "<skill-dir>/scripts/check-name.mts" --registries pypi,npm,docker,hf,github-user,dns-com,dns-ai <name>   # the brief's claims except github-repo
usage: check-name.mts [--domain <tld>]... [--registries <id,id,...>] [--no-arxiv] [--json] <name>...
       check-name.mts --list-registries
  --domain <tld>          a DNS column per zone (default: com, ai, dev; the list replaces the default)
  --registries <id,...>   the availability columns to run; the gate columns run on every name regardless
  --no-arxiv              skip the arXiv column (one request every three seconds)
  --json                  one JSON object, rows and failures, instead of the table
  --list-registries       the live column table: id, label, taken control, gate
exits: 0 every row printed and every control answered as expected;
       1 a control answered wrongly: the named columns are not evidence; 2 usage error

每个名称占一行,每个注册来源占一列;注册来源集中列于 scripts/columns/registries/table.mts 中,运行 --list-registries 可打印该表。除 say 列使用 note(<reading>) 外,每个单元格的内容均为 free、taken(<why>) 或 unknown(<why>):

name    pypi  npm                 crates  homebrew                        docker                  maven  hf    github-user           github-repo  bluesky                arxiv  dns-com                     dns-ai  wiktionary                    urban                typosquat                                                         say
lumera  free  taken(npm package)  free    free                            taken(docker hub user)  free   free  taken(github handle)  free         taken(bluesky handle)  free   taken(lumera.com resolves)  free    taken(word in Italian,Latin)  free                 free                                                              note(ok(3s))
tarnix  free  free                free    taken(homebrew formula tarnix)  free                    free   free  free                  free         free                   free   free                        free    free                          taken(1 entry: ...)  free                                                              note(flag(2s; hard x))
numpi   free  free                free    free                            free                    free   free  free                  free         free                   free   free                        free    free                          free                 taken(1 edit from numpy on claimed pypi (top 5000 by downloads))  note(ok(2s))
  • --registries 用于选择可用性列;门控列 say、typosquat、wiktionary 和 urban 会对每个名称运行,无论该名称是什么,因此选择性运行无法跳过它们:硬门控会读取前两列,第 5 步会读取两列含义列,且都会检查每个名称。
  • 每批都会运行两项控制检查:对于每个注册表列,一个在该处已被占用的名称(DNS 使用该区域自身的委派,写作 @;Wiktionary 使用带有已标记义项的词),以及一个必须在所有地方都空闲的随机字符串。若某列对任一项的判断有误,脚本会在 stderr 上将其报告为失效的检测项,并以退出码 1 结束。不要读取该列。
  • unknown 不等于 free。受到速率限制的 arXiv 或返回 5xx 的结果在表格中仍为 unknown;稍后重跑,或用 --no-arxiv 去掉该列。
  • arXiv 每 3 秒允许一个请求,脚本会按此间隔发送请求。各执行通道会使用 --no-arxiv;负责汇总的执行通道会在第 6 步对合并后的候选名单运行一次 arXiv 列。
  • Maven Central 的搜索有些请求会被挂起半分钟甚至更久,因此脚本会逐个查询,并在短暂等待后重试;unknown(maven TimeoutError ...) 单元格表示连续 3 次被挂起,稍后重跑。
  • Docker Hub ID 只能由 4 到 30 个小写字母和数字组成;不符合条件的名称在那里会显示为 unknown,因为 Docker 会拒绝它,而不是因为它空闲。
  • GitHub 会将拥有至少 20 颗星的同名仓库视为已占用。请设置 GH_TOKEN,或登录 gh,以满足每个 token 的搜索速率限制。
  • GitHub 每个 token 每分钟允许 30 次搜索,无 token 时允许 10 次,所有执行通道共用此限制。因此,脚本有 token 时会每隔 2 秒搜索一次,没有 token 时每隔 6 秒搜索一次:在 github-repo 列上检查 20 个名称大约需要 1 分钟;无 token 时需要 3 分钟。遇到速率限制时,结果为 unknown(github search rate-limited; retry later)。
  • 各执行通道不会将 github-repo 纳入 --registries;与 arXiv 一样,负责汇总的执行通道会在第 6 步对合并后的候选名单运行一次该列。
  • Homebrew 的逐名称页面只会返回与条目同名的结果(python 是 [email protected] 的别名,没有对应页面),因此脚本会完整读取 formula 和 cask 索引,并与 typosquat 列表一同缓存一天。单元格会列出 formula 或 cask 的名称;如果该名称是别名,还会标注 via alias、via old name 或 via old token。
  • typosquat 列会检查名称是否与热门软件包相差一次编辑(添加、删除或替换一个字母,或交换两个字母)。单元格会列出软件包、注册表的 claimed 或 unclaimed 状态(--registries 中列出的注册表均为已声明;不传该参数时所有注册表均视为已声明),以及匹配到的列表。列表会在 OS 临时目录下的 check-name-cache 中缓存一天。
  • 无法读取的列表会在同一单元格中与任何命中项一起列出(taken(1 edit from lumeras on unclaimed pypi (...); claimed crates lookup failed (crates ranking page 1 HTTP 503)));如果没有命中项,则该单元格只列出无法读取的列表。若某个命中列表对应的数据源读取失败,该列表就不完整:应先重跑,再将其作为唯一的冲突项来判断。
  • 这些列表包括:PyPI 按下载量排名前 5000 的软件包(公开的 top-pypi-packages JSON);npm 按 npm-high-impact 数据集中的下载量排名前 5000 的软件包(npm 不发布排名,且其搜索不是模糊搜索);以及 crates.io 按下载量排名前 2000 的软件包,通过其 crate 列表读取,每页 100 个(它不发布排名文件,且其搜索只会返回名称匹配的结果,不会返回相差一次编辑的热门 crate)。
  • 如果列表比其数据源发布的内容短,它就是被截断的列表,而不是较短的排名:crates 页面少于 100 个条目,或 PyPI、npm 列表少于该列读取的 5000 个条目,都会导致相应数据源失败,方式相同(claimed crates lookup failed (crates ranking page 7 reply malformed: page has 40 entries, expected 100)),因为截断之后的名称从未参与比较。
  • crates.io 要求自动化客户端每秒最多发送一个请求。在同一进程内,脚本会将 crate 查询以及排名列表的 20 个页面读取间隔控制为每秒一次:单个进程处理 20 个名称时,crates 列大约需要 20 秒。
  • 所有进程共用每天一次的排名列表获取任务:第一个开始读取某个页面的进程会在缓存条目旁创建锁文件并持锁获取页面;其他进程会等待,然后读取它写入的内容。因此,冷缓存下的 6 个执行通道只会获取一次排名列表,大约需要 20 秒。
  • say 列只读取拼写,因此结果始终是 note,不会是 free 或 taken,也不运行控制检查:ok(<syllables>s) 或 flag(<syllables>s; <reasons>)。“said as spelled”这一行会在 Conditions 下列出每个原因。
  • --json 会将行和控制检查结果作为一个对象输出,供执行通道报告使用。
5. 含义检查

脚本的 Wiktionary 列会从页面的 wikitext 中读取所有语言的每个义项,并检查其中是否有语体标签(粗俗、冒犯性、侮辱性称呼、贬义);Urban Dictionary 列则只读取完全匹配的词条。这涵盖了拼写完全一致的情况。近似同音词和转写需要判断,仅对通过第 4 步的名称进行:

for each survivor:
  say it aloud in every language the brief lists, then in Spanish, Portuguese, French,
    Italian, German, Hindi, Turkish, Arabic, Japanese, Mandarin, Russian, Korean:
    which word is it one sound away from?
  is it a drug, a perfume, a car, a company, an ML method? (one web search: "<name>" AI OR company OR app)
verdict per name: SERIOUS (the word named), MILD (the word named), NONE, each with its source

命名机构会由母语人士完成这一步。报告会注明这是由模型完成的,并在第 9 步将其列入“未检查”项。

6. 提交给负责人的一张表

所有流程汇总为一张排名表。每个名称都必须有对应的行,才能提交给负责人。

名称读法典型示例 1-5优雅度 1-5延展性 1-5注册情况含义结论
<name><stress and vowels><score><score><score><free, or the taken cells named><NONE, MILD: word, SERIOUS: word>CLEAR / MINOR: <the one collision> / TAKEN
  • CLEAR:所有标注的注册项均未被占用,含义为 NONE。
  • MINOR:有一处负责人知情后可以接受的冲突,并在单元格中注明。
  • TAKEN:未通过硬性门槛;仅在负责人要求查看被排除项时展示。

表格发出前,还会对每个入围名称进行另外两项检查,结果会填入 say it 和 meaning 单元格:

  • 对陌生人读出名称。 逐个字母向一个毫无背景信息的新 Agent 拼出名称,请它读出名称并拼回原拼写。如果读音与该行 say it 单元格中的内容不同,或拼写与名称不同,则标为 MILD,并引用陌生人的读法。
  • 查看名称的视觉效果。 将名称写成四种形式:全小写、首字母大写、终端命令(<name> --help)以及简短的图标标签。若某种形式容易被误读(例如将小写字母 l 看成 I,或在首字母大写时错误地拆分单词),则在该行中注明。
7. 淘汰轮

“这些都不行”也是信息,并非失败。询问对方为什么不喜欢这些名称,以及哪一行最接近要求。根据新的典型示例改写需求简述,然后重新运行产生了相近候选项的流程。通常会进行两到三轮。

8. 重新验证

仅验证选定的名称,使用同一脚本,在同一天由负责人执行,而非由提出该名称的流程执行。注册情况每周都会变化;决策记录中的行应标明日期。

9. 记录
chosen:       <name>, claimed at <registries> on <date>
why it won:   <the exemplar it matched, the gate it passed>
not checked:  trademark offices, app stores, social handles, native-speaker review, <anything the brief skipped>

条件

名称只要在任意一行未通过硬性门槛,就会被淘汰:

门槛未通过条件
按拼写读出say 列标记了以下任一项:hard x,q,z,k;doubled ll;cluster str(三个辅音连在一起);two readings,适用于 ch、gh、ough、ea、词尾 e,或 e、i、y 前的 c 和 g;spoken digits 1,2,3(读出数字,并计作一个音节)
简短超过 3 个音节、约 8 个字母,或包含多个词
可注册在需求说明声称可注册的任何注册平台上已被占用,或存在同名且拥有 20 个或更多星标的仓库
无相近名称已有 AI 公司、产品或 ML 方法使用该名称(通过网页搜索确认)
无不良含义在任何语言中发现严重含义问题
无错误信号名称有含义,但含义与项目不符
非拼写抢注typosquat 列列出了需求说明声称可注册的平台上的软件包;若在未声称可注册的平台上发现匹配项,则记为次要备注

含义要么一目了然,要么不存在。毫无含义的名称可以通过;含义错误的名称不通过;读者必须解码才能理解的名称(双关、典故、层层转折)默认淘汰。

软性评分,每项 1 到 5 分,在表格中展示,绝不用于挽救未通过硬性门槛的名称:

  • 范例贴合度,主要评分:名称与所有者在第 1 步提供的名称有多相似。
  • 优雅度:辅音柔和、元音开阔,以小写和标题大小写呈现时都清晰易读。
  • 拓展空间:不局限于项目可能不再需要的某项功能。

除非需求说明另有规定,否则默认淘汰:缩写、字母 x q k z、双写字母、辅音连缀、后缀 -lens -scope -lux -ly -ify、版本号、过度使用的典故(jarvis、alfred、hal)。

脚本不检查的内容

商标注册库、应用商店、Bluesky 以外的社交账号,以及已注册但尚未解决的域名。每次决策记录都会在“未检查”项下列出这些内容,以便所有者了解后续可能遇到哪些权利主张。

Go 模块:模块路径是一个 URL(github.com/<owner>/<name>),因此无法注册一个裸名称;而 pkg.go.dev 仅以 HTML 提供搜索结果。GitHub 列涵盖了该路径所指向的仓库。

相关内容

  • /verify-with-controls:第 4 步中的对照行对应其规则 2(信任零结果前先验证阳性对照)和规则 6(观察检查器失效)。
  • /orchestrator-mode:第 3 步中的各条路径,可作为并行子 Agent 运行(若已安装)。

评论

支持 Markdown