From supadevops
在 Next.js(App Router)/ Expo(React Native)的 npm workspaces + turborepo monorepo 中,先于实现确定 JSDoc 契约,并以 5 阶段(Plan→Test→Implement→验收→Finish)+人工门控推进的 supadevops 契约优先 TDD 开发流。当添加新功能、修复缺陷、重构,或新建/变更辅助函数/Route Handler/Server Action/组件/Expo 画面/共享库时,即使未被明确要求也必须使用本技能。它施加 JSDoc 契约、tsc/jest/Playwright/Maestro、测试放置位置、类型检查的纪律,并增强 Superpowers。对于非 supadevops 对象的仓库,或不伴随设计的一行修改,不使用本技能。
How this skill is triggered — by the user, by Claude, or both
Slash command
/supadevops:supa-tddThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
先于实现确定 **JSDoc 契约**,并让测试与实现向其收敛。**不要跳过顺序。** 本技能即 supadevops 纪律(契约优先 + TDD)的作业规约,单凭它即可自洽完结。
先于实现确定 JSDoc 契约,并让测试与实现向其收敛。不要跳过顺序。 本技能即 supadevops 纪律(契约优先 + TDD)的作业规约,单凭它即可自洽完结。
.d.ts。类型检查为 tsc -p jsconfig.json --noEmit。package.json 中 "type":"module")。app/next-<名>(Next.js src/app)、app/expo-<名>(Expo Router 同为 src/app)、package/*(共享库=与平台无关的逻辑/类型)。若无则先执行 /supa-init。request / end2end = Playwright(web、Expo web)、Maestro(Expo native)。契约优先 / 多层、详细的 JSDoc / Plan 直接生成实文件(无另设 manifest)/ 粒度为模块单位 / 进度体现在实文件(throw 桩)/ 人工门控 / 增强 Superpowers。
flowchart TD
R["要件"] --> P1["阶段1 Plan(契约)<br/>在 .js/.jsx 写多层JSDoc + throw 桩 + tsc验证"]
P1 -->|🚧 批准| P2["阶段2 Test<br/>it.todo→🚧批准→断言(red)"]
P2 --> P3["阶段3 Implement<br/>桩实现(green)、jest+tsc"]
P3 --> P4["阶段4 endpoint、end2end(验收)<br/>Playwright / Maestro、实现后"]
P4 --> P5["阶段5 Finish<br/>评审、桩残留为零"]
| 阶段 | 作业 | 门控 |
|---|---|---|
| 1 Plan(契约) | 在对象 .js/.jsx 直接写入多层 JSDoc(module/class/function/method/component props/@typedef)+ 结构占位(本体 throw new Error('not implemented'))。以 tsc -p jsconfig.json --noEmit 验证类型契约 | 🚧 批准 |
| 2 Test(red) | 针对 JSDoc 契约写 Jest。用 it.todo 列举验证项 → 🚧批准 → 填入断言得到 red | 🚧 批准(it.todo) |
| 3 Implement(green) | 以模块单位实现桩本体,让 jest + tsc 转绿 | — |
| 4 验收(endpoint、end2end) | 实现后用 Playwright/Maestro 追加(后述) | — |
| 5 Finish | 评审,并确认没有遗留未实现的桩 | — |
门控由会话侧维持。 阶段1与阶段2的 it.todo 列举之后,在获得用户批准前不向下推进。
tsc)— 自阶段1之后持续进行。| 代码种类 | 行为测试 |
|---|---|
辅助函数(src/helper/)、共享库(package/*) | Jest 单元 |
Server Action(src/action/) | Jest(公共服务、外部服务的 HTTP 用 MSW mock。纯逻辑部分抽到 helper) |
Route Handler(src/app/api/) | endpoint(Playwright request、公共/外部服务用 env 桩化的 dev 服务器) |
| React 组件 / page / layout(next UI) | end2end(Playwright) |
Expo 逻辑(app/expo-*/src/) | Jest(jest-expo) |
| Expo UI web | end2end(Playwright) / Expo UI native |
// @ts-check → import → @typedef → export 函数/class → 非公开 helper。说明仅用 JSDoc(位于对象的正上方行)。不写说明行为的行内 //(例外仅为 // @ts-check、'use server'/'use client')。<name>.test.js。endpoint=src/endpoint/、end2end(web)=src/end2end/(Expo 为 src/end2end/web/)、Maestro=src/end2end/native/*.yaml。jsconfig.json(allowJs/checkJs/noEmit/jsx/types:["node"])。测试类型来自 import(@jest/globals / @playwright/test)。阶段1:契约桩(src/helper/order.js)— 类型与意图写入 JSDoc,本体为 throw:
// @ts-check
/**
* 订单的金额计算、验证辅助函数(纯函数)。
* @module helper/order
*/
/**
* @typedef {object} OrderItem
* @property {string} sku - 商品代码
* @property {number} qty - 数量(>=1)
*/
/**
* 从明细组装新订单(纯函数。不做持久化)。
* @param {OrderItem[]} items - 1 条以上的明细
* @returns {{ items: OrderItem[], total: number, status: 'pending' }} 新订单
* @throws {RangeError} 当 items 为空时
*/
export function buildOrder(items) {
throw new Error('not implemented');
}
阶段2前半:it.todo 列举(🚧 等待批准):
import { describe, it } from '@jest/globals';
describe('buildOrder', () => {
it.todo('从明细构建订单且 status 为 pending');
it.todo('items 为空则抛出 RangeError');
});
阶段2后半:填入断言得到 red(src/helper/order.test.js)。类型仅标注在复用值(factory)上:
// @ts-check
import { describe, it, expect } from '@jest/globals';
import { buildOrder } from './order.js';
/** @param {Partial<import('./order.js').OrderItem>} [o] @returns {import('./order.js').OrderItem} */
const makeItem = (o = {}) => ({ sku: 'A1', qty: 1, ...o });
describe('buildOrder', () => {
it('从明细构建订单且 status 为 pending', () => {
expect(buildOrder([makeItem()]).status).toBe('pending');
});
it('items 为空则抛出 RangeError', () => {
expect(() => buildOrder([])).toThrow(RangeError);
});
});
组件 / Server Action 的桩(props 也用 JSDoc、本体 throw):
// @ts-check
/** @param {{ order: import('@/type/order').Order, onCancel: () => void }} props */
export function OrderCard({ order, onCancel }) {
throw new Error('not implemented');
}
// @ts-check
'use server';
/**
* 将已确定的订单发送至公共服务。
* @param {import('@/type/order').OrderItem[]} items
* @returns {Promise<{ id: string }>}
*/
export async function checkout(items) {
throw new Error('not implemented');
}
Server Action 的测试(作为函数用 Jest、公共/外部服务用 MSW mock):
// @ts-check
import { describe, it, expect, beforeAll, afterAll } from '@jest/globals';
import { setupServer } from 'msw/node';
import { http, HttpResponse } from 'msw';
import { checkout } from './checkout.js';
const server = setupServer(
http.post('https://order.internal/orders', () => HttpResponse.json({ id: 'o1' })),
);
beforeAll(() => server.listen());
afterAll(() => server.close());
describe('checkout', () => {
it('将订单发送至公共服务并返回 id', async () => {
expect((await checkout([{ sku: 'A1', qty: 1 }])).id).toBe('o1');
});
});
阶段4:endpoint(src/endpoint/orders.spec.js、无浏览器):
// @ts-check
import { test, expect } from '@playwright/test';
test('POST /api/orders 创建订单', async ({ request }) => {
const res = await request.post('/api/orders', { data: { items: [{ sku: 'A1', qty: 1 }] } });
expect(res.status()).toBe(201);
});
flowchart TD
REQ["功能请求 / 缺陷报告"] --> K{"新增 or 既有?"}
K -->|新功能| NEW["阶段1<br/>新符号的 JSDoc契约 + 桩"]
K -->|缺陷修复| FIX["阶段1<br/>确认/增强既有契约"]
NEW --> T["阶段2 red"]
FIX --> T2["阶段2 复现缺陷 red"]
T --> IMP["阶段3 实现 green"]
T2 --> IMP
IMP --> REG["阶段4-5<br/>turbo typecheck test + endpoint/end2end 做回归确认"]
REG --> REQ
每个功能请求、缺陷修复都走完整流的一轮循环。新功能=契约→red→green→回归确认。缺陷修复=确认既有契约(若有缺口则增强 JSDoc)→复现缺陷的 red→修复 green→回归确认。完成前让 turbo run typecheck test(全 workspace 的 tsc + jest)转绿(Stop 钩子自动确认)。endpoint/end2end 在阶段4执行(不计入 Stop)。修复的缺陷以 red→green 测试固化。
supa-reviewer 增强。仅当执行阶段(3 实现 / 4 验收 / 5 评审)存在 3 个以上独立模块且用户希望时,用对应技能生成、启动 Workflow 进行并行化:
supa-implement 技能supa-acceptance 技能supa-review 技能1 Workflow = 1 阶段(因运行中无法接受人工输入)。人工门控由会话侧维持。
npx claudepluginhub magcen-zone/supadevops --plugin supadevopsCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.