入门 Zed Industries 2026-09-14 17:42:20 · 0 阅读

第129章 发布扩展与许可证要求

发布扩展的步骤如下:

  1. 查看发布前置条件,确保扩展已就绪。
  2. 为扩展添加可接受的许可证
  3. 按照发布指南,将其提交至 Zed 扩展仓库。

扩展发布后,请参考更新扩展了解如何发布更新,并查阅常见问题解答获取关于维护和过时扩展的一般信息。

扩展许可证要求

自 2025 年 10 月 1 日起,扩展仓库必须包含许可证。 接受的许可证如下:

这使我们能够将基于你的扩展代码生成的二进制文件分发给用户。 如果没有有效的许可证,用于添加或更新扩展的 Pull Request 将无法通过 CI 检查。

许可证文件应位于扩展的根目录,但不一定需要在仓库根目录。如果扩展位于仓库的某个子目录中,许可证必须放置在该子目录内,仓库根目录的许可证无效。你可以将现有许可证符号链接到扩展目录,或为扩展代码选择其他可接受的许可证。

任何文件名以 LICENCELICENSE 作为前缀(不区分大小写)的文件,都会被检查以确保其符合获认可的许可证之一。请参见 许可证验证源代码

请注意:

  • 此许可证要求仅适用于扩展代码本身(即编译到扩展二进制文件中的代码)。
  • 它不适用于扩展可能下载或交互的任何工具,例如语言服务器或其他外部依赖项。
  • 如果你的仓库同时包含扩展代码和其他项目(如语言服务器),你无需重新许可这些其他项目;只有扩展代码必须采用上述获认可的许可证之一。

发布扩展的前置条件

在提交扩展以供发布之前,请确保其满足以下要求。

请注意,维护者将在发布过程中指出不合规之处。如果你选择忽略这些要求,发布将被延迟,甚至可能被直接拒绝。

通用要求

  • 手动在 Zed 中测试你在提交时所在的子模块 commit 下的扩展。
  • 发布扩展注册表中尚不具备的功能。
  • 如果遇到现有扩展的问题,请优先尝试为现有扩展做出贡献。有关此要求的更多详情,请参见 常见问题解答
  • 不要滥用扩展 API 来规避其当前的局限性。
  • 在极少数情况下,我们可能会接受合理的变通方案。
  • 是否接受变通方案由维护者自行决定。
  • 为你的扩展使用合适的 ID。ID 必须:
  • 具有唯一性
  • 使用 kebab-case 格式
  • 不包含 zedextension 字样
  • 能很好地表明你的扩展提供了什么功能(详见下文)
  • 仅包含扩展运行所需的资源。
  • 允许的许可证 之一为扩展授予许可。
  • 将所有面向用户的文本用英文编写。
  • 不要读取或修改 Zed 为扩展指定的环境之外的任何内容。
  • 使用 Zed Rust Extension API 来读取和修改环境。
  • 使用 Rust 标准库方法来读取和修改为扩展提供的工作目录。
  • 如有其他需要更改的地方,请让用户自行操作。
  • 语言扩展

    • 只为你扩展所针对的语言及其直接相关的方言提供支持。
    • 在扩展的 extension.toml 中为你提供的每种语言定义一个 grammar
    • 你也可以为该语言提供 language server、debugger 和代码片段。
    • 扩展 ID 和名称应与你要添加的主要语言的名称相同或相近。
    • 如果扩展不提供 language server,就不要包含任何 Rust 代码。

    Language Server 扩展

    • 如果你的扩展只提供 language server,请确保扩展 ID 能体现这一点(例如加上 -language-server-lsp 后缀)。
    • 不要把 language server 打包进扩展。应通过 Zed Rust Extension API 下载它,或在用户环境中检查是否已存在。

    Debugger 扩展

    • 如果你的扩展只提供 debugger,请确保扩展 ID 能体现这一点(例如加上 -debugger 后缀)。
    • 不要把 debug adapter 打包进扩展。应通过 Zed Rust Extension API 下载它,或在用户环境中检查是否已存在。

    主题扩展

    • 只提供主题,不要包含其他内容。
    • 确保扩展 ID 能表明它是一个主题(例如加上 -theme 后缀)。

    图标主题扩展

    • 只提供图标主题,不要包含其他内容。
    • 确保扩展 ID 能表明它是一个图标主题(例如加上 -icon-theme-icons 后缀)。

    代码片段扩展

    • 如果扩展仅包含代码片段,扩展 ID 应体现这一点(例如加上 -snippets 后缀)。
    • 仅在必要时将代码片段设为全局作用域,语言相关的代码片段应限定在对应语言中。

    MCP Server Extensions

    MCP 服务器扩展未来将被废弃,取而代之的是 MCP 注册表;相关进展详见 #59351。为确保兼容 Zed 后续版本,请务必将服务器发布到注册表。

    • 扩展内仅提供一个 MCP 服务器,不要包含其他内容。
    • 扩展 ID 需表明其为 MCP 服务器(例如加上 mcp-server- 前缀或 -mcp-server 后缀)。
    • 不要在扩展中捆绑 MCP 服务器,应通过 Zed Rust Extension API 下载或检测用户环境中是否已存在。

    Agent 服务器和 Slash 命令扩展

    Agent 服务器和 slash 命令扩展已废弃,不再接受提交。若希望在 Zed 中提供 Agent 服务器,请将其发布至 ACP 注册表


    若扩展符合以上所有要求,可以着手发布了!

    Publishing Guide

    开始发布流程前,请确认扩展已满足所有发布前提许可证要求。未满足上述要求,请勿继续执行以下步骤,否则发布可能被延迟或直接拒绝。

    请仔细执行每一步,以确保发布流程顺利进行。

    Pull request rules {#pull-request-rules}

    为控制代码评审队列规模,针对 zed-industries/extensions 仓库的所有 PR 均需遵守以下规则:

    • 每个 PR 必须新增或更新且仅涉及一个扩展
    • 任意时刻,你最多可以有三个未合并的 PR
    • 需在3 周内响应维护者的反馈,否则你的 PR 将被关闭。

    不符合上述规则的 PR 将直接关闭,不再提供额外反馈。若反复违反这些规则,可能导致被临时禁止或永久禁止向扩展仓库提交内容。

    Fork 和克隆仓库

    1. Fork zed-industries/extensions 仓库。

    提示:建议将 zed-industries/extensions 仓库 fork 到个人 GitHub 账号而非 GitHub 组织,这样 Zed 团队可以向你 fork 的仓库推送必要变更,从而加快发布流程。

    1. 将仓库克隆到本地机器。
    # 将此处替换为你自己 fork 仓库的 URL:
    git clone https://github.com/your-username/extensions
    cd extensions
    git submodule init
    git submodule update
    

    提交你的扩展 {#submitting-your-extension}

    要发布扩展,需向 zed-industries/extensions 仓库 提交 PR。

    在你的 PR 中,执行以下操作:

    1. 将你的扩展作为 Git 子模块添加至 extensions/ 目录下,路径为 extensions/{extension-id}。 - 子模块必须使用 HTTPS URL,而非 SSH URL(git@github.com)。 - 你的扩展仓库必须是公开的。 - 子模块检出的提交必须位于某个分支上,不能是 detached commit。
    git submodule add https://github.com/your-username/foobar-zed.git extensions/my-extension
    git add extensions/my-extension
    
    1. 在顶层 extensions.toml 文件中新增一条包含你扩展信息的条目: - 确保 version 与特定提交下 extension.toml 中设置的版本一致。
    [my-extension]
    submodule = "extensions/my-extension"
    version = "0.0.1"
    

    如果你的扩展位于子模块的子目录中,可以用 path 字段指定扩展所在的位置:

    [my-extension]
    submodule = "extensions/my-extension"
    path = "packages/zed"
    version = "0.0.1"
    
    1. 运行 pnpm sort-extensions,确保 extensions.toml.gitmodules 的条目已排序。

    这样就完成了!PR 被合并后,扩展会自动打包并发布到 Zed 扩展注册表。

    审核流程 {#review-process}

    PR 提交后,维护者会进行审核,并可能要求修改。请牢记PR 规则对维护者反馈超过 3 周无响应,提交将被关闭。

    关于审核需要多久、为什么设置时间限制、PR 被关闭后该怎么办等问题,请参阅FAQ

    更新扩展

    要更新扩展,请向zed-industries/extensions 仓库提交 PR。

    更新类的 PR 同样需要遵守PR 规则

    在 PR 中需要做以下几件事:

    1. 将扩展的子模块更新到新版本对应的 commit。可以运行:
    # 从仓库根目录执行:
    git submodule update --remote extensions/your-extension-name
    

    这样即可将扩展更新到远程仓库中最新的 commit。

    1. 更新 extensions.toml 中该扩展的 version 字段。 - 确保此处的 version 与对应 commit 中 extension.toml 里设置的版本一致。

    如果想自动化这一流程,可以使用一个社区 GitHub Action

    如需了解扩展的维护或终止维护相关问题,请参阅常见问题

    常见问题

    在发布扩展之前、期间和之后,常会遇到各种问题。以下是我们收到最多的几类。

    提交审核需要多长时间? {#review-duration}

    我们会尽力在合理时间内回复。但我们也清楚,目前并非总能做到——对此我们深表歉意!我们正不断迭代流程,以期更快地为每个提交提供反馈,并带来更好的贡献体验。

    通常情况下,大多数提交会在几周内收到初步反馈;部分扩展可能需要更久,甚至一两个月。我们知道这既非最优体验,也不令人愉悦,我们正在努力改进(实际上,本文档正是我们提供背景信息、改善这一流程的一部分)。

    但请注意,我们目前无法给出具体承诺。由于当前积压量较大等多种原因,审核时间可能进一步延长,对此我们深表遗憾。

    为什么我的 PR 被关闭了? {#pr-closed}

    如果你的 PR 在缺乏太多反馈的情况下被直接关闭,说明它严重违反了发布前置条件。由于提交量巨大,这类情况下我们通常不再提供额外说明。请务必重新仔细阅读前置条件。

    此外,正如拉取请求规则所述,如果在维护者反馈后 **3 周内无任何响应**,我们会认为该提交已停滞并将其关闭。

    因停滞而被关闭的 PR 并不意味着终结:你随时可以重新开启一个新 PR,我们会再次审查。

    为什么对我的响应有期限,而你们却不受限制? {#response-timeframe}

    我们明白这看起来似乎不太公平,尤其是考虑到我们自身的响应速度——对此我们也感到遗憾。但为了大家的利益,我们需要关闭那些长期停滞的提交,以保持审查队列处于可控状态,从而让我们能更快地处理每一个提交,包括您接下来的提交。

    为什么要求我新建 PR,而不是继续我那个已关闭的? {#fresh-prs}

    由于积压任务较多,在某些情况下我们更倾向于处理新的 PR,因为它们能保持队列更短。经验表明,新的 PR 往往处于更容易审查的状态;而更新后的 PR 虽然声称已处理所有反馈,实际上却常常处于损坏且无法合并的状态。这既浪费了审查者,也浪费了贡献者的宝贵时间。

    从这个意义上说,新的 PR 处理起来更快,通常合并过程也更简单、更迅速。

    为什么要强制规定这么多严格的前置条件? {#why-prerequisites}

    我们设定扩展前置条件的目标,是在开放扩展生态与一定的标准和质量水平之间寻求平衡:当用户安装一个扩展时,应当能放心它能在一定程度上良好工作,而不必自己先去检验。

    这些前置条件也有助于集中力量。如果多人维护多个几乎相同的扩展,用户分散在各处,这会让所有相关方都陷入巨大的混乱。将力量引导到统一的地方,对拥有者、贡献者和用户都有益——每个用例只保留一个扩展,你也不用费心去猜哪个才是对的。

    当然,我们深知这些条件无法涵盖所有情况,但它们设定了大家都能依赖的基线。如果某个扩展最终确实无法工作或无人维护,这正是本页面下方那些政策所应对的场景。

    已发布的扩展是否也需遵守这些前置条件? {#prerequisites-for-existing-extensions}

    是的。已发布的扩展并不豁免这些前置条件,其更新将与新提交遵循相同的标准。

    唯一的例外是 ID 限制:由于扩展一旦发布,其 ID 便不可更改,因此现有的 ID 将保持原样。

    我必须维护我的扩展吗? {#do-i-have-to-maintain-my-extension}

    不需要。扩展发布后,我们这边没有任何后续要求。感谢你为 Zed 扩展生态做出的贡献,我们非常感激!

    话虽如此,没有哪个扩展第一天就完美无缺——bug 可能会出现,改进需求也可能随之而来。维护虽非义务,但如果你能在合理时间内回应这些问题报告,对所有人都有帮助。

    我发现某个扩展有 bug,或者想改进它,该怎么做? {#reporting-issues-and-improvements}

    请先在扩展的原仓库中提交问题或提出改进建议,而不是发布一个竞争性的扩展。大多数作者都欢迎反馈和贡献,把力量集中在一处,既免去了用户在几乎相同的扩展之间做选择的困扰,也让维护者不用重复审核。

    如果作者长期没有回应,请参阅 扩展作者停止回应会发生什么?

    我不想再维护我的扩展了,怎么办? {#stepping-back}

    完全没问题——优先级会变化,放弃维护某个扩展不必感到愧疚。作为当前作者,你可以:

    • 把仓库所有权转让给新的维护者,或者
    • zed-industries/extensions 提交 issue 或 pull request,请求下架你的扩展。

    你也可以选择继续保留这个扩展——很多扩展很少甚至从未更新过,却依然拥有大量满意的用户。

    扩展作者对问题报告不再回应会发生什么? {#unresponsive-owner}

    我们不希望已发布的扩展被弃之不管,那会给用户带来糟糕的体验。所以当一个扩展的作者联系不上时:

    • 贡献者可以 fork 该扩展,并提议用自己的 fork 替代现有扩展;或者
    • Zed 官方可以将扩展 fork 到 zed-extensions 组织下,由社区和 Zed 官方共同继续维护。

    只有满足以下条件之一时,我们才会采取上述行动:

    • 当前作者已给出书面许可;或
    • 书面证据表明曾尝试与所有者建立联系,且所有者在至少 6 周内未予回应。

    若缺少上述任一条件,该扩展仍将保留给当前所有者。

    这种归属权的变更也不一定是永久性的:如果原所有者恢复响应,该扩展可以切换回原仓库。

    为什么我的语言不能复用内置语法或其他扩展中的语法? {#grammar-reuse}

    如果某语言依赖于非其自身拥有的语法,该语法的更新可能会改变 Tree-sitter 解析生成的节点结构,从而导致该语言静默失效。为避免此类问题,每种语言必须使用在其自身扩展的 extension.toml 中定义的语法。

    我对这些政策有疑问或持反对意见,应该去哪里反馈? {#policy-discussion}

    首先,感谢通读这些内容!

    虽然这些政策的制定都有充分理由,但并非所有条款都不可更改——我们非常重视围绕这些议题的开放讨论。

    如果其中有任何内容让您觉得不妥,或者您有任何疑问,欢迎在 zed-industries/zed 仓库中发起讨论并 @MrSubidubi ——我们更希望通过沟通解决问题,而不是让您感到困扰。

    评论 (0)