mcpField
O
openspec-continue-change

openspec-continue-change

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

关于 openspec-continue-change

用于推进 OpenSpec 变更并创建下一个已就绪产物的技能。它会检查变更状态和依赖项,遵循对应 schema 的指引,每次调用只创建一个产物。

主要功能

  1. 01检查变更状态
  2. 02创建下一个就绪产物
  3. 03读取已完成的依赖项
  4. 04遵循 schema 专属指引
  5. 05报告进度及后续可执行项

适用场景

  1. 01继续尚未完成规划的变更
  2. 02创建下一个提案或规划产物
  3. 03查看哪些产物已就绪

安装

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

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

安装后在 Claude Code 中输入/openspec-continue-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,而不是重试或绕过检查。

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

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

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

无论哪种情况,都不要通过副作用创建根目录:用户提出要求前,不要运行 openspec init;不要手动创建 openspec/ 文件;不要让命令创建该目录。

输入: 可选择指定变更名称。如果未指定,请检查能否根据对话上下文推断。如果描述含糊或不明确,你必须询问有哪些可用变更。

步骤

  1. 选择变更

    如果提供了名称,请使用该名称。否则:

    • 如果用户在对话中提到过某项变更,则据此推断
    • 如果只有一项活跃变更,则自动选择
    • 如果无法确定,则运行 openspec list --json 获取可用变更,并按最近修改时间排序,然后请用户选择一项

    提示用户时,列出最近修改的前 3 到 4 项变更作为选项,并显示:

    • 变更名称
    • 状态(例如“0/5 个任务”“已完成”“没有任务”)
    • 修改时间(来自 lastModified 字段)

    将最近修改的变更标记为“(推荐)”,因为它很可能是用户想要继续处理的变更。

    始终告知用户:“正在使用变更:”,并说明如何切换(例如,/openspec-continue-change <other>)。

  2. 检查当前状态

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

    解析 JSON 以了解当前状态。响应包括:

    • schemaName:所使用的工作流架构(例如,“spec-driven”)
    • artifacts:包含各项产物及其状态(“done”“skipped”“ready”或“blocked”)的数组
    • isPlanningComplete:布尔值,表示所有规划产物是否都已完成。较旧的 CLI 版本会以 isComplete 提供相同的值。
    • planningHome、changeRoot、artifactPaths 和 actionContext:路径和范围上下文。请使用这些值,不要假定路径位于仓库本地。
  3. 根据状态采取行动:


    处理其他事项之前,先完成部分写入的产物:

    • 如果某项产物的输出是 glob 模式(例如 specs/**/*.md),只要存在一个匹配文件,其状态就会显示为 done;因此,如果运行在写入文件时中断,该产物可能显示为 done,但仍有文件缺失
    • 对于每项此类 done 产物,先获取其说明并阅读确定预期文件所需的已完成依赖项。然后,将这些文件与 artifactPaths.<id>.existingOutputPaths 进行比较。对于 spec-driven 的 specs,读取提案,并检查其列出的每项能力是否都有一个 specs/<capability-path>/spec.md;在比较路径标识前,先根据 changeRoot 解析每个预期路径;并确认解析符号链接后,每个路径都仍位于 changeRoot 内部,包括其父目录和已存在的文件本身
    • 切勿写入未通过此项检查的预期路径;请停止并告知用户。如果有文件缺失,只写入缺失的文件,并将每个文件写入其通过检查的路径;如果 instruction 字段将创建工作委托给某项技能或命令,仅当它能够将每个文件写入通过检查的路径时才调用,否则请停止并告知用户;然后停止——这就算作本次调用的唯一一项产物。如果无法确定某个文件是否是有意遗漏的,请询问用户

    如果所有规划产物都已完成(isPlanningComplete: true,或旧版的 isComplete: true):

    • 向用户表示祝贺
    • 显示包含所用架构的最终状态
    • 建议:“规划已完成!现在可以开始实施此变更。实施和所有需要跟踪的工作完成后,请将其归档。”
    • 停止

    如果有可创建的工件(状态输出中显示工件的 status: "ready"):

    • 从状态输出中选择第一个 status: "ready" 的工件
    • 获取其说明:
      openspec instructions <artifact-id> --change "<name>" --json
      
    • 解析 JSON。关键字段包括:
      • context:项目背景(对你的约束——不得包含在输出中)
      • rules:工件专属规则(对你的约束——不得包含在输出中)
      • template:输出文件要使用的结构
      • instruction:特定于架构的指导
      • resolvedOutputPath:要写入工件的解析后路径或模式
      • dependencies:要读取以了解背景的已完成工件(带有 skipped: true 的条目没有文件——不要查找)
      • skipped/warning:当变更声明了 skip_specs 且不得创建此工件时出现——请改选其他工件
    • 创建工件文件:
      • 阅读所有已完成的依赖文件以了解背景——即使你之前在对话中看过,也必须始终从磁盘重新读取(用户可能已编辑这些文件)
      • 创建任何内容之前先选择输出路径。如果说明中指定的 resolvedOutputPath 是 glob 模式,请根据架构说明和变更背景,在 changeRoot 内选择一个具体路径,并验证解析符号链接后该路径仍位于 changeRoot 内,包括其父目录和文件本身(如果文件已存在);如果不在其中,请停止并告知用户。否则,输出路径就是 resolvedOutputPath
      • 如果 instruction 字段要求使用特定技能或命令来创建工件,只有当它能够将工件写入该输出路径时才调用;否则,请停止并告知用户
      • 否则,请自行编写:
        • 使用 template 作为结构——填充其中各部分
        • 编写时遵循 context 和 rules 中的约束——但不得将它们复制到文件中
        • 将文件写入该输出路径
      • 无论采用哪种方式,都要验证该输出路径下的工件文件确实存在
    • 显示创建了什么,以及现在解锁了什么
    • 创建一个工件后即停止

    如果没有可创建的工件(全部受阻):

    • 这种情况不应该发生在有效架构中
    • 显示状态并建议检查问题
  4. 创建工件后,显示进度

    openspec status --change "<name>"
    

输出

每次调用后,显示:

  • 创建了哪个工件
  • 使用的架构工作流
  • 当前进度(已完成 N/M 项)
  • 现在解锁了哪些工件
  • 提示:“想继续吗?只需让我继续,或告诉我下一步该做什么。”

工件创建指南

工件类型及其用途取决于架构。说明输出中的 instruction 字段是每种工件的权威指导——即使工件名称很熟悉(如 proposal.md、tasks.md 等),也应遵循该指导,因为自定义架构可能会为相同文件名定义不同的内容或流程。

如果 instruction 字段要求使用特定技能或命令来创建工件,请调用它,而不要直接编写工件——但前提是你已选择并检查输出路径,而且该技能或命令能够将工件写入该路径。

安全护栏

  • 每次调用只创建一个工件
  • 创建新工件前,始终先阅读依赖工件——从磁盘重新读取,而不是依赖对话记忆(自上次查看后,文件可能已更改)
  • 永远不要跳过工件,也不要打乱顺序创建
  • 如果背景不明确,请先询问用户,再创建
  • 写入后,验证工件文件确实存在,再标记进度
  • 使用架构规定的工件顺序,不要擅自假设具体工件名称
  • 重要:context 和 rules 是对你的约束,不是文件内容
    • 不要将 <context>、<rules>、<project_context> 块复制到工件中
    • 这些内容用于指导你编写,但绝不能出现在输出中

评论

支持 Markdown