@deepstorm/cli 0.11.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/dist/build-registry.js +11 -5
- package/dist/cli.js +839 -585
- package/dist/mcp/code-hosting/github.json +14 -1
- package/dist/mcp/docs-reference/context7.json +1 -10
- package/dist/mcp-skills/deepstorm-mcp-feishu-wiki-read/SKILL.md +8 -5
- package/dist/mcp-skills/deepstorm-mcp-feishu-wiki-write/SKILL.md +10 -8
- package/dist/mcp-skills/deepstorm-mcp-figma-read/SKILL.md +21 -20
- package/dist/mcp-skills/deepstorm-mcp-github-read/SKILL.md +17 -17
- package/dist/mcp-skills/deepstorm-mcp-github-write/SKILL.md +20 -20
- package/dist/mcp-skills/deepstorm-mcp-jira-read/SKILL.md +8 -8
- package/dist/mcp-skills/deepstorm-mcp-jira-write/SKILL.md +13 -12
- package/dist/mcp-skills/deepstorm-mcp-playwright-read/SKILL.md +10 -10
- package/dist/skills/atoll-ops/SKILL.md +4 -0
- package/dist/skills/reef-commit/SKILL.md +9 -5
- package/dist/skills/reef-commit/scripts/branch-check.mjs +5 -11
- package/dist/skills/reef-commit/scripts/check-openspec-status.mjs +6 -12
- package/dist/skills/reef-commit/scripts/collect-git-context.mjs +13 -11
- package/dist/skills/reef-gen-backend/variants/java/steps.md +7 -7
- package/dist/skills/reef-gen-backend/variants/nodejs/steps.md +7 -7
- package/dist/skills/reef-gen-backend/variants/python/steps.md +7 -7
- package/dist/skills/reef-gen-frontend/variants/angular/steps.md +5 -5
- package/dist/skills/reef-gen-frontend/variants/react/steps.md +6 -6
- package/dist/skills/reef-gen-frontend/variants/vue/steps.md +6 -6
- package/dist/skills/reef-harden/EXAMPLES.md +12 -10
- package/dist/skills/reef-harden/SKILL.md +6 -0
- package/dist/skills/reef-harden/scripts/find-change-dir.mjs +13 -13
- package/dist/skills/reef-pr/SKILL.md +7 -0
- package/dist/skills/reef-pr/scripts/create-pr.mjs +31 -29
- package/dist/skills/reef-scope/SKILL.md +6 -6
- package/dist/skills/reef-start/references/jira-start-subagent.md +7 -7
- package/dist/skills/reef-start/references/risk-routing-card.md +28 -25
- package/dist/skills/reef-start/references/stage-4-implementation.md +33 -21
- package/dist/skills/reef-start/references/superpowers-gate.md +9 -9
- package/dist/skills/reef-style-backend/fragments/java/ai/spring-ai/examples/structured-output.md +2 -2
- package/dist/skills/reef-style-backend/fragments/java/ai/spring-ai/quick-reference.md +11 -0
- package/dist/skills/reef-style-backend/fragments/java/api-spec/jackson-polymorphism.md +36 -40
- package/dist/skills/reef-style-backend/fragments/java/api-spec/quick-reference.md +11 -10
- package/dist/skills/reef-style-backend/fragments/java/db-migration/liquibase/examples/database-migration.md +7 -7
- package/dist/skills/reef-style-backend/fragments/java/dependency-management/quick-reference.md +24 -21
- package/dist/skills/reef-style-backend/fragments/java/exception-handling/examples/error-code-enum.md +7 -7
- package/dist/skills/reef-style-backend/fragments/java/exception-handling/quick-reference.md +10 -8
- package/dist/skills/reef-style-backend/fragments/java/framework/spring-boot/examples/dto-mapper.md +2 -2
- package/dist/skills/reef-style-backend/fragments/java/framework/spring-boot/examples/service-entity.md +5 -5
- package/dist/skills/reef-style-backend/fragments/java/framework/spring-boot/examples/testing.md +1 -0
- package/dist/skills/reef-style-backend/fragments/java/framework/spring-boot/quick-reference.md +12 -12
- package/dist/skills/reef-style-backend/fragments/java/orm/hibernate/quick-reference.md +13 -12
- package/dist/skills/reef-style-backend/fragments/java/security-redlines/quick-reference.md +11 -9
- package/dist/skills/reef-style-backend/fragments/java/test/data-jpa-test/quick-reference.md +7 -7
- package/dist/skills/reef-style-backend/fragments/java/test/junit5/quick-reference.md +6 -6
- package/dist/skills/reef-style-backend/fragments/java/test/spring-mvc-test/quick-reference.md +8 -8
- package/dist/skills/reef-style-backend/fragments/java/test/spring-service-test/quick-reference.md +8 -7
- package/dist/skills/reef-style-backend/fragments/nodejs/eslint-config.json +1 -4
- package/dist/skills/reef-style-backend/fragments/nodejs/nestjs-structure.md +9 -9
- package/dist/skills/reef-style-backend/fragments/python/alembic-migration/quick-reference.md +2 -1
- package/dist/skills/reef-style-backend/fragments/python/api-spec/quick-reference.md +10 -10
- package/dist/skills/reef-style-backend/fragments/python/dependency-management/quick-reference.md +24 -22
- package/dist/skills/reef-style-backend/fragments/python/exception-handling/quick-reference.md +10 -9
- package/dist/skills/reef-style-backend/fragments/python/fastapi-quick-reference/quick-reference.md +3 -0
- package/dist/skills/reef-style-backend/fragments/python/langchain/quick-reference.md +10 -7
- package/dist/skills/reef-style-backend/fragments/python/pytest-testing/quick-reference.md +2 -0
- package/dist/skills/reef-style-backend/fragments/python/ruff-mypy-toolchain/quick-reference.md +2 -0
- package/dist/skills/reef-style-backend/fragments/python/security-redlines/quick-reference.md +11 -9
- package/dist/skills/reef-style-backend/fragments/python/sqlalchemy-orm/quick-reference.md +3 -0
- package/dist/skills/reef-style-backend/variants/java/examples/code-wrapping.md +3 -4
- package/dist/skills/reef-style-backend/variants/java/quick-reference.md +31 -29
- package/dist/skills/reef-style-backend/variants/nodejs/examples/module-example.md +2 -8
- package/dist/skills/reef-style-backend/variants/nodejs/quick-reference.md +35 -36
- package/dist/skills/reef-style-backend/variants/python/quick-reference.md +32 -31
- package/dist/skills/reef-style-frontend/fragments/css/tailwind/quick-reference.md +9 -7
- package/dist/skills/reef-style-frontend/fragments/test/vitest/examples/testing.md +9 -4
- package/dist/skills/reef-style-frontend/fragments/test/vitest/quick-reference.md +4 -4
- package/dist/skills/reef-style-frontend/fragments/test/vitest-react/examples/testing.md +135 -140
- package/dist/skills/reef-style-frontend/fragments/test/vitest-react/quick-reference.md +32 -32
- package/dist/skills/reef-style-frontend/fragments/test/vitest-vue/examples/testing.md +161 -162
- package/dist/skills/reef-style-frontend/fragments/test/vitest-vue/quick-reference.md +42 -42
- package/dist/skills/reef-style-frontend/fragments/ts-config/strict/quick-reference.md +16 -10
- package/dist/skills/reef-style-frontend/fragments/ui-lib/antd/examples/ui-components.md +72 -87
- package/dist/skills/reef-style-frontend/fragments/ui-lib/antd/quick-reference.md +14 -10
- package/dist/skills/reef-style-frontend/fragments/ui-lib/antd-vue/examples/ui-components.md +93 -111
- package/dist/skills/reef-style-frontend/fragments/ui-lib/antd-vue/quick-reference.md +29 -33
- package/dist/skills/reef-style-frontend/fragments/ui-lib/primeng/examples/ui-components.md +14 -23
- package/dist/skills/reef-style-frontend/variants/angular/examples/code-wrapping.md +15 -17
- package/dist/skills/reef-style-frontend/variants/angular/examples/component-types-pipes.md +22 -5
- package/dist/skills/reef-style-frontend/variants/angular/examples/entity-types.md +52 -22
- package/dist/skills/reef-style-frontend/variants/angular/examples/forms-layer.md +17 -20
- package/dist/skills/reef-style-frontend/variants/angular/examples/service-routing.md +8 -11
- package/dist/skills/reef-style-frontend/variants/angular/quick-reference.md +27 -27
- package/dist/skills/reef-style-frontend/variants/react/examples/code-wrapping.md +14 -27
- package/dist/skills/reef-style-frontend/variants/react/examples/component-types-pipes.md +45 -52
- package/dist/skills/reef-style-frontend/variants/react/examples/entity-types.md +44 -44
- package/dist/skills/reef-style-frontend/variants/react/examples/forms-layer.md +56 -85
- package/dist/skills/reef-style-frontend/variants/react/examples/service-routing.md +114 -88
- package/dist/skills/reef-style-frontend/variants/react/quick-reference.md +48 -42
- package/dist/skills/reef-style-frontend/variants/vue/examples/code-wrapping.md +24 -43
- package/dist/skills/reef-style-frontend/variants/vue/examples/component-types-pipes.md +48 -49
- package/dist/skills/reef-style-frontend/variants/vue/examples/entity-types.md +45 -45
- package/dist/skills/reef-style-frontend/variants/vue/examples/forms-layer.md +64 -68
- package/dist/skills/reef-style-frontend/variants/vue/examples/service-routing.md +85 -84
- package/dist/skills/reef-style-frontend/variants/vue/quick-reference.md +46 -51
- package/dist/skills/reef-testcase/SKILL.md +19 -19
- package/dist/skills/reef-testcase/references/coverage-dimensions.md +8 -0
- package/dist/skills/reef-testcase/references/test-case-template.md +16 -16
- package/dist/skills/sweep-explore/SKILL.md +129 -100
- package/dist/skills/sweep-explore/references/explore-flow-template.md +9 -9
- package/dist/skills/sweep-init/SKILL.md +4 -0
- package/dist/skills/sweep-init/scripts/flow-selector.mjs +6 -11
- package/dist/skills/sweep-init/scripts/init-project.mjs +68 -51
- package/dist/skills/sweep-plan/references/test-flow-template.md +12 -6
- package/dist/skills/sweep-record/SKILL.md +38 -15
- package/dist/skills/sweep-run/SKILL.md +59 -50
- package/dist/skills/sweep-run/scripts/env-manager.mjs +4 -5
- package/dist/skills/sweep-run/scripts/flow-parser.mjs +7 -6
- package/dist/skills/sweep-run/scripts/flow-selector.mjs +4 -15
- package/dist/skills/sweep-run/scripts/generate-report.mjs +1 -2
- package/dist/skills/sweep-run/scripts/mcp-manager.mjs +107 -14
- package/dist/skills/sweep-run/scripts/spec-compiler.mjs +19 -9
- package/dist/skills/tide-discuss/references/checklists.md +32 -32
- package/dist/skills/tide-discuss/references/data-format.md +85 -77
- package/dist/skills/tide-discuss/references/prd-template.md +21 -19
- package/dist/skills/tide-discuss/references/publish-flow.md +30 -11
- package/dist/skills/tide-discuss/references/role-prompts.md +5 -5
- package/package.json +4 -3
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
|
|
17
17
|
每类文件必须包含以下注释(缺少则视为未完成):
|
|
18
18
|
|
|
19
|
-
| 文件类型
|
|
20
|
-
|
|
21
|
-
| **Prisma Schema** | 每个 model 加 `/// 注释` 描述实体用途;每个字段加 `/// 注释`
|
|
22
|
-
| **DTO**
|
|
23
|
-
| **Service**
|
|
24
|
-
| **Controller**
|
|
25
|
-
| **Module**
|
|
19
|
+
| 文件类型 | 注释要求 |
|
|
20
|
+
| ----------------- | ------------------------------------------------------------------------------------ |
|
|
21
|
+
| **Prisma Schema** | 每个 model 加 `/// 注释` 描述实体用途;每个字段加 `/// 注释` |
|
|
22
|
+
| **DTO** | 类 JSDoc `/** 用途说明 */`;字段通过 `@ApiProperty({ description: '...' })` 提供文档 |
|
|
23
|
+
| **Service** | 每个 public 方法加 JSDoc `/** 功能、@param、@returns */`;复杂逻辑内联注释说明 |
|
|
24
|
+
| **Controller** | 每个端点加 `@ApiOperation({ summary: '...', description: '...' })` |
|
|
25
|
+
| **Module** | 类 JSDoc `/** 模块职责 */` |
|
|
26
26
|
|
|
27
27
|
## 安全红线
|
|
28
28
|
|
|
@@ -50,13 +50,13 @@ app.include_router(orders.router, prefix="/api/v1/orders", tags=["orders"])
|
|
|
50
50
|
|
|
51
51
|
每类文件必须包含以下注释(缺少则视为未完成):
|
|
52
52
|
|
|
53
|
-
| 文件类型
|
|
54
|
-
|
|
55
|
-
| **Schema (Pydantic)**
|
|
56
|
-
| **Model (SQLAlchemy)** | 类 docstring 说明表含义;复杂字段用 `comment=` 或行内注释说明
|
|
57
|
-
| **Service**
|
|
58
|
-
| **Router**
|
|
59
|
-
| **Migration**
|
|
53
|
+
| 文件类型 | 注释要求 |
|
|
54
|
+
| ---------------------- | ----------------------------------------------------------------------------------------- |
|
|
55
|
+
| **Schema (Pydantic)** | 类 docstring 说明用途;关键字段用 `Field(description=...)`(会生成 OpenAPI 文档) |
|
|
56
|
+
| **Model (SQLAlchemy)** | 类 docstring 说明表含义;复杂字段用 `comment=` 或行内注释说明 |
|
|
57
|
+
| **Service** | 每个 public 函数加 docstring(Google 风格 `"""功能、Args、Returns"""`);复杂逻辑行内注释 |
|
|
58
|
+
| **Router** | 每个端点加 `summary=`/`description=` 参数或 docstring |
|
|
59
|
+
| **Migration** | 每个 revision 加 docstring 说明变更意图 |
|
|
60
60
|
|
|
61
61
|
## ⚠️ 异步红线
|
|
62
62
|
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
|
|
12
12
|
## 注释要求
|
|
13
13
|
|
|
14
|
-
| 文件类型
|
|
15
|
-
|
|
16
|
-
| **类型定义**
|
|
17
|
-
| **Service**
|
|
14
|
+
| 文件类型 | 注释要求 |
|
|
15
|
+
| ------------- | ---------------------------------------- |
|
|
16
|
+
| **类型定义** | 复杂类型加行内注释说明字段含义 |
|
|
17
|
+
| **Service** | 简要说明每个方法的功能和返回类型 |
|
|
18
18
|
| **Component** | 关键组件加注释说明用途;复杂逻辑行内注释 |
|
|
19
|
-
| **路由**
|
|
19
|
+
| **路由** | 无需额外注释 |
|
|
20
20
|
|
|
21
21
|
## 核心约束
|
|
22
22
|
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
|
|
12
12
|
## 注释要求
|
|
13
13
|
|
|
14
|
-
| 文件类型
|
|
15
|
-
|
|
16
|
-
| **类型定义** | 复杂类型加行内注释说明字段含义
|
|
17
|
-
| **API Hook** | 简要说明该 Hook 的功能和返回值
|
|
18
|
-
| **组件**
|
|
19
|
-
| **页面**
|
|
14
|
+
| 文件类型 | 注释要求 |
|
|
15
|
+
| ------------ | ---------------------------------------- |
|
|
16
|
+
| **类型定义** | 复杂类型加行内注释说明字段含义 |
|
|
17
|
+
| **API Hook** | 简要说明该 Hook 的功能和返回值 |
|
|
18
|
+
| **组件** | 关键组件加注释说明用途;复杂逻辑行内注释 |
|
|
19
|
+
| **页面** | 无需额外注释 |
|
|
20
20
|
|
|
21
21
|
## 核心约束
|
|
22
22
|
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
|
|
12
12
|
## 注释要求
|
|
13
13
|
|
|
14
|
-
| 文件类型
|
|
15
|
-
|
|
16
|
-
| **类型定义**
|
|
17
|
-
| **组合式函数** | 简要说明该函数的功能和返回值
|
|
18
|
-
| **组件**
|
|
19
|
-
| **页面**
|
|
14
|
+
| 文件类型 | 注释要求 |
|
|
15
|
+
| -------------- | ---------------------------------------- |
|
|
16
|
+
| **类型定义** | 复杂类型加行内注释说明字段含义 |
|
|
17
|
+
| **组合式函数** | 简要说明该函数的功能和返回值 |
|
|
18
|
+
| **组件** | 关键组件加注释说明用途;复杂逻辑行内注释 |
|
|
19
|
+
| **页面** | 无需额外注释 |
|
|
20
20
|
|
|
21
21
|
## 核心约束
|
|
22
22
|
|
|
@@ -14,6 +14,7 @@ proposal.md 的 Scope 段列出了 21 条要做的功能,但没有一条"不
|
|
|
14
14
|
|
|
15
15
|
```markdown
|
|
16
16
|
## 不做什么
|
|
17
|
+
|
|
17
18
|
- 仅支持 Scope 中列出的控件类型(TextControl、NumberControl、DateTimeControl、
|
|
18
19
|
ChoiceControl、ObjectControl),其余控件均不在本版本支持范围内
|
|
19
20
|
- 不支持批量导入(不支持一次上传多个 Excel 文件)
|
|
@@ -37,6 +38,7 @@ spec.md 末尾新增:
|
|
|
37
38
|
|
|
38
39
|
```markdown
|
|
39
40
|
## Known Limitations
|
|
41
|
+
|
|
40
42
|
本版本存在以下已知约束:
|
|
41
43
|
|
|
42
44
|
- **仅支持新增**:导入操作仅创建新的 FormResponse,不支持通过
|
|
@@ -61,16 +63,16 @@ spec.md 末尾新增:
|
|
|
61
63
|
|
|
62
64
|
```markdown
|
|
63
65
|
- [x] 7.1 `FormExportServiceTest`:测试 Excel 生成逻辑(表头必填标记、
|
|
64
|
-
|
|
66
|
+
填写说明行、下拉验证、隐藏 Sheet、Sheet 保护)
|
|
65
67
|
```
|
|
66
68
|
|
|
67
69
|
### 加固后
|
|
68
70
|
|
|
69
71
|
```markdown
|
|
70
72
|
- [x] 7.1 `FormExportServiceTest`:覆盖 TextControl / NumberControl /
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
DateTimeControl / ChoiceControl(PredefinedOptionsSource + DatasetOptionsSource)
|
|
74
|
+
/ ObjectControl 五种控件导出;验证标题行必填标记 *、填写说明行、_meta Sheet
|
|
75
|
+
的 revisionId 与 key 顺序、Sheet VERY_HIDDEN + 保护、白名单过滤、空字段报错
|
|
74
76
|
```
|
|
75
77
|
|
|
76
78
|
关键动作:将"测试 X"的许愿式描述替换为场景覆盖清单。
|
|
@@ -81,9 +83,9 @@ spec.md 末尾新增:
|
|
|
81
83
|
|
|
82
84
|
加固过程中发现的数字:
|
|
83
85
|
|
|
84
|
-
| 数字
|
|
85
|
-
|
|
86
|
-
| 5MB / 3000行 / 200列
|
|
87
|
-
| #3B82F6 / #22C55E 等颜色
|
|
88
|
-
| w-225(对话框宽度)
|
|
89
|
-
| application.properties vs .yaml | **修正**
|
|
86
|
+
| 数字 | 处理方式 | 理由 |
|
|
87
|
+
| ------------------------------- | ---------- | --------------------------- |
|
|
88
|
+
| 5MB / 3000行 / 200列 | **不修改** | 业务指标,用户确认 |
|
|
89
|
+
| #3B82F6 / #22C55E 等颜色 | **不修改** | 有引用来源(Figma) |
|
|
90
|
+
| w-225(对话框宽度) | **不修改** | 设计稿尺寸,可追溯 |
|
|
91
|
+
| application.properties vs .yaml | **修正** | 项目实际使用 yaml,文档写错 |
|
|
@@ -19,6 +19,7 @@ node packages/reef/skills/reef-harden/scripts/find-change-dir.mjs
|
|
|
19
19
|
输出 JSON。`noMatch: true` 时需让用户选择;有 `suggestion` 时使用推荐 change。
|
|
20
20
|
|
|
21
21
|
如需并列出 SDD 文档路径:
|
|
22
|
+
|
|
22
23
|
```bash
|
|
23
24
|
node packages/reef/skills/reef-harden/scripts/find-change-dir.mjs --files
|
|
24
25
|
```
|
|
@@ -60,6 +61,7 @@ openspec/changes/<change>/
|
|
|
60
61
|
#### 第一道筛:特定数字
|
|
61
62
|
|
|
62
63
|
搜索文档中所有具体数字(5MB、3000、80%、100ms 等),逐一判断:
|
|
64
|
+
|
|
63
65
|
- 有引用来源(benchmark、SLA、Figma 等)→ 通过
|
|
64
66
|
- 无引用来源 → 标注 TBD 或在旁边加上 Rationale 说明理由
|
|
65
67
|
- 禁止让"看起来合理但无根据"的数字留在文档里
|
|
@@ -67,10 +69,12 @@ openspec/changes/<change>/
|
|
|
67
69
|
#### 第二道筛:"不做什么"
|
|
68
70
|
|
|
69
71
|
检查是否存在 `## 不做什么` / `## Out of Scope` 段:
|
|
72
|
+
|
|
70
73
|
- 若不存在 → 必须新增
|
|
71
74
|
- 若存在但内容敷衍(< 5 条)→ 用反向提问扩充:"这个功能在第一版里应该不做什么?"
|
|
72
75
|
|
|
73
76
|
至少应覆盖:
|
|
77
|
+
|
|
74
78
|
- 不支持的功能/控件/场景(明确列出)
|
|
75
79
|
- 第一版 scale 边界(并发、文件大小、批量操作等)
|
|
76
80
|
- 是 permanent out 还是 v2 做(标注)
|
|
@@ -78,6 +82,7 @@ openspec/changes/<change>/
|
|
|
78
82
|
#### 第三道筛:验证方法
|
|
79
83
|
|
|
80
84
|
检查所有验证要求,确保每一条可执行:
|
|
85
|
+
|
|
81
86
|
- "定期 review" → 不合格,追问为"谁、频率、用什么工具"
|
|
82
87
|
- "写测试" → 不合格,细化为"FormExportServiceTest:覆盖 X/Y/Z 场景"
|
|
83
88
|
- 每条验证应对应一个 CI 命令或具体测试步骤
|
|
@@ -110,6 +115,7 @@ openspec/changes/<change>/
|
|
|
110
115
|
### Step 3: 沉淀 Known Limitations
|
|
111
116
|
|
|
112
117
|
在 proposal.md 末尾添加 `## Known Limitations` 段,内容来源:
|
|
118
|
+
|
|
113
119
|
1. 第二步"不做什么"中标注的边界
|
|
114
120
|
2. 第四步反向 grill 中不可忽视的风险点
|
|
115
121
|
3. 已知但有意推迟的 trade-off
|
|
@@ -31,9 +31,7 @@ function isArchivePath(changePath) {
|
|
|
31
31
|
* @returns {object|null}
|
|
32
32
|
*/
|
|
33
33
|
export function findChangeByName(changes, name) {
|
|
34
|
-
return changes.find(c =>
|
|
35
|
-
c.name === name && !isArchivePath(c.path)
|
|
36
|
-
) || null;
|
|
34
|
+
return changes.find((c) => c.name === name && !isArchivePath(c.path)) || null;
|
|
37
35
|
}
|
|
38
36
|
|
|
39
37
|
/**
|
|
@@ -42,7 +40,7 @@ export function findChangeByName(changes, name) {
|
|
|
42
40
|
* @returns {object|null}
|
|
43
41
|
*/
|
|
44
42
|
export function findMostRecent(changes) {
|
|
45
|
-
const active = changes.filter(c => !c.archived);
|
|
43
|
+
const active = changes.filter((c) => !c.archived);
|
|
46
44
|
if (active.length === 0) return null;
|
|
47
45
|
return active.sort((a, b) => b.mtimeMs - a.mtimeMs)[0];
|
|
48
46
|
}
|
|
@@ -115,9 +113,10 @@ find-change-dir.mjs — 发现 OpenSpec change 目录
|
|
|
115
113
|
process.exit(0);
|
|
116
114
|
}
|
|
117
115
|
|
|
118
|
-
const root =
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
const root =
|
|
117
|
+
process.argv.indexOf('--dir') >= 0
|
|
118
|
+
? process.argv[process.argv.indexOf('--dir') + 1]
|
|
119
|
+
: process.env.INIT_CWD || process.cwd();
|
|
121
120
|
const changesDir = join(root, CHANGES_GLOB);
|
|
122
121
|
const allChanges = listChanges(changesDir);
|
|
123
122
|
|
|
@@ -137,9 +136,7 @@ find-change-dir.mjs — 发现 OpenSpec change 目录
|
|
|
137
136
|
} else {
|
|
138
137
|
const branch = execGitBranch();
|
|
139
138
|
result = branch
|
|
140
|
-
?
|
|
141
|
-
{ noMatch: true, branch,
|
|
142
|
-
suggestion: findMostRecent(allChanges) })
|
|
139
|
+
? findChangeByName(allChanges, branch) || { noMatch: true, branch, suggestion: findMostRecent(allChanges) }
|
|
143
140
|
: { noMatch: true, allChanges };
|
|
144
141
|
}
|
|
145
142
|
|
|
@@ -148,9 +145,12 @@ find-change-dir.mjs — 发现 OpenSpec change 目录
|
|
|
148
145
|
|
|
149
146
|
function execGitBranch() {
|
|
150
147
|
try {
|
|
151
|
-
return
|
|
152
|
-
|
|
153
|
-
|
|
148
|
+
return (
|
|
149
|
+
execSync('git branch --show-current', {
|
|
150
|
+
encoding: 'utf8',
|
|
151
|
+
timeout: 5000,
|
|
152
|
+
}).trim() || null
|
|
153
|
+
);
|
|
154
154
|
} catch {
|
|
155
155
|
return null;
|
|
156
156
|
}
|
|
@@ -43,13 +43,20 @@ node packages/reef/skills/reef-pr/scripts/create-pr.mjs --collect
|
|
|
43
43
|
|
|
44
44
|
```markdown
|
|
45
45
|
## 概要
|
|
46
|
+
|
|
46
47
|
{2-4 行概括变更动机,优先从 proposal.md 提取}
|
|
48
|
+
|
|
47
49
|
## 关联
|
|
50
|
+
|
|
48
51
|
JIRA: {commit body / proposal.md / jira-start 元数据}
|
|
49
52
|
OpenSpec: openspec/changes/{branch-name}/
|
|
53
|
+
|
|
50
54
|
## 变更清单
|
|
55
|
+
|
|
51
56
|
{git diff --stat 输出}
|
|
57
|
+
|
|
52
58
|
## 测试计划
|
|
59
|
+
|
|
53
60
|
- [ ] {前端路径含 src/main/web/ 则加}
|
|
54
61
|
- [ ] {后端路径含 src/main/java/ 则加}
|
|
55
62
|
- [ ] {手动验证步骤,如有}
|
|
@@ -40,13 +40,13 @@ export function buildPrBody(ctx) {
|
|
|
40
40
|
lines.push(`Changes: ${s.files} 文件, +${s.insertions}/-${s.deletions}`);
|
|
41
41
|
lines.push('');
|
|
42
42
|
lines.push('## 变更清单');
|
|
43
|
-
s.changedFiles.forEach(f => lines.push(`- \`${f}\``));
|
|
43
|
+
s.changedFiles.forEach((f) => lines.push(`- \`${f}\``));
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
if (ctx.commitLog && ctx.commitLog.length > 0) {
|
|
47
47
|
lines.push('');
|
|
48
48
|
lines.push('## Commits');
|
|
49
|
-
ctx.commitLog.forEach(c => lines.push(`- ${c.hash} ${c.message}`));
|
|
49
|
+
ctx.commitLog.forEach((c) => lines.push(`- ${c.hash} ${c.message}`));
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
return lines.join('\n');
|
|
@@ -74,27 +74,18 @@ function exec(command) {
|
|
|
74
74
|
|
|
75
75
|
function collectContext() {
|
|
76
76
|
const branch = exec('git branch --show-current');
|
|
77
|
-
const forkPoint = exec(
|
|
78
|
-
|
|
79
|
-
);
|
|
80
|
-
const diffStat = exec(
|
|
81
|
-
`git diff "${forkPoint || 'main'}..HEAD" --stat`
|
|
82
|
-
);
|
|
83
|
-
const commitLog = forkPoint
|
|
84
|
-
? exec(`git log "${forkPoint}"..HEAD --oneline`)
|
|
85
|
-
: '';
|
|
77
|
+
const forkPoint = exec('git merge-base main HEAD');
|
|
78
|
+
const diffStat = exec(`git diff "${forkPoint || 'main'}..HEAD" --stat`);
|
|
79
|
+
const commitLog = forkPoint ? exec(`git log "${forkPoint}"..HEAD --oneline`) : '';
|
|
86
80
|
const statusShort = exec('git status --short');
|
|
87
81
|
|
|
88
82
|
// 查找关联 proposal
|
|
89
83
|
let proposalTitle = '';
|
|
90
|
-
const root = exec(
|
|
91
|
-
'git rev-parse --show-toplevel 2>/dev/null || echo ""'
|
|
92
|
-
);
|
|
84
|
+
const root = exec('git rev-parse --show-toplevel');
|
|
93
85
|
if (root && branch) {
|
|
94
86
|
const p = join(root, 'openspec', 'changes', branch, 'proposal.md');
|
|
95
87
|
if (existsSync(p)) {
|
|
96
|
-
const firstLine = readFileSync(p, 'utf8')
|
|
97
|
-
.split('\n')[0] || '';
|
|
88
|
+
const firstLine = readFileSync(p, 'utf8').split('\n')[0] || '';
|
|
98
89
|
proposalTitle = firstLine.replace(/^#+\s*/, '').trim();
|
|
99
90
|
}
|
|
100
91
|
}
|
|
@@ -104,10 +95,14 @@ function collectContext() {
|
|
|
104
95
|
hasUncommitted: checkUncommitted(statusShort),
|
|
105
96
|
proposalTitle,
|
|
106
97
|
commitLog: commitLog
|
|
107
|
-
? commitLog
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
98
|
+
? commitLog
|
|
99
|
+
.split('\n')
|
|
100
|
+
.filter(Boolean)
|
|
101
|
+
.map((l) => {
|
|
102
|
+
const m = l.match(/^(\S+)\s+(.*)/);
|
|
103
|
+
return m ? { hash: m[1], message: m[2] } : null;
|
|
104
|
+
})
|
|
105
|
+
.filter(Boolean)
|
|
111
106
|
: [],
|
|
112
107
|
diffStat: diffStat ? parseDiffStat(diffStat) : null,
|
|
113
108
|
};
|
|
@@ -116,7 +111,9 @@ function collectContext() {
|
|
|
116
111
|
function parseDiffStat(output) {
|
|
117
112
|
const lines = output.trim().split('\n').filter(Boolean);
|
|
118
113
|
const changedFiles = [];
|
|
119
|
-
let files = 0,
|
|
114
|
+
let files = 0,
|
|
115
|
+
insertions = 0,
|
|
116
|
+
deletions = 0;
|
|
120
117
|
|
|
121
118
|
for (const line of lines) {
|
|
122
119
|
const sm = line.match(/(\d+)\s+files?\s+changed/);
|
|
@@ -136,7 +133,7 @@ function parseDiffStat(output) {
|
|
|
136
133
|
}
|
|
137
134
|
|
|
138
135
|
function checkExistingPR() {
|
|
139
|
-
const out = exec('gh pr view --json url
|
|
136
|
+
const out = exec('gh pr view --json url');
|
|
140
137
|
return out ? { exists: true, url: out } : { exists: false };
|
|
141
138
|
}
|
|
142
139
|
|
|
@@ -187,7 +184,7 @@ create-pr.mjs — PR 上下文收集与创建
|
|
|
187
184
|
}
|
|
188
185
|
|
|
189
186
|
const branch = exec('git branch --show-current');
|
|
190
|
-
const pushOut = exec(`git push -u origin ${branch}
|
|
187
|
+
const pushOut = exec(`git push -u origin ${branch}`);
|
|
191
188
|
if (!pushOut) {
|
|
192
189
|
console.error('git push 失败');
|
|
193
190
|
process.exit(1);
|
|
@@ -197,17 +194,22 @@ create-pr.mjs — PR 上下文收集与创建
|
|
|
197
194
|
title: process.argv[titleArg + 1],
|
|
198
195
|
body: process.argv[bodyArg + 1],
|
|
199
196
|
branch,
|
|
200
|
-
reviewer: reviewerArg >= 0
|
|
201
|
-
? process.argv[reviewerArg + 1] : null,
|
|
197
|
+
reviewer: reviewerArg >= 0 ? process.argv[reviewerArg + 1] : null,
|
|
202
198
|
label: labelArg >= 0 ? process.argv[labelArg + 1] : null,
|
|
203
199
|
draft: isDraft,
|
|
204
200
|
});
|
|
205
201
|
|
|
206
202
|
const out = exec(cmd);
|
|
207
|
-
process.stdout.write(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
203
|
+
process.stdout.write(
|
|
204
|
+
JSON.stringify(
|
|
205
|
+
{
|
|
206
|
+
created: true,
|
|
207
|
+
url: out,
|
|
208
|
+
},
|
|
209
|
+
null,
|
|
210
|
+
2,
|
|
211
|
+
) + '\n',
|
|
212
|
+
);
|
|
211
213
|
process.exit(0);
|
|
212
214
|
}
|
|
213
215
|
|
|
@@ -116,12 +116,12 @@ scope-check:
|
|
|
116
116
|
|
|
117
117
|
## 环境变量
|
|
118
118
|
|
|
119
|
-
| 变量
|
|
120
|
-
|
|
121
|
-
| `ANTHROPIC_API_KEY` | —
|
|
122
|
-
| `OPENAI_API_KEY`
|
|
123
|
-
| `LLM_MODEL`
|
|
124
|
-
| `MAX_DIFF_CHARS`
|
|
119
|
+
| 变量 | 默认值 | 说明 |
|
|
120
|
+
| ------------------- | -------------------------- | -------------------------- |
|
|
121
|
+
| `ANTHROPIC_API_KEY` | — | Claude API Key(优先使用) |
|
|
122
|
+
| `OPENAI_API_KEY` | — | OpenAI API Key(备选) |
|
|
123
|
+
| `LLM_MODEL` | `claude-sonnet-4-20250514` | 使用的模型 |
|
|
124
|
+
| `MAX_DIFF_CHARS` | 20000 | diff 截断字符数 |
|
|
125
125
|
|
|
126
126
|
## 常见问题
|
|
127
127
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
> **⚠️ 本文件已被 `SKILL.md.tmpl` 中的 TDD(Red → Green → Refactor)实现流程替代。**
|
|
4
4
|
>
|
|
5
5
|
> 原阶段五(现阶段四)的子代理 A→E 编码循环已移除,替换为:
|
|
6
|
+
>
|
|
6
7
|
> - 逐 task TDD 循环(RED → GREEN → REFACTOR)
|
|
7
8
|
> - 纯配置/文档/SKILL.md 豁免 TDD
|
|
8
9
|
> - 详见 SKILL.md.tmpl 的「阶段四:TDD 实现」
|
|
@@ -11,7 +12,6 @@
|
|
|
11
12
|
|
|
12
13
|
---
|
|
13
14
|
|
|
14
|
-
|
|
15
15
|
## 步骤 A:构造子代理 prompt
|
|
16
16
|
|
|
17
17
|
组合以下上下文发送给子代理:
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
|
|
33
33
|
使用 `Agent` 工具(type: `"general-purpose"`),prompt 为步骤 A 构造的内容。
|
|
34
34
|
|
|
35
|
-
| 返回状态
|
|
36
|
-
|
|
37
|
-
| **DONE**
|
|
38
|
-
| **DONE_WITH_CONCERNS** | 阅读疑虑。涉及正确性则先修复;仅观察则记录后继续
|
|
39
|
-
| **NEEDS_CONTEXT**
|
|
40
|
-
| **BLOCKED**
|
|
35
|
+
| 返回状态 | 处理 |
|
|
36
|
+
| ---------------------- | ----------------------------------------------------- |
|
|
37
|
+
| **DONE** | 继续步骤 C |
|
|
38
|
+
| **DONE_WITH_CONCERNS** | 阅读疑虑。涉及正确性则先修复;仅观察则记录后继续 |
|
|
39
|
+
| **NEEDS_CONTEXT** | 补充上下文后重新派遣 |
|
|
40
|
+
| **BLOCKED** | context 不足→补充;task 过大→拆分;plan 错误→告知用户 |
|
|
41
41
|
|
|
42
42
|
## 步骤 C:Spec 合规审查
|
|
43
43
|
|
|
@@ -6,22 +6,22 @@
|
|
|
6
6
|
|
|
7
7
|
## 风险因子 → Mode 对照表
|
|
8
8
|
|
|
9
|
-
| 变更类型
|
|
10
|
-
|
|
11
|
-
| 文档修改
|
|
12
|
-
| 配置文件
|
|
13
|
-
| SKILL.md / 流程文档
|
|
14
|
-
| 测试框架基础设施搭建
|
|
15
|
-
| 简单重构(测试覆盖充分) | 提取函数、重命名、移动文件
|
|
16
|
-
| 简单重构(测试覆盖不足) | 同上但测试覆盖 < 80%
|
|
17
|
-
| 新增业务逻辑
|
|
18
|
-
| Bug 修复
|
|
19
|
-
| 权限 / 安全变更
|
|
20
|
-
| 资金 / 计费变更
|
|
21
|
-
| 幂等性 / 数据库迁移
|
|
22
|
-
| 状态机逻辑
|
|
23
|
-
| 并发 / 异步逻辑
|
|
24
|
-
| 不确定风险等级
|
|
9
|
+
| 变更类型 | 示例 | 推荐 Mode | 依据 |
|
|
10
|
+
| ------------------------ | -------------------------------------- | ------------- | ------------------------------------ |
|
|
11
|
+
| 文档修改 | `.md` 文件内容调整、注释修改 | **plan** | 无行为逻辑,直接可验证 |
|
|
12
|
+
| 配置文件 | `.json` / `.yaml` / `.toml` 配置项调整 | **plan** | 结构确定,验证成本低 |
|
|
13
|
+
| SKILL.md / 流程文档 | 流程描述修改、检查清单增删 | **plan** | 纯文档,无运行时行为 |
|
|
14
|
+
| 测试框架基础设施搭建 | 初始化 vitest / jest / pytest 配置 | **plan** | 脚手架性质,无业务逻辑 |
|
|
15
|
+
| 简单重构(测试覆盖充分) | 提取函数、重命名、移动文件 | **plan** | 已有测试覆盖(>80%)可验证 |
|
|
16
|
+
| 简单重构(测试覆盖不足) | 同上但测试覆盖 < 80% | **tdd** | 需先补测试再重构 |
|
|
17
|
+
| 新增业务逻辑 | Controller / Service / Repository 新增 | **tdd** | 行为变更需先写测试 |
|
|
18
|
+
| Bug 修复 | 功能缺陷修复 | **tdd** | 先写回归测试再修复 |
|
|
19
|
+
| 权限 / 安全变更 | 权限校验、鉴权逻辑、数据脱敏 | **tdd** | 高风险,需完整测试覆盖 |
|
|
20
|
+
| 资金 / 计费变更 | 金额计算、支付流程、账单生成 | **tdd** | 高风险,需完整测试覆盖,标记高优先级 |
|
|
21
|
+
| 幂等性 / 数据库迁移 | 数据库脚本、数据迁移、重入逻辑 | **tdd** | 幂等性需严格验证 |
|
|
22
|
+
| 状态机逻辑 | 状态流转、事件驱动 | **tdd** | 状态组合复杂,需全覆盖 |
|
|
23
|
+
| 并发 / 异步逻辑 | 线程、协程、消息队列消费 | **tdd** | 竞态条件需测试验证 |
|
|
24
|
+
| 不确定风险等级 | 无法明确归类 | **默认 auto** | Agent 推荐后人工确认 |
|
|
25
25
|
|
|
26
26
|
## Plan Mode 决定性特征
|
|
27
27
|
|
|
@@ -36,15 +36,15 @@
|
|
|
36
36
|
|
|
37
37
|
## Plan vs TDD 执行策略差异表
|
|
38
38
|
|
|
39
|
-
| 维度
|
|
40
|
-
|
|
41
|
-
| **实现前**
|
|
42
|
-
| **实现中**
|
|
43
|
-
| **后置验证**
|
|
44
|
-
| **验证失败处理** | 修复后重新验证,通过才标完成
|
|
45
|
-
| **测试编写**
|
|
46
|
-
| **代码审查**
|
|
47
|
-
| **复杂度超预期** | 主动升级为 tdd mode
|
|
39
|
+
| 维度 | Plan Mode | TDD Mode |
|
|
40
|
+
| ---------------- | -------------------------------- | ----------------------------- |
|
|
41
|
+
| **实现前** | 直接实现 | 🔴 先写测试(RED) |
|
|
42
|
+
| **实现中** | 持续关注复杂度超预期信号 | 🟢 写最小实现代码 |
|
|
43
|
+
| **后置验证** | build → lint → test **必须全过** | 🔵 重构 → build → lint → test |
|
|
44
|
+
| **验证失败处理** | 修复后重新验证,通过才标完成 | 同左 |
|
|
45
|
+
| **测试编写** | 后置验证阶段不要求新测试 | 前置 RED 阶段已完成 |
|
|
46
|
+
| **代码审查** | 同标准 code-audit | 同标准 code-audit |
|
|
47
|
+
| **复杂度超预期** | 主动升级为 tdd mode | 不允许降级 |
|
|
48
48
|
|
|
49
49
|
## 模式选择规则
|
|
50
50
|
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
Agent 在 plan mode 实现过程中,如发现变更复杂度超出预期(涉及多模块联动、边界条件复杂、异常路径多),**SHALL 主动暂停**,向用户声明并建议升级为 tdd mode。用户确认后方可切换。
|
|
54
54
|
|
|
55
55
|
**升级信号:**
|
|
56
|
+
|
|
56
57
|
- 实现时发现需要修改 3+ 个模块
|
|
57
58
|
- 发现隐藏的边界条件或并发问题
|
|
58
59
|
- 发现现有测试覆盖率不足且无法目视确认正确性
|
|
@@ -63,6 +64,7 @@ Agent 在 plan mode 实现过程中,如发现变更复杂度超出预期(涉
|
|
|
63
64
|
一旦 superpowers 门禁判定为 tdd mode,Agent **SHALL NOT** 以任何理由降级为 plan mode。即使实现过程中发现变更比预期简单,也必须完成完整的 RED→GREEN→REFACTOR 循环。
|
|
64
65
|
|
|
65
66
|
**常见违规场景(禁止):**
|
|
67
|
+
|
|
66
68
|
- "这个 task 其实很简单,直接改吧" → ❌ 违规
|
|
67
69
|
- "测试已经覆盖了,不写新测试直接改" → ❌ 违规(对于 tdd mode task)
|
|
68
70
|
- "现在补测试太慢,先改后面再补" → ❌ 违规
|
|
@@ -70,6 +72,7 @@ Agent 在 plan mode 实现过程中,如发现变更复杂度超出预期(涉
|
|
|
70
72
|
### 规则 3:默认 auto 模式
|
|
71
73
|
|
|
72
74
|
风险路由**默认自动推荐**。Agent 在 superpowers 门禁中:
|
|
75
|
+
|
|
73
76
|
1. 根据变更类型和风险因子,输出风险判断表 + 推荐模式 + 推荐理由
|
|
74
77
|
2. **等待用户确认后**,方可进入阶段四
|
|
75
78
|
|