mcpField
O
openspec-ff-change

openspec-ff-change

github.com/fission-ai开发73.3k4.1k 次安装4 天前更新
代码仓库

关于 openspec-ff-change

此技能会快速完成 OpenSpec 规划:创建变更,并生成实现前所需的规划文档。适合希望一次完成规划流程的用户;代码修改不在其范围内。

主要功能

  1. 01创建变更框架
  2. 02按依赖顺序生成文档
  3. 03起草前检查项目上下文
  4. 04处理必需和条件性文档
  5. 05将实现留给独立流程

适用场景

  1. 01准备待实现的变更
  2. 02生成相互关联的规划文档
  3. 03规划功能或修复而不修改代码

安装

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

$npx skills add https://github.com/fission-ai/openspec --skill openspec-ff-change

安装后在 Claude Code 中输入/openspec-ff-change确认已加载。

详细介绍

通过快进完成产物创建——一次性生成开始实施所需的一切。

存储库选择: 如果用户指定了存储库(存储库是指在这台机器上注册的独立 OpenSpec 仓库),或相关工作位于某个存储库中,请运行 openspec store list --json 以发现已注册的存储库 ID,然后在读取或写入规范和变更的命令中传入 --store <id>(new change、status、instructions、list、show、validate、archive、doctor、context、schemas、view)。选定后,在工作流剩余部分始终使用 --store <id>。下文中这些命令所有未指定存储库的示例都只是简写:运行前请追加此标志。例如,运行 openspec status --change "<name>" --json --store "<id>",而不是下方展示的未指定存储库形式。其他命令不接受此标志。命令打印的提示已经包含此标志;后续命令中请保留它。未指定存储库时,命令会作用于最近的本地 openspec/ 根目录。

项目检查: 以下步骤要求项目已在使用 OpenSpec。在第一个会写入内容的步骤(new change、archive、sync specs 或编写产物文件)之前,请确认项目已有根目录:运行 openspec list --json(如果已选择存储库,则需使用 --store <id>,因为此时存储库就是根目录),并读取 root。存在根对象表示项目已完成设置。"root": null 表示尚未设置——此处没有 openspec/ 目录,像 openspec new change 这样的写入操作会将其作为副作用创建。该命令还会以非零状态退出;这就是结果,并不表示 CLI 损坏,因此请读取 JSON,而不要重试或绕过检查。

如果 status 的错误消息以 Declared in 或 Invalid store declaration in 开头,并提及此项目的 openspec/config.yaml(或 config.yml),那么一个 "root": null 并不表示项目尚未设置:该项目通过其声明的存储库使用 OpenSpec,但这台机器无法解析该存储库(存储库未注册,或 store: 行格式错误)。不要将其视为尚未初始化,也不要继续执行下方分支:停止写入,并向用户展示该错误的 message 和 fix。

否则,如果没有根目录,接下来如何处理取决于此工作流的触发方式:

  • 自动选择:此工作流是由你自行选择的,用户没有提及 OpenSpec、此技能,也没有运行其斜杠命令。停止使用 OpenSpec,并像未安装 OpenSpec 一样正常回答请求。不要要求用户进行任何设置,也不要提及 OpenSpec 设置。
  • 明确请求使用 OpenSpec:用户提到了 OpenSpec、此技能,或运行了其斜杠命令。停止写入,并询问用户希望如何继续:设置此项目(openspec init)、指定已有存储库(--store <id>),或在此请求中不使用 OpenSpec。等待用户回复。

在这两种分支中,绝不要将创建根目录作为副作用:除非用户要求,否则不要运行 openspec init;不要手动创建 openspec/ 文件;也不要让命令创建它。

输入:用户的请求应包含变更名称(kebab-case),或描述他们想要构建的内容。

步骤

  1. 如果未提供明确的输入,询问他们想构建什么

    向用户开放式提问(不要提供预设选项):

    “你想处理什么变更?请描述你想构建或修复的内容。”

    根据他们的描述推导出 kebab-case 名称(例如,“添加用户身份验证” → add-user-auth)。

    重要:在弄清楚用户想构建什么之前,不要继续。

  2. 创建变更目录

    openspec new change "<name>"
    

    这会在 CLI 解析出的规划主目录中创建一个脚手架变更。

  3. 获取制品构建顺序

    openspec status --change "<name>" --json
    

    解析 JSON,获取:

    • applyRequires:实现前所需制品 ID 的数组(例如,["tasks"])
    • artifacts:所有制品的列表,每个制品都包含其 status 和 requires 边(即它直接依赖的制品 ID)
    • planningHome、changeRoot、artifactPaths 和 actionContext:路径和范围上下文。请使用这些信息,不要假定路径位于仓库本地。
  4. 创建所需集合中的每个制品

    使用待办列表跟踪制品进度。

    按依赖顺序遍历制品(先处理没有待处理依赖项的制品):

    a. 对于每个状态为 ready(依赖项均已满足)的制品:

    • 获取说明:
      openspec instructions <artifact-id> --change "<name>" --json
      
    • 说明 JSON 包含:
      • context:项目背景(对你的约束——不要写入输出)
      • rules:制品专属规则(对你的约束——不要写入输出)
      • template:输出文件需采用的结构
      • instruction:针对该制品类型的架构专属指南
      • skipped/warning:当变更声明了 skip_specs,且不得创建该制品时会出现——停止并选择另一个制品
      • resolvedOutputPath:解析后的输出路径或模式
      • dependencies:需阅读以了解上下文的已完成制品
    • 阅读所有已完成的依赖文件以了解上下文——务必从磁盘重新读取,即使你之前在对话中看过这些文件(用户可能已编辑过)
    • 起草前检查相关项目:先阅读 context 和 rules,再检查 openspec/ 之外相关的实现、附近的测试、配置和文档。检查应保持只读,并与变更范围相称;将发现复用于后续制品,并仅在需要时进一步检查。
      • 根据请求和项目上下文确定目标项目;规划目录可能与代码分开。如果目标不明确,请询问。对于绿地项目或非代码变更,请检查可用的结构和相关文档。如果源代码不可用,说明限制;若这会实质影响计划,请向用户询问。
      • 根据检查结果确定范围、方案和任务。区分观察到的行为、假设和拟议的新增内容;如果与现有规范冲突,请明确指出,不要默默决定采用哪一方。
      • 现在就进行此项探索,不要把通用的“探索代码库”或“制定计划”任务留给实现阶段。必要的后续调查应明确针对尚未解决的问题。
    • 创建任何内容前先确定输出路径。如果 resolvedOutputPath 是 glob 模式,请按照 instruction 在 changeRoot 内选择符合该模式的具体路径,并在解析符号链接后验证其父目录和文件本身(如果文件已存在)均位于 changeRoot 内;如果不在,请停止并告知用户。否则,输出路径就是 resolvedOutputPath
    • 如果 instruction 字段要求使用特定技能或命令来创建文件,仅当它能将制品写入该输出路径时才调用;否则停止并告知用户。随后验证该输出路径上的制品文件确实存在
    • 否则使用 template 作为结构创建制品文件,并将其写入该输出路径
    • 将 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. 如果产物需要用户输入(上下文存在关键不明确之处):

    • 请用户澄清
    • 然后继续创建
  5. 显示最终状态

    openspec status --change "<name>"
    

输出

完成所有产物后,进行总结:

  • 变更名称和位置
  • 列出已创建的产物并简要说明;同时列出跳过的任何有条件产物及原因
  • 已就绪内容:“所有实现所需的产物均已就绪。”
  • 提示:“运行 /openspec-apply-change 或让我来实现,即可开始处理任务。”

产物创建指南

  • 遵循 openspec instructions 中针对每种产物类型的 instruction 字段——这是权威指南,即使产物名称很熟悉也应如此
  • 如果 instruction 字段要求使用特定技能或命令创建产物,请调用该技能或命令,而不是直接编写产物;但仅在选定并检查输出路径后,且该技能或命令能够写入该路径时才这样做
  • Schema 定义了每种产物应包含的内容——请遵循
  • 创建新产物前,请先阅读其依赖产物以了解上下文
  • 使用 template 作为输出文件的结构,并填写其中各部分
  • 重要:context 和 rules 是对你的约束,不是文件内容
    • 不要将 <context>、<rules>、<project_context> 块复制到产物中
    • 这些内容用于指导你撰写,但绝不能出现在输出中

防护措施

  • 创建实现阶段传递依赖的所有产物,而不仅是 apply.requires 中列出的产物 ID
  • 创建新产物前,务必重新从磁盘读取依赖产物,而不是依赖对话记录中的内容(文件可能已在你上次查看后发生变化)
  • 如果上下文存在关键不明确之处,请询问用户;但优先做出合理判断以保持进度
  • 如果已存在同名变更,建议继续处理该变更
  • 每次写入后,都要确认产物文件存在,再继续下一项

评论

支持 Markdown