mcpField
C
creating-spec

creating-spec

github.com/pedronauck开发644274 次安装1 周前更新
代码仓库

关于 creating-spec

用于编写技术规格说明的技能,要求先探索相关代码库并确认设计决策。它提供分阶段流程、文档结构,以及 Effect-TS 和跨规格一致性检查。

主要功能

  1. 01跨代码库探索流程
  2. 02写作前澄清设计决策
  3. 03结构化规格说明模板
  4. 04Effect-TS 合规审查
  5. 05跨规格一致性检查
  6. 06实施与迁移规划

适用场景

  1. 01规划跨包的集中式模块
  2. 02记录 SDK 缺口与功能模块
  3. 03按项目规范检查规格说明

安装

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

$npx skills add https://github.com/pedronauck/skills --skill creating-spec

安装后在 Claude Code 中输入/creating-spec确认已加载。

详细介绍

创建 Spec

用于创建全面技术规范的系统化工作流,这些规范可整合分散的功能、填补 SDK 空缺,或规划新的功能模块。此技能编码了经过验证的流程,可用于编写高质量规范,例如会话管理和工具注册表桥接规范。

<critical_rules>

强制工作流

你必须按顺序遵循以下阶段。跳过或合并阶段会导致规范不完整。

阶段 1:深入探索(仅输出,不写入文件)

目标:在提出任何方案之前,梳理所有相关代码库中现有代码的全貌。

  1. 并行启动探索 Agent(同时启动 4-5 个),分别检查:

    • 将实现规范的目标包(例如,providers/sdk)
    • 实现最完整的参考代码(例如,providers/runtime)
    • 拥有各自实现的使用方代码库(例如,packages/electron/src/agents/、packages/electron/src/looper/)
    • 包含相关类型或工具的共享包(例如,packages/types)
  2. 每个探索 Agent 都必须报告:

    • 包含关键类型/接口的文件路径
    • 组件之间的连接和交互方式
    • 使用的模式(Effect 服务、Context.Tag、工厂等)
    • 各代码库之间的重复和碎片化情况
  3. 强制要求:探索后直接阅读关键文件以验证发现。不要仅依赖探索 Agent 的摘要来了解类型签名或 API 结构。

  4. 首先展示发现——向用户说明:

    • 跨代码库对比表(各处已有的内容)
    • 重复情况图谱(多个位置实现的相同功能)
    • 哪些内容应集中管理,哪些应保留原位
    • 明确指出缺口

禁止事项:阶段 1 期间不得写入任何文件。仅在聊天中输出分析。

阶段 2:澄清(写入前提问)

目标:明确会影响规范架构的设计决策。

  1. 使用 AskUserQuestion 工具提出 2-4 个有针对性的问题,涉及:

    • 范围决策(完全替换、构建基础组件,还是薄封装)
    • 自动化程度(完全自动、手动,还是混合)
    • 向后兼容性方面的考虑(原生支持,还是由使用方处理)
    • 集中模块应包含和排除的内容
  2. 问题格式:

    • 每个问题应提供 2-3 个具体选项,并附说明
    • 用“(推荐)”标出推荐选项
    • 选项应代表真正不同的架构选择,而非细枝末节的偏好
  3. 强制要求:等待用户回答后再继续。不要擅自假设默认选项。

禁止事项:一次最多提出 4 个问题。聚焦于会实质影响规范的决策。

第 3 阶段:编写规范

目标:在恰当的抽象层级编写全面的规范——描述行为约定和架构决策,而不是实现代码。

  1. 检查现有规范格式——阅读同一目录中的任何既有规范(例如,tasks/prd-sdk/1_*.md、tasks/prd-sdk/2_*.md),以符合既定的风格和结构。

  2. 按照下面的模板结构编写规范。

  3. 必需章节(必须全部包含):

    • 问题陈述(说明存在的问题或重复之处,以及当前造成的成本)
    • 设计概述(ASCII 架构图、高层流程)
    • 新增文件(目录结构)
    • 详细 API 规范(接口、类型、服务标签)
    • 替换内容(逐文件说明哪些内容将在何处变更)
    • 与现有系统的交互(说明如何与现有内容共存)
    • 公共 API 范围(明确的导出列表)
    • 高层实现概述(面向使用者的代码示例)
    • 测试策略(单元测试和集成测试计划)
    • 实施顺序(列出带依赖关系和并行安排的编号步骤)
    • 迁移路径(现有使用者的分阶段推出计划)
    • 不会迁移的内容(明确列出排除项及原因)
第 3b 阶段:EFFECT-TS 合规性检查

目标:在向用户提交规范之前,验证其中的所有代码片段都遵循 Effect-TS 模式。

必须执行:编写规范后,根据 effect-ts 和 effect-ts 技能审核每个代码片段。检查:

  1. 导入模式:必须使用 import * as Module from "effect/Module",绝不能使用 import { X } from "effect"
  2. 名义类型:所有领域基本类型(ID、键、名称)都必须通过 Schema.String.pipe(Schema.brand("X")) 添加名义标记。检查现有的 protocol/branded.ts,遵循其中既定的模式。
  3. Schema 类模式:记录使用 Schema.Class,可区分变体(事件、状态类型)使用 Schema.TaggedClass。检查 protocol/events.ts 中现有事件的定义,并严格保持一致。
  4. 不使用 Schema.Unknown:使用 JsonValue、JsonObject(来自 protocol/shared.ts),或使用 Schema.Defect(封装外部错误)。绝不使用 Schema.Unknown 或类型中的裸 unknown。
  5. 不使用 Schema.Enums:字符串字面量联合使用 Schema.Literal("a", "b", "c")。Schema.Enums 仅用于 TypeScript enum 类型。
  6. 不使用 Schema.suspend:仅用于递归类型。引用其他 Schema 时无需使用。
  7. 服务模式:服务必须使用带静态工厂方法和静态 layer 的 Context.Tag。绝不使用模块级函数实现服务逻辑或创建层。
  8. 静态辅助方法:辅助函数/工具函数必须是辅助类上的静态方法(例如,MyHelpers.resolve()),不能是模块级的 export const 函数。
  9. Effect.fn 跟踪:所有服务方法实现都必须指定 Effect.fn("ServiceName.methodName") 以支持可观测性。请在规范中明确说明此要求。
  10. 错误处理:领域错误使用 Schema.TaggedError。未知外部错误使用 Schema.Defect 封装。错误通道中不得出现 unknown。
  11. 机密信息:API 密钥和敏感值使用 Redacted.Redacted,不能使用普通的 string。
  12. 可测试性:使用 Clock.currentTimeMillis,而不是 Date.now() 或原始 clock 回调。Effect 的 TestClock 可用于控制测试时间。
  13. 不可变状态:服务状态必须保存在 Ref 或 SynchronizedRef 中,不能使用可变的 Map/Set。优先使用 Effect 提供的 HashMap.HashMap。
  14. Schema.Class 构造:返回 Schema.Class 类型实例时,必须始终使用 new ClassName({...}) 构造函数,不能使用普通对象字面量。
阶段 3c:跨规范一致性检查

目标:确保新规范不会与其他规范中的定义相矛盾或重复。

强制要求:定稿前,检查同一目录中的所有现有规范:

  1. 不得重复定义:如果某个类型、常量或函数已在其他规范中定义,则应导入,不能重新定义。常见的重复来源:
    • 提供方系列解析函数
    • 提供方元数据键回退映射
    • 涉及多个关注点的类型定义
  2. 命名一致:同一概念在所有规范中必须使用相同名称。如果规范 N 定义了 ProviderFamilyId,规范 N+1 就不能将其称为 OpenResponsesProviderFamily。
  3. 类型兼容:如果两个规范扩展了同一个接口(例如 CompozyCallProviderOptions),请列出所有规范中的全部字段,而不只是当前规范中的字段。
  4. 实现顺序:如果你的规范依赖另一规范中的类型扩展(例如 ProviderId 从 3 个值扩展为 11 个值),请在“实现顺序”部分明确记录此依赖。
  5. 规范所有权:每个类型、函数和常量都必须有一个规范的源文件。定义它的规范是其所有者。其他需要使用它的规范必须注明“从 src/path/file.ts 导入(定义于规范 N)”。
阶段 4:高层实现(按需迭代)

目标:展示具体的、面向使用者的 API 示例,说明最终结果如何运作。

  1. 在规范中加入“高层实现概览”部分,其中包含:
    • 设置/配置代码
    • 注册/初始化代码
    • 流式处理或执行期间的用法
    • 直接使用工具函数的示例(编解码器、辅助函数等)
    • 自定义提供方/扩展示例
    • 前后依赖关系图(ASCII)
  2. 如果用户另行提出此要求,请在聊天回复中提供带注释代码块的简洁说明。

</critical_rules>

<spec_template>

规范文档结构

每份规范都遵循此结构。各部分均已编号,便于交叉引用。

# [Feature Name] for [Target Package]

## Problem Statement
- What systems currently exist (list each with location)
- What duplication exists (table format: concern | location A | location B | location C)
- What this costs today (concrete pain points, not abstract)

## Design: [Design Name]
- Architecture diagram (ASCII art showing data flow)
- Key principle (e.g., "fully automatic", "opt-in", "plug-in")

## New Files
- Directory tree of new files to create

## 1-N. Detailed Specifications
- Each major component gets its own numbered section
- Include full TypeScript interfaces with JSDoc
- Show Effect service tags, Layer factories
- Specify error types

## N+1. What This Replaces
- Table: Current File | What Moves | What's Eliminated
- Separate tables per codebase (runtime, agents, looper)

## N+2. Interaction With Existing Systems
- How new code coexists with existing services
- What changes vs. what stays the same

## N+3. Public API Surface
- Explicit export lists from sub-path and main entry

## N+4. High-Level Implementation Overview
- Consumer-facing code examples (setup, usage, customization)
- Before/after dependency graph

## N+5. Testing Strategy
- Unit test plan per module
- Integration test plan
- Migrated tests from existing codebases

## N+6. Implementation Order
- Numbered steps with dependency column and parallelization notes
- Table format: Step | What | Depends On | Parallelizable

## N+7. Migration Path
- Phased rollout (Phase 1, 2, 3...)
- Each phase: what changes, what re-exports, what gets deleted

## N+8. What Does NOT Move
- Table: Concern | Location | Why It Stays
- Be explicit about boundaries

</spec_template>

<quality_standards>

质量检查清单

在认为规范完整之前,请确认:

  • 已完成跨代码库探索(而非仅探索目标包)
  • 重复项映射清楚展示了各处的重复内容
  • 所有设计决策均已通过 AskUserQuestion 与用户确认
  • TypeScript 接口完整(不是伪代码)
  • 符合 Effect-TS 要求——所有代码片段均通过阶段 3b 检查(品牌类型、Schema 模式、服务模式、Effect.fn、不使用 Schema.Unknown)
  • 跨规范一致性——没有重复定义,命名一致,类型扩展兼容(阶段 3c)
  • 规范所有权——每个类型/函数/常量都只有一个所有规范,其他规范均从该处导入
  • Effect 模式遵循项目约定(Context.Tag、Layer、Schema.TaggedError)
  • 实现顺序具有清晰的依赖链(包括跨规范依赖)
  • 迁移路径分阶段进行(而非一次性整体切换)
  • 明确列出不会迁移的内容,排除使用方关注事项
  • 高层实现展示真实的、面向使用者的代码
  • 文件路径遵循现有规范的命名约定(例如 tasks/prd-sdk/N_feature-name.md)
  • 避免过度规定——通过“规范与实现”测试(见下文)

写作风格

  • 使用表格进行比较和映射(不要用散文)
  • 使用 ASCII 图绘制架构图(不要用 mermaid)
  • 使用 TypeScript 代码块编写接口(不要用伪代码)
  • 内容具体:文件路径、函数名、类型名(不要写“该服务”或“该模块”)
  • 使用具体的行数和文件名说明“当前成本”
  • 每个部分都应回答“哪些内容会改变,哪些内容保持不变”

规范与实现测试(防止膨胀)

规范必须描述系统做什么以及为什么,而不是逐行描述如何实现。请对每个代码块应用此测试:

适合写入规范的内容(保留):
  • 类型/架构定义——这些就是契约(例如,Schema.Class、接口、品牌类型)
  • 接口签名——带有 JSDoc 的公共 API 表面
  • 简短的行为伪代码(少于 15 行)——以较高层次概述关键算法步骤
  • 决策表——提供方 → 配置 → 行为映射
  • ASCII 图示——架构、数据流、依赖关系变更前后的对比图
  • 每种模式一个示例——展示一次该模式,并注明“对 X、Y、Z 应用相同模式”
不适合写入规范的内容(替换):
  • 完整函数体(超过 15 行)——替换为行为描述:“发生 X 时,系统应执行 Y”
  • 重复的实现(同一模式展示 N 次)——只展示一次,用表格列出差异
  • 内部状态类型——内部数据结构属于实现细节,应改为描述行为
  • 确切的变量名和循环结构——对实现者限制过多
  • 可直接复制粘贴用于生产环境的代码——如果实现者会直接复制而非理解,就说明细节过多
如何精简臃肿的章节:
  1. 从代码中提取架构决策,并在代码上方用文字说明
  2. 将实现代码替换为:行为契约、映射表或接口签名
  3. 如确实需要参考代码,将其移至附录——标注为“参考实现草图(非规范性)”
  4. 单示例规则:展示一个具体示例(例如,一个 env 构造器),其余部分用表格说明
转换示例:

臃肿(8 个 env 构造器,共 131 行):

export const buildZaiEnvVars = (config: ZaiConfig): Record<string, string> => {
  const env: Record<string, string> = {};
  env.ANTHROPIC_BASE_URL = "https://api.zai.com/v1";
  if (config.apiKey) env.ANTHROPIC_AUTH_TOKEN = config.apiKey;
  // ... 15 more lines
};
export const buildOpenRouterEnvVars = (config: OpenRouterConfig): ... => { ... };
// ... 6 more builders, same pattern

正确(表格 + 1 个示例):

关键决策:每次请求都重新构造环境变量(而非在创建时预先计算)。

提供方基础 URL认证变量额外变量是否清除 API_KEY?
zaihttps://api.zai.com/v1ANTHROPIC_AUTH_TOKEN—是
openrouterhttps://openrouter.ai/api/v1ANTHROPIC_AUTH_TOKEN—是
...............

所有构造器都遵循相同模式。参考:buildZaiEnvVars(如上所示)。

</quality_standards>

<anti_patterns>

不要做的事

工作流反模式
  • 不要在探索之前编写规范——否则会遗漏重复内容和上下文
  • 不要跳过澄清阶段——设计决策会影响每个章节
  • 不要跳过 Phase 3b(Effect-TS 检查)——每份跳过此阶段编写的规范都有 5–7 处违规
  • 不要跳过 Phase 3c(跨规范检查)——规范 2 和 5 各自定义了相同的 3 个函数,但签名不同,导致 3 处严重矛盾
  • 不要在未阅读先前规范的情况下编写规范——格式一致性和类型一致性都很重要
  • 澄清问题不要超过 4 个——只关注架构决策
内容反模式
  • 不要编写含糊的接口——提供完整的类型签名并遵循 Effect 模式
  • 不要提议一次性大规模迁移——始终采用分阶段推出
  • 不要在 SDK 中纳入消费者关注点——审批关卡、UI 流式传输、提示词注入应留在消费者端
  • 不要跳过“哪些内容不会迁移”一节——明确边界可防止范围蔓延
  • 不要只提供高层概述而不附具体代码——展示设置、注册、使用和自定义方式

</anti_patterns>

臃肿反模式(来自真实审计发现)
  • 不要编写完整的函数实现 — 包含 100 行以上函数体(环境构建器、适配器、驱动程序)的规格会把架构决策埋进大段代码中。改用行为描述和表格。
  • 不要重复展示同一种模式 N 次 — 展示一次,并用表格列出差异。将一个环境构建器展示 8 次会浪费 131 行;使用表格加 1 个示例,只需 20 行且更清晰。
  • 不要指定内部状态类型 — RegistryState 及其精确的 Map 键格式属于实现细节。描述行为约定(“按工具集签名缓存桥接器”)。
  • 不要编写可直接复制粘贴的生产代码 — 如果实现者会原样复制你的代码,那你写的是实现,而不是规格。规格应要求读者进行理解和转换。
  • 不要把关键决策埋在代码中 — “request.model 的双重角色”这一决策在一个 99 行的类体中难以察觉。应先用文字说明决策,再写代码。
Effect-TS 反模式(来自真实审计发现)
  • 不要使用 Schema.Unknown — 使用 JsonValue、JsonObject 或 Schema.Defect
  • 不要为 ID 使用普通类型别名 — 使用带品牌的 schema:Schema.String.pipe(Schema.brand("X"))
  • 不要对事件使用 Schema.Class — 使用带判别的变体(带有 type 字段的事件),必须使用 Schema.TaggedClass
  • 不要对字符串字面量使用 Schema.Enums — 使用 Schema.Literal("a", "b", "c")
  • 不要定义模块作用域函数 — 在辅助类或服务类上使用静态方法
  • 不要从 Schema.Class 工厂返回普通对象 — 使用 new ClassName({...}) 构造函数
  • 不要对可测试操作使用原始回调 — 使用 Effect 服务(例如,用 Clock 替代 clock?: () => number)
  • 不要使用 as unknown as X 双重类型断言 — 使用展开语法或 Schema.encode
跨规格反模式(来自真实审计发现)
  • 不要重新定义其他规格已定义的函数 — 应导入该函数。常见陷阱:多个缺口规格分别定义 resolveProviderMetadata 等实用函数。
  • 不要给同一概念使用不同名称 — ProviderFamilyId 与 OpenResponsesProviderFamily 曾造成混淆。选定一个名称并始终使用。
  • 扩展共享类型时,不要默默丢弃字段 — 如果规格 1 向选项类型添加了 apiKey,而规格 2 扩展该类型,则应包含 apiKey,或明确说明将其移除。
  • 不要假设实现顺序 — 如果你的规格依赖另一份规格中的类型扩展(例如,ProviderId 的取值从 3 个增加到 11 个),应在“实现顺序”部分记录此依赖关系。

</anti_patterns>

评论

支持 Markdown