关于 openspec-propose
用于规划 OpenSpec 变更的技能,可创建变更并生成所需文档。它将规划与实现分开,实现须通过 apply 工作流另行启动。
主要功能
- 01创建变更及规划文档
- 02遵循已配置的工作流模式
- 03检查依赖项和文档状态
- 04实现须显式启动 apply 工作流
适用场景
- 01编写功能提案与设计
- 02编码前规划实现任务
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ full-stack-skills/ ddd-skills --skill openspec-propose安装后在 Claude Code 中输入/openspec-propose确认已加载。
详细介绍
提出一项新变更——一步创建变更并生成所有产物。
规划边界:此工作流仅创建规划产物。选择或触发此工作流的用户请求仅授权进行规划,即使请求要求构建或修复某项内容也是如此。不要编辑项目代码。规划产物完成后即停止。即使初始请求要求实施,也不要在同一条回复中开始实施。展示产物后,等待用户提出新请求;之后再启动应用工作流。
我将根据你的架构定义创建变更及其产物。对于默认的规范驱动架构,产物包括:
- proposal.md(内容与原因)
specs/<capability-path>/spec.md(系统必须执行的操作——增量,而非主规范)- design.md(实现方式)
- tasks.md(实施步骤)
<capability-path> 是相对于 specs/ 的规范目录(例如 user-auth 或 identity/user-auth)。保留现有能力的完整路径,并遵循项目为新能力采用的组织方式。
准备好实施时,用户必须明确启动应用工作流。
**存储库选择:**如果用户指定了存储库(存储库是此机器上注册的独立 OpenSpec 仓库),或者相关工作位于某个存储库中,请运行 openspec store list --json 以查找已注册的存储库 ID,然后在读取或写入规范和变更的命令中传入 --store <id>(new change、status、instructions、list、show、validate、archive、doctor、context、view)。选定后,在工作流的其余部分中始终使用 --store <id>。下方未指定存储库的命令示例均为简写:运行前请追加此标志。例如,运行 openspec status --change "<name>" --json --store "<id>",而不是下方所示的未指定存储库形式。其他命令不接受此标志。命令打印的提示已包含该标志;后续命令也要保留它。未指定存储库时,命令会作用于最近的本地 openspec/ 根目录。
输入:用户的请求应包含变更名称(kebab-case),或描述他们想要构建的内容。
步骤
-
理解请求并澄清重要歧义
如果没有明确的输入,请向用户询问(开放式提问,不提供预设选项):
“你想处理什么变更?请描述你想要构建或修复的内容。”
根据用户的描述,推导一个 kebab-case 名称(例如,“add user authentication” →
add-user-auth)。重要:未理解用户想要构建什么之前,不要继续。
如果请求中存在会对范围、外部可观察行为、兼容性或验收标准产生重大影响的歧义,请在创建变更前询问用户。对于细节问题,请做出合理假设并记录在规划产物中。
-
确定工作流架构
使用配置的默认架构,除非用户明确要求使用其他工作流。
仅在以下情况使用其他架构:
- 用户明确指定某个架构名称 → 使用
--schema <schema-name> - 用户要求“显示工作流”或询问有哪些“工作流” → 从当前工作目录运行
openspec context --json,以确定权威根目录。如果用户明确选择了一个已注册的存储库,则运行openspec context --json --store "<store-id>"。然后将工作目录设为返回的root.path,运行openspec schemas --json,并让用户选择。这样可以保留通过本地store:指针或全局defaultStore选定的根目录;schemas不接受--store。如果 context 仅报告no_openspec_root,则改为从当前工作目录运行openspec schemas --json。无效或不可用的存储库不能使用此回退方式。
否则,省略
--schema,以保留配置的默认架构。 - 用户明确指定某个架构名称 → 使用
-
创建变更目录 选择以下一种 schema 形式。如果选择了已注册的存储,请在该命令以及下方每个接受
--store的后续 OpenSpec 命令中追加--store "<store-id>"。使用已配置的默认值:
openspec new change "<name>"使用明确指定的 schema:
openspec new change "<name>" --schema "<schema-name>"这会在 CLI 通过
.openspec.yaml解析出的规划目录中创建一个脚手架变更。 -
获取制品构建顺序
openspec status --change "<name>" --json解析 JSON 以获取:
applyRequires:实现前所需制品 ID 的数组(例如,["tasks"])artifacts:所有制品的列表,每个制品都包含其status和requires依赖项(它直接依赖的制品 ID)planningHome、changeRoot、artifactPaths和actionContext:路径和范围上下文。请使用这些信息,不要假定路径位于仓库内。
-
创建所需集合中的每个制品
使用待办列表跟踪制品进度。
按依赖顺序遍历制品(优先处理没有待解决依赖项的制品):
a. 对于每个状态为
ready(依赖项已满足)的制品:- 获取说明:
openspec instructions <artifact-id> --change "<name>" --json - 说明 JSON 包含:
context:项目背景(对你的约束——请勿包含在输出中)rules:针对制品的规则(对你的约束——请勿包含在输出中)template:输出文件所用的结构instruction:针对该制品类型的 schema 专属指导skipped/warning:当变更声明了 skip_specs 且不得创建此制品时提供——停止并选择其他制品resolvedOutputPath:要写入制品的解析后路径或模式dependencies:要阅读以了解上下文的已完成制品
- 阅读所有已完成的依赖文件以了解上下文——即使你在之前的对话中看过,也务必从磁盘重新读取(用户可能已经编辑过这些文件)
- 如果
instruction字段要求委托特定技能或命令来创建制品,请调用该技能或命令生成制品,而不是自行编写文件,然后验证resolvedOutputPath处是否存在制品文件 - 否则,使用
template作为结构创建制品文件,并将其写入resolvedOutputPath。如果resolvedOutputPath是 glob,请遵循instruction选择具体文件路径 - 将
context和rules作为约束应用——但请勿将它们复制到文件中 - 简要显示进度:“已创建 ”
b. 持续执行,直到必需集合中的每个工件都已存在(而不只是
apply.requires中的工件) - 创建每个工件后,重新运行
openspec status --change "<name>" --json - 必需集合包括
applyRequires,以及沿着status --json中的requires边从这些工件出发可达的所有工件——递归遍历这些依赖(spec-driven 会涵盖 proposal、specs、design、tasks)。不要处理该集合之外的工件 status只检查文件是否存在,因此,某个applyRequires工件显示为done并不代表它的依赖也存在——过早写入tasks.md会使tasks显示为done,但specs可能从未写入。应使用每个工件的requires边构建必需集合,而不是看它的status:即使工件显示为done,仍会列出它所依赖的内容- 已显示为
status: "skipped"的工件视为已满足:此变更在.openspec.yaml中声明了skip_specs,因此其文件不得存在。绝不要尝试创建此类文件 - 创建必需集合中所有缺失的工件,然后重新检查——创建某个工件可能会解除其他工件的阻塞
- 仅在以下情况下跳过某个工件:
status已报告其为skipped,或其自身的instruction指明它是有条件的:运行openspec instructions <artifact-id> --change "<name>" --json,仅当其instruction字段将其标记为可选(例如“仅在……时创建”)时才跳过。Spec-driven 的design.md符合条件;specs只有在上述skipped状态下才符合条件,绝不可自行判断。告知用户,并且不要重新考虑 - 依赖项是促成条件,而非门槛:如果必需工件仅因为跳过了有条件的依赖项而仍处于
blocked状态,仍应编写该工件 - 当必需集合中的每个工件都处于
done、skipped状态,或已被有意跳过时,停止
c. 如果某个工件需要用户输入(上下文不明确):
- 请用户澄清
- 然后继续创建
- 获取说明:
-
显示最终状态
openspec status --change "<name>"
输出
完成所有工件后,进行总结:
- 变更名称和位置
- 列出已创建的工件及简要说明,并说明跳过的任何有条件工件及原因
- 准备情况:“所有实施所需的工件均已就绪。”
- 提示:“工件已准备好供审阅。准备就绪后,请运行
$openspec-apply-change (Codex) or /openspec-apply-change (other agents),或让我应用此变更。”
工件创建指南
- 遵循
openspec instructions中针对每种工件类型的instruction字段——这是权威指南,即使工件名称很熟悉也应如此 - 如果
instruction字段要求使用特定技能或命令来创建工件,请调用它,而不是直接编写工件 - Schema 定义了每个工件应包含的内容——请遵循
- 创建新工件前,先阅读依赖工件以了解上下文
- 使用
template作为输出文件的结构——填写其中的各部分 - 重要:
context和rules是对你的约束,不是文件内容- 不要将
<context>、<rules>、<project_context>块复制到工件中 - 这些内容用于指导你撰写,但绝不能出现在输出中 防护措施
- 不要将
- 调用此工作流的请求仅授权进行规划。该请求中的任何实现或应用指令均不延续生效。此工作流中请勿实现更改、启动应用工作流或编辑项目代码。呈现所有产物后,请停止并等待新的用户请求,以启动应用工作流
- 创建应用阶段传递依赖的所有产物,而不仅是
apply.requires中列出的 ID - 创建新产物前,务必先读取依赖产物;从磁盘重新读取,不要依赖对话记忆(自上次查看后,文件可能已更改)
- 对于会实质改变范围、外部可观察行为、兼容性或验收标准的歧义,先提问确认;对于次要细节,做出合理假设并记录下来
- 如果已存在同名更改,请询问用户是要继续该更改还是创建新的更改
- 写入后,请在继续下一项之前确认每个产物文件确实存在