mcpField
O
openspec-update-change

openspec-update-change

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

关于 openspec-update-change

用于审查和修订现有 OpenSpec 变更规划文档的技能,不修改实现代码。它会核对文档间的一致性,并在用户确认后写入修改,同时遵守存储区和文件范围规则。

主要功能

  1. 01选择待处理的变更
  2. 02检查规划文档一致性
  3. 03写入前提出修改供确认
  4. 04仅修改规划文件
  5. 05支持已注册的 OpenSpec 存储区

适用场景

  1. 01需求变化后修订变更计划
  2. 02解决规划文档间的矛盾
  3. 03更新计划而不触碰源代码

安装

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

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

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

详细介绍

修订变更现有的规划文档,并确保内容一致。切勿编辑代码。

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

项目检查: 以下步骤要求项目已使用 OpenSpec。在首次执行会写入内容的步骤(new change、archive、sync specs 或编写工件文件)之前,请确认项目有根目录:运行 openspec list --json(如果已选择存储,则传入 --store <id>,因为此时该存储就是根目录),并读取 root。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/ 文件;不要让命令创建它。

输入: 可选指定变更名称。如果未指定,请检查能否根据对话上下文推断。如果含糊或不明确,则必须提示用户从可用变更中选择。

此工作流用于修订已存在的工件;/openspec-continue-change 用于创建尚不存在的工件。

步骤

  1. 选择变更

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

    • 如果用户在对话中提到了某项变更,则根据上下文推断
    • 如果只有一项进行中的变更,则自动选择
    • 如果有多项可能的变更,则运行 openspec list --json,按最近修改时间排序获取可用变更,并请用户选择一项

    提示用户时,将最近修改的 3–4 项变更作为选项,并显示:

    • 变更名称
    • 状态(例如“0/5 项任务”“已完成”“无任务”)
    • 修改时间距今多久(根据 lastModified 字段)

    将最近修改的变更标记为“(推荐)”,因为它很可能就是用户想要更新的变更。 始终声明:“使用变更:”,并说明如何覆盖(例如,/openspec-update-change <other>)。

  2. 获取变更的工件

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

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

    • schemaName:正在使用的工作流架构(例如,“spec-driven”)
    • artifacts:包含工件及其状态(“done”“skipped”“ready”“blocked”)的数组
    • isPlanningComplete:用于指示所有规划工件是否已完成的布尔值。旧版 CLI 将相同值显示为 isComplete。
    • planningHome、changeRoot、artifactPaths 和 actionContext:路径和范围上下文。请使用这些值,不要假定仓库内的路径。

    工件 ID 和路径来自当前使用的架构——不要假定它们,也不要针对硬编码的工件名称编写分支逻辑。自定义架构必须能够直接使用。

    要编辑的文件是 artifactPaths.<id>.existingOutputPaths——这些是磁盘上实际存在的文件,通配符工件的路径已展开为具体文件(例如,specs/**/*.md),还包括步骤 4 中允许在部分填充的通配符工件下添加的任何已确认具体路径。不要写入 resolvedOutputPath:对于通配符工件,它仍然是通配符模式,而不是实际文件。

  3. 了解请求

    • 如果用户提出了具体的修订要求(“设计现在使用 X”),则以此为编辑起点。
    • 如果用户只说“更新”或“让内容保持一致”,则将其视为一致性审查:阅读现有工件,并检查它们之间是否存在矛盾、缺漏或重复。
  4. 阅读并协调

    • 阅读请求涉及的制品以及变更中其他已存在的制品。
    • 在对话中起草所请求的编辑,不要在文件中编辑。明确其具体变更内容;第 5 步负责所有写入。然后对照起草的编辑检查其他每个已存在的制品,方向不限:对后续制品的编辑可能需要修订较早的制品,不只是反过来。构建顺序是有用的阅读顺序,但不限制可修订的制品。
    • 记录所有现在不一致、缺失或相互矛盾的内容。
    • 提议修订已存在的文件(existingOutputPaths)。如果某个制品没有任何现有输出文件,且状态为 ready 或 blocked,请注明并指引用户前往 /openspec-continue-change 创建这些文件。保持 skipped 制品不变;不要将其视为缺失,也不要将其交给 continue 工作流处理。
    • glob 制品(例如 specs/**/*.md)在至少匹配一个文件后会标记为 done,而 continue 工作流只处理 ready 制品。当协调过程中发现 existingOutputPaths 非空的 glob 制品缺少文件时:
      1. 运行 openspec instructions "<artifact-id>" --change "<name>" --json,并使用其中的 instruction 和 template。将 context 和 rules 视为约束;不要将其复制到文件中。如果指令报告 skipped: true,则不要创建文件。从磁盘读取当前依赖文件;如果缺少必需的、未跳过的依赖文件,请停止并要求用户先恢复它。
      2. 在 changeRoot 内选择一个符合 artifactPaths.<id>.outputPath 且尚不存在的具体路径。解析任何符号链接的父目录后,确认该路径仍位于 changeRoot 内。glob 的 resolvedOutputPath 不是有效目标。
      3. 将新文件纳入第 5 步的拟议修订中,并仅在用户确认后创建。
      4. 确认后,在创建前立即刷新状态和指令。确认该制品仍在范围内、未被跳过且已有部分内容;重复上述具体路径检查。
      5. 使用目标已存在时会失败的创建操作。如果 instruction 将创建工作委托给其他技能或命令,仅当其能够遵守已确认的路径和这些防护要求时才调用;否则停止。如果任何检查失败,或已确认的草稿不再有效,请停止并与用户协调,而不是替换现有内容或另选路径。
    • 如果变更已经协调一致,请说明这一点,不要提议任何修订。
  5. 确认并逐个应用制品

    • 此步骤负责此工作流中的所有制品写入;此前的步骤都不得编辑制品。
    • 展示每项拟议修订及其原因,包括第 4 步中起草的所请求编辑。只有在用户确认后才写入。
    • 如果用户拒绝某项修订,不要写入——保持该制品不变。
    • 当需要大幅重写时,先获取该制品的规则和模板:
      openspec instructions "<artifact-id>" --change "<name>" --json
      
  6. 指出下一步(仅提供指引——绝不要执行)

    • existingOutputPaths 为空且状态为 ready 或 blocked 的制品 -> 建议使用 /openspec-continue-change 创建它们。
    • 变更已实施(任务已勾选/已应用)-> 代码可能已不再符合修订后的计划;建议使用 /openspec-apply-change 将差异应用到代码中。
    • 所有内容均已完成并实施 -> 建议使用 /openspec-archive-change。

输出 每次调用后,都显示:

  • 修改了哪些制品(以及哪些拟议修改遭到拒绝)
  • 在已有部分内容的 glob 制品下创建的任何文件
  • 任何推迟到 /openspec-continue-change 处理的事项(尚无文件且状态为 ready 或 blocked 的制品,绝不包括状态为 skipped 的制品)
  • 当前变更的进展情况以及建议执行的下一条命令

注意事项

  • 仅处理规划制品,绝不编辑实现代码。如果修订后的计划意味着需要修改代码,请停止并指向 /openspec-apply-change。
  • 使用 openspec status 报告的制品 ID 和路径;切勿根据硬编码的制品名称进行分支判断。
  • 仅编辑 existingOutputPaths 中的具体文件,以及在步骤 4 中确认允许在部分填充的 glob 制品下创建的任何具体路径;绝不写入 glob resolvedOutputPath。
  • 不要推进构建进度:如果某个制品的 existingOutputPaths 为空且状态为 ready 或 blocked,则应由 /openspec-continue-change 处理。保持 skipped 制品不变。唯一允许的新文件范围,是在 existingOutputPaths 非空的 glob 制品下确认的具体路径。
  • 写入前,须向用户确认每项修改。
  • 如果请求改变的是变更的意图,而非对其进行完善,请建议重新开始,并使用 /openspec-new-change(“更新还是重新开始”判断准则)。

评论

支持 Markdown