关于 create-requires-module
用于编写依赖现有 `.plain` 模块的技能,指导作者设置构建顺序、查看前置规格与导出概念,并检查模块配置。
主要功能
- 01将模块接入构建链
- 02复用祖先模块生成的代码
- 03查看前置功能规格
- 04通过导出控制概念可见性
- 05检查祖先路径与规格冲突
适用场景
- 01创建基于现有模块的模块
- 02将模块挂接到指定构建链位置
- 03检查依赖路径是否形成禁止的菱形连接
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ plainlang/ plain-forge --skill create-requires-module安装后在 Claude Code 中输入/create-requires-module确认已加载。
详细介绍
创建 Requires 模块
先加载规则。 在读取、编辑或编写任何 .plain 文件之前,先调用 load-plain-reference 技能,并阅读它指引你查看的规则文件。只有当本次对话中已经运行过 load-plain-reference 时,才可跳过此步骤。
Requires 的作用
requires 会将当前模块接入项目的构建链。所需模块会在当前模块之前构建,其生成的代码——即该模块及其所有祖先模块累积的输出——会被复制为起始代码。当前模块不必在功能上扩展所需模块,但两者的输出绝不是相互独立的:当前模块的代码中实际包含所需模块的代码。
渲染此模块时:
- 所需模块生成的代码(
plain_modules/<required_module>/code)会被复制为起始代码。 - 所需模块及其所有祖先模块的
***功能规范***都会显示为先前功能规范。 - 所需模块的定义中,只有
exported_concepts里的概念可见,且会显示其完整定义文本。导出可见性不会传递——若要查看某个祖先的导出内容,也要将该祖先列入requires。 - 所需模块的测试 plain 文件仍归该模块所有。新模块会有自己的测试 plain 文件,每项新增功能对应一个(参见
test-plain-files.md)。
所有通过 requires 连接的模块会构成一棵拥有共同根节点的树。禁止出现菱形合并:多个 requires 条目必须位于同一条从根到叶的祖先路径上。最深层的条目是挂接点;其他条目仅用于让这些祖先的导出内容可见。
以下情况使用 requires:
- 在现有模块功能的基础上构建
- 将模块接入构建链中的适当位置,即使它关注的是不同方面
如果你只需要共享定义和 reqs(没有功能规范,也没有生成代码),请改用 import——参见 create-import-module 技能。
工作流
- 确定挂接点。 确定这个新模块在构建链中挂接在哪个现有模块之后。该模块必须已存在且可渲染。如果列出其他模块,请确认它们都是挂接点的祖先——不得出现菱形合并。
- 在仓库根目录创建
.plain文件,并在 YAML frontmatter 中包含requires字段。包含功能规范的模块应放在根目录,而不是template/中。 - 检查整个祖先链上的功能规范——它们会被视为先前需求。你的新功能规范不得与其中任何一项冲突。
- 检查所列每个模块的
exported_concepts——只有这些概念可供引用;要使用某个祖先的导出内容,必须将该祖先列出。 - 添加模块专属内容——仅适用于此模块的定义、实现 reqs、测试 reqs 和功能规范。通过
add-functional-spec或add-functional-specs添加每项功能规范,这也会创建对应的测试 plain 文件。 - 检查冲突,确保新功能规范与祖先链中的任何规范都不冲突。
格式
requires 字段是 YAML frontmatter 中的模块路径列表:
---
requires:
- base_module
import:
- shared_template
description: Extended module that builds on base_module
---
***definitions***
- :NewFeature: is a feature added by this module.
***functional specs***
# new-feature
:NewFeature: is available.
模块可以同时使用 requires 和 import。requires 指向其他根目录级模块;import 则从默认的 template/ 目录解析(无需前缀)。
只有当多个 requires 条目位于同一条祖先路径上时,它们才是合法的(例如,requires: [auth, messaging],其中 messaging 本身需要 auth)。最深层的条目(messaging)是挂接点;列出 auth 仅用于使其导出内容可见。
导出的概念
必需模块通过 exported_concepts 控制哪些概念可见:
> In the required module's frontmatter:
---
exported_concepts: [":StorageClient:", ":BackupResult:"]
---
只有 :StorageClient: 和 :BackupResult: 可供 require 此模块的模块使用,且包含各自的完整定义文本。必需模块中的所有其他概念均为内部概念。
使用 Requires 按时间顺序排列
整个 requires 祖先链中的功能规范均视为先前的功能规范。这意味着:
- 它们已渲染完成,且其代码已存在。
- 你的新规范会在它们之后渲染,并充分了解它们定义的内容。
- 你的新规范不得与祖先链中的任何规范冲突。
- 渲染器会将该链中的功能规范作为上下文来渲染你的规范。
当前模块在功能上可能与必需模块相关,也可能无关——无论哪种情况,requires 都会将其放到累积构建链中的正确位置。
Import 与 Requires
| 方面 | import | requires |
|---|---|---|
| 引入定义 | 是 | 否(仅 exported_concepts) |
| 引入实现要求 | 是 | 否 |
| 引入测试要求 | 是 | 否 |
| 引入功能规范 | 否 | 是(作为先前要求,传递引入) |
| 复制生成的代码 | 否 | 是(累积的祖先链) |
| 典型用途 | 模板、共享定义 | 将模块附加到构建链 |
验证清单
- 模块文件位于仓库根目录(不在
template/中) - 必需模块存在且可渲染
- 所有
requires条目都位于同一条祖先路径上——不存在菱形合并 - 最深层的
requires条目是预期的附加点 - 每个列出的模块的
exported_concepts都提供了所需概念 - 新功能规范与祖先链中的任何规范均不冲突
- 模块至少包含一项功能规范和一项实现要求
- 每项功能规范都有对应的测试纯文本文件
-
requires和import均使用正确(没有混淆) - YAML frontmatter 在
---标记之间正确格式化