@namewta/speculo 0.1.0
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/LICENSE +21 -0
- package/README.md +89 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +58 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.js +60 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/utils.d.ts +1 -0
- package/dist/src/utils.js +11 -0
- package/dist/src/utils.js.map +1 -0
- package/package.json +54 -0
- package/speculo/.speculo/.config/LESSONS.md +9 -0
- package/speculo/.speculo/.config/RULES.md +9 -0
- package/speculo/.speculo/.config/adr/.gitkeep +1 -0
- package/speculo/.speculo/.config/context/.gitkeep +1 -0
- package/speculo/.speculo/archive/dev/.gitkeep +0 -0
- package/speculo/.speculo/archive/doc/.gitkeep +1 -0
- package/speculo/.speculo/commands/.gitkeep +0 -0
- package/speculo/.speculo/dev/.gitkeep +0 -0
- package/speculo/.speculo/dev/docs-sync-state.json +14 -0
- package/speculo/.speculo/dev-status.json +3 -0
- package/speculo/.speculo/doc/.gitkeep +1 -0
- package/speculo/.speculo/doc-status.json +3 -0
- package/speculo/commands/archive.md +53 -0
- package/speculo/commands/caveman.md +43 -0
- package/speculo/commands/grill-me.md +42 -0
- package/speculo/commands/handoff.md +42 -0
- package/speculo/commands/scaffold-exercises.md +50 -0
- package/speculo/commands/status.md +51 -0
- package/speculo/commands/write-a-skill.md +46 -0
- package/speculo/skills/caveman/SKILL.md +38 -0
- package/speculo/skills/caveman/references/compression-rules.md +102 -0
- package/speculo/skills/github-npm-ops/SKILL.md +53 -0
- package/speculo/skills/github-npm-ops/references/ci-and-security-ops.md +178 -0
- package/speculo/skills/github-npm-ops/references/failure-recovery.md +132 -0
- package/speculo/skills/github-npm-ops/references/issue-pr-triage.md +219 -0
- package/speculo/skills/github-npm-ops/references/package-json-checklist.md +171 -0
- package/speculo/skills/github-npm-ops/references/preflight-checklist.md +39 -0
- package/speculo/skills/github-npm-ops/references/publish-detection.md +68 -0
- package/speculo/skills/github-npm-ops/references/release-notes-injection.md +236 -0
- package/speculo/skills/github-npm-ops/references/release-pipeline.md +108 -0
- package/speculo/skills/github-npm-ops/references/setup-npm-token.md +63 -0
- package/speculo/skills/github-npm-ops/references/troubleshooting-playbook.md +305 -0
- package/speculo/skills/github-npm-ops/references/version-bump-flow.md +232 -0
- package/speculo/skills/github-npm-ops/references/workflow-yaml-reference.md +268 -0
- package/speculo/skills/grill-me/SKILL.md +40 -0
- package/speculo/skills/handoff/SKILL.md +41 -0
- package/speculo/skills/scaffold-exercises/SKILL.md +41 -0
- package/speculo/skills/scaffold-exercises/references/exercise-structure.md +85 -0
- package/speculo/skills/scaffold-exercises/references/lint-and-git.md +54 -0
- package/speculo/skills/speculo-write/SKILL.md +53 -0
- package/speculo/skills/speculo-write/references/asset-selection-sop.md +65 -0
- package/speculo/skills/speculo-write/references/command-authoring-sop.md +92 -0
- package/speculo/skills/speculo-write/references/migration-sop.md +101 -0
- package/speculo/skills/speculo-write/references/persistence-contract-sop.md +123 -0
- package/speculo/skills/speculo-write/references/skill-authoring-sop.md +195 -0
- package/speculo/skills/speculo-write/references/validation-checklist.md +73 -0
- package/speculo/skills/speculo-write/references/workflow-authoring-sop.md +130 -0
- package/speculo/workflows/dev/00-INDEX.md +56 -0
- package/speculo/workflows/dev/01-grill-with-docs/01-grill-with-docs.md +79 -0
- package/speculo/workflows/dev/01-grill-with-docs/ADR-FORMAT.md +49 -0
- package/speculo/workflows/dev/01-grill-with-docs/CONTEXT-FORMAT.md +65 -0
- package/speculo/workflows/dev/01-grill-with-docs/grill-context-scan.md +30 -0
- package/speculo/workflows/dev/01-grill-with-docs/grill-decision.md +38 -0
- package/speculo/workflows/dev/02-prd/02-prd.md +64 -0
- package/speculo/workflows/dev/02-prd/prd-synthesis.md +30 -0
- package/speculo/workflows/dev/02-prd/prd-zoom-out.md +29 -0
- package/speculo/workflows/dev/03-tdd/03-tdd.md +80 -0
- package/speculo/workflows/dev/03-tdd/deep-modules.md +33 -0
- package/speculo/workflows/dev/03-tdd/interface-design.md +31 -0
- package/speculo/workflows/dev/03-tdd/mocking.md +60 -0
- package/speculo/workflows/dev/03-tdd/refactoring.md +10 -0
- package/speculo/workflows/dev/03-tdd/tdd-finish.md +28 -0
- package/speculo/workflows/dev/03-tdd/tdd-loop.md +33 -0
- package/speculo/workflows/dev/03-tdd/tdd-plan.md +30 -0
- package/speculo/workflows/dev/03-tdd/tests.md +61 -0
- package/speculo/workflows/dev/D-docs-sync/D-docs-sync.md +97 -0
- package/speculo/workflows/dev/D-docs-sync/agents-contract.md +95 -0
- package/speculo/workflows/dev/D-docs-sync/changelog-contract.md +155 -0
- package/speculo/workflows/dev/D-docs-sync/docs-sync-diff.md +50 -0
- package/speculo/workflows/dev/D-docs-sync/docs-sync-finish.md +33 -0
- package/speculo/workflows/dev/D-docs-sync/docs-sync-state.md +32 -0
- package/speculo/workflows/dev/D-docs-sync/docs-sync-update.md +35 -0
- package/speculo/workflows/dev/D-docs-sync/readme-contract.md +124 -0
- package/speculo/workflows/dev/D-docs-sync/state-json-schema.md +155 -0
- package/speculo/workflows/dev/H-diagnose/H-diagnose.md +80 -0
- package/speculo/workflows/dev/H-diagnose/diagnose-fix.md +34 -0
- package/speculo/workflows/dev/H-diagnose/diagnose-guide.md +114 -0
- package/speculo/workflows/dev/H-diagnose/diagnose-loop.md +32 -0
- package/speculo/workflows/dev/H-diagnose/scripts/hitl-loop.template.sh +41 -0
- package/speculo/workflows/dev/I-to-issues/I-to-issues.md +70 -0
- package/speculo/workflows/dev/I-to-issues/issues-slices.md +31 -0
- package/speculo/workflows/dev/R-review/R-review.md +82 -0
- package/speculo/workflows/dev/R-review/review-setup.md +39 -0
- package/speculo/workflows/dev/R-review/review-two-axis.md +33 -0
- package/speculo/workflows/dev/_templates/diagnosis-template.md +19 -0
- package/speculo/workflows/dev/_templates/docs-sync-report-template.md +28 -0
- package/speculo/workflows/dev/_templates/docs-sync-state-template.json +14 -0
- package/speculo/workflows/dev/_templates/grill-context-map-template.md +19 -0
- package/speculo/workflows/dev/_templates/grill-decision-log-template.md +19 -0
- package/speculo/workflows/dev/_templates/issues-slices-template.md +19 -0
- package/speculo/workflows/dev/_templates/prd-overview-template.md +19 -0
- package/speculo/workflows/dev/_templates/prd-template.md +25 -0
- package/speculo/workflows/dev/_templates/regression-template.md +19 -0
- package/speculo/workflows/dev/_templates/review-report-template.md +16 -0
- package/speculo/workflows/dev/_templates/review-sources-template.md +24 -0
- package/speculo/workflows/dev/_templates/tdd-log-template.md +16 -0
- package/speculo/workflows/dev/_templates/tdd-plan-template.md +19 -0
- package/speculo/workflows/dev/_templates/tdd-verification-template.md +16 -0
- package/speculo/workflows/doc/00-INDEX.md +51 -0
- package/speculo/workflows/doc/B-writing-beats/B-writing-beats.md +77 -0
- package/speculo/workflows/doc/B-writing-beats/writing-beats-append.md +31 -0
- package/speculo/workflows/doc/B-writing-beats/writing-beats-options.md +29 -0
- package/speculo/workflows/doc/E-edit-article/E-edit-article.md +77 -0
- package/speculo/workflows/doc/E-edit-article/edit-article-plan.md +30 -0
- package/speculo/workflows/doc/E-edit-article/edit-article-rewrite.md +31 -0
- package/speculo/workflows/doc/F-writing-fragments/F-writing-fragments.md +78 -0
- package/speculo/workflows/doc/F-writing-fragments/writing-fragments-interview.md +32 -0
- package/speculo/workflows/doc/F-writing-fragments/writing-fragments-log.md +29 -0
- package/speculo/workflows/doc/S-writing-shape/S-writing-shape.md +79 -0
- package/speculo/workflows/doc/S-writing-shape/writing-shape-block.md +32 -0
- package/speculo/workflows/doc/S-writing-shape/writing-shape-opening.md +27 -0
- package/speculo/workflows/doc/_templates/edit-article-plan-template.md +24 -0
- package/speculo/workflows/doc/_templates/edit-article-template.md +6 -0
- package/speculo/workflows/doc/_templates/writing-article-template.md +6 -0
- package/speculo/workflows/doc/_templates/writing-beat-options-template.md +20 -0
- package/speculo/workflows/doc/_templates/writing-fragments-template.md +6 -0
- package/speculo/workflows/doc/_templates/writing-interview-log-template.md +20 -0
- package/speculo/workflows/doc/_templates/writing-shape-log-template.md +24 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# 深模块
|
|
2
|
+
|
|
3
|
+
来自《A Philosophy of Software Design》:
|
|
4
|
+
|
|
5
|
+
**深模块** = 小接口 + 大量实现
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌─────────────────────┐
|
|
9
|
+
│ 小接口 │ ← 方法少,参数简单
|
|
10
|
+
├─────────────────────┤
|
|
11
|
+
│ │
|
|
12
|
+
│ │
|
|
13
|
+
│ 深层实现 │ ← 复杂逻辑被隐藏
|
|
14
|
+
│ │
|
|
15
|
+
│ │
|
|
16
|
+
└─────────────────────┘
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**浅模块** = 大接口 + 很少实现(应避免)
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
┌─────────────────────────────────┐
|
|
23
|
+
│ 大接口 │ ← 方法多,参数复杂
|
|
24
|
+
├─────────────────────────────────┤
|
|
25
|
+
│ 薄实现 │ ← 只是透传
|
|
26
|
+
└─────────────────────────────────┘
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
设计接口时,问自己:
|
|
30
|
+
|
|
31
|
+
- 能否减少方法数量?
|
|
32
|
+
- 能否简化参数?
|
|
33
|
+
- 能否把更多复杂性隐藏在里面?
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 面向可测试性的接口设计
|
|
2
|
+
|
|
3
|
+
好的接口让测试变得自然:
|
|
4
|
+
|
|
5
|
+
1. **接受依赖,而不是自己创建**
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// 易于测试
|
|
9
|
+
function processOrder(order, paymentGateway) {}
|
|
10
|
+
|
|
11
|
+
// 难以测试
|
|
12
|
+
function processOrder(order) {
|
|
13
|
+
const gateway = new StripeGateway();
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
2. **返回结果,而不是产生副作用**
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// 易于测试
|
|
21
|
+
function calculateDiscount(cart): Discount {}
|
|
22
|
+
|
|
23
|
+
// 难以测试
|
|
24
|
+
function applyDiscount(cart): void {
|
|
25
|
+
cart.total -= discount;
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
3. **小表面积**
|
|
30
|
+
- 方法越少 = 需要的测试越少
|
|
31
|
+
- 参数越少 = 测试准备越简单
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# 何时使用 Mock
|
|
2
|
+
|
|
3
|
+
只在**系统边界**处 mock:
|
|
4
|
+
|
|
5
|
+
- 外部 API(支付、邮件等)
|
|
6
|
+
- 数据库(有时——优先考虑测试数据库)
|
|
7
|
+
- 时间/随机性
|
|
8
|
+
- 文件系统(有时)
|
|
9
|
+
|
|
10
|
+
不要 mock:
|
|
11
|
+
|
|
12
|
+
- 你自己的类/模块
|
|
13
|
+
- 内部协作者
|
|
14
|
+
- 任何你能控制的东西
|
|
15
|
+
|
|
16
|
+
## 为可 Mock 性设计
|
|
17
|
+
|
|
18
|
+
在系统边界处,设计易于 mock 的接口:
|
|
19
|
+
|
|
20
|
+
**1. 使用依赖注入**
|
|
21
|
+
|
|
22
|
+
将外部依赖传入,而不是在内部创建:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// 易于 mock
|
|
26
|
+
function processPayment(order, paymentClient) {
|
|
27
|
+
return paymentClient.charge(order.total);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 难以 mock
|
|
31
|
+
function processPayment(order) {
|
|
32
|
+
const client = new StripeClient(process.env.STRIPE_KEY);
|
|
33
|
+
return client.charge(order.total);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**2. 优先使用 SDK 风格的接口,而非通用 fetcher**
|
|
38
|
+
|
|
39
|
+
为每个外部操作创建专用函数,而不是一个带条件逻辑的通用函数:
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
// 好:每个函数都可以独立 mock
|
|
43
|
+
const api = {
|
|
44
|
+
getUser: (id) => fetch(`/users/${id}`),
|
|
45
|
+
getOrders: (userId) => fetch(`/users/${userId}/orders`),
|
|
46
|
+
createOrder: (data) => fetch('/orders', { method: 'POST', body: data }),
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// 坏:mock 时需要在内部写条件逻辑
|
|
50
|
+
const api = {
|
|
51
|
+
fetch: (endpoint, options) => fetch(endpoint, options),
|
|
52
|
+
};
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
SDK 方式意味着:
|
|
56
|
+
|
|
57
|
+
- 每个 mock 返回一种特定的数据结构
|
|
58
|
+
- 测试准备中不需要条件逻辑
|
|
59
|
+
- 更容易看出测试覆盖了哪些端点
|
|
60
|
+
- 每个端点都有类型安全
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Finish Phase
|
|
2
|
+
|
|
3
|
+
## 输入
|
|
4
|
+
|
|
5
|
+
- `implementation-log.md`
|
|
6
|
+
- 项目验证命令和变更 diff
|
|
7
|
+
- `03-tdd.md` 中的内置 TDD 指引和同目录 `refactoring.md`
|
|
8
|
+
|
|
9
|
+
## 产物
|
|
10
|
+
|
|
11
|
+
- `.speculo/dev/<change>/verification.md`,由 `../_templates/tdd-verification-template.md` 填写
|
|
12
|
+
|
|
13
|
+
## 填写引导
|
|
14
|
+
|
|
15
|
+
1. 运行与变更相关的测试、类型检查、lint 或构建命令。
|
|
16
|
+
2. 记录无法运行的命令和阻塞原因。
|
|
17
|
+
3. 搜索临时调试标记、一次性脚本和推测性实现。
|
|
18
|
+
4. 如有可沉淀经验,记录在 `verification.md` 的后续建议中;在用户允许或项目规则允许时追加到 `.speculo/.config/LESSONS.md`。
|
|
19
|
+
|
|
20
|
+
## 边界
|
|
21
|
+
|
|
22
|
+
- 不自动归档 change;归档由 `commands/archive.md` 负责。
|
|
23
|
+
- 不修改 `.speculo/.config/RULES.md` 或用户未明确授权的项目规则文档。
|
|
24
|
+
|
|
25
|
+
## 完成准则
|
|
26
|
+
|
|
27
|
+
- `verification.md` 无残留 `[TODO:]`
|
|
28
|
+
- `.status.json` 的 `implementation_status` 为 `verified` 或 `blocked`
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Slice Loop Phase
|
|
2
|
+
|
|
3
|
+
## 输入
|
|
4
|
+
|
|
5
|
+
- `tdd-plan.md`
|
|
6
|
+
- `slices.md` 或用户确认的切片顺序
|
|
7
|
+
- `03-tdd.md` 中的内置 TDD 指引和同目录辅助文档
|
|
8
|
+
|
|
9
|
+
## 产物
|
|
10
|
+
|
|
11
|
+
- `.speculo/dev/<change>/implementation-log.md`,由 `../_templates/tdd-log-template.md` 填写
|
|
12
|
+
- 可选:`tasks/00-INDEX.md` 与 `tasks/TNN.md`,由 workflow 自治创建
|
|
13
|
+
|
|
14
|
+
## 填写引导
|
|
15
|
+
|
|
16
|
+
1. 每次只选择一个切片和一个行为。
|
|
17
|
+
2. RED:写一个通过公共接口验证行为的失败测试。
|
|
18
|
+
3. GREEN:写最少实现使当前测试通过。
|
|
19
|
+
4. REFACTOR:只在绿色状态下整理设计。
|
|
20
|
+
5. 每轮记录测试名、失败信号、实现摘要、重构摘要和验证命令。
|
|
21
|
+
6. 每轮检查:测试描述行为而非实现;测试只使用公共接口;测试能经受内部重构;代码是当前测试的最少实现;没有添加推测性功能。
|
|
22
|
+
|
|
23
|
+
## 边界
|
|
24
|
+
|
|
25
|
+
- 不预实现未来切片。
|
|
26
|
+
- 不使用内部实现细节作为主要断言。
|
|
27
|
+
- 不在 RED 状态下重构。
|
|
28
|
+
|
|
29
|
+
## 完成准则
|
|
30
|
+
|
|
31
|
+
- 每个完成切片都有 RED/GREEN/REFACTOR 记录
|
|
32
|
+
- `implementation-log.md` 无残留 `[TODO:]`
|
|
33
|
+
- `.status.json` 已追加 `red_green_refactor_cycles`
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# TDD Plan Phase
|
|
2
|
+
|
|
3
|
+
## 输入
|
|
4
|
+
|
|
5
|
+
- `prd.md`、`slices.md`、`diagnosis.md` 或用户明确任务
|
|
6
|
+
- 项目测试命令、现有测试样式和公共接口
|
|
7
|
+
- `03-tdd.md` 中的内置 TDD 指引和同目录辅助文档
|
|
8
|
+
|
|
9
|
+
## 产物
|
|
10
|
+
|
|
11
|
+
- `.speculo/dev/<change>/tdd-plan.md`,由 `../_templates/tdd-plan-template.md` 填写
|
|
12
|
+
|
|
13
|
+
## 填写引导
|
|
14
|
+
|
|
15
|
+
1. 遵循 `03-tdd.md` 的内置 TDD 指引。
|
|
16
|
+
2. 按需读取同目录的接口设计、测试、mock 和 deep module 文档。
|
|
17
|
+
3. 与用户确认公共接口、最重要的行为和测试覆盖优先级。
|
|
18
|
+
4. 拆出第一个 tracing slice,避免水平切片。
|
|
19
|
+
5. 探索代码库时使用项目领域术语表,确保测试名称和接口词汇与项目语言一致,并尊重触及区域的 ADR。
|
|
20
|
+
6. 写任何代码前确认接口变更、优先测试的行为、deep module 机会、可测试接口设计和行为列表。
|
|
21
|
+
|
|
22
|
+
## 边界
|
|
23
|
+
|
|
24
|
+
- 本阶段不写代码。
|
|
25
|
+
- 不批量预写所有测试。
|
|
26
|
+
|
|
27
|
+
## 完成准则
|
|
28
|
+
|
|
29
|
+
- `tdd-plan.md` 无残留 `[TODO:]`
|
|
30
|
+
- `.status.json` 的 `implementation_status` 为 `planned`
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# 好测试与坏测试
|
|
2
|
+
|
|
3
|
+
## 好测试
|
|
4
|
+
|
|
5
|
+
**集成式**:通过真实接口测试,而不是 mock 内部组件。
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// 好:测试可观察的行为
|
|
9
|
+
test("用户可以用有效购物车结算", async () => {
|
|
10
|
+
const cart = createCart();
|
|
11
|
+
cart.add(product);
|
|
12
|
+
const result = await checkout(cart, paymentMethod);
|
|
13
|
+
expect(result.status).toBe("confirmed");
|
|
14
|
+
});
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
特征:
|
|
18
|
+
|
|
19
|
+
- 测试用户/调用者关心的行为
|
|
20
|
+
- 只使用公共 API
|
|
21
|
+
- 能经受住内部重构
|
|
22
|
+
- 描述「做什么」,而不是「怎么做」
|
|
23
|
+
- 每个测试一个逻辑断言
|
|
24
|
+
|
|
25
|
+
## 坏测试
|
|
26
|
+
|
|
27
|
+
**实现细节测试**:与内部结构耦合。
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// 坏:测试实现细节
|
|
31
|
+
test("checkout 调用了 paymentService.process", async () => {
|
|
32
|
+
const mockPayment = jest.mock(paymentService);
|
|
33
|
+
await checkout(cart, payment);
|
|
34
|
+
expect(mockPayment.process).toHaveBeenCalledWith(cart.total);
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
危险信号:
|
|
39
|
+
|
|
40
|
+
- mock 内部协作者
|
|
41
|
+
- 测试私有方法
|
|
42
|
+
- 断言调用次数/顺序
|
|
43
|
+
- 重构时测试坏了但行为没变
|
|
44
|
+
- 测试名称描述的是「怎么做」而不是「做什么」
|
|
45
|
+
- 通过外部手段验证而不是通过接口
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// 坏:绕过接口来验证
|
|
49
|
+
test("createUser 保存到数据库", async () => {
|
|
50
|
+
await createUser({ name: "Alice" });
|
|
51
|
+
const row = await db.query("SELECT * FROM users WHERE name = ?", ["Alice"]);
|
|
52
|
+
expect(row).toBeDefined();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// 好:通过接口验证
|
|
56
|
+
test("createUser 使用户可被检索", async () => {
|
|
57
|
+
const user = await createUser({ name: "Alice" });
|
|
58
|
+
const retrieved = await getUser(user.id);
|
|
59
|
+
expect(retrieved.name).toBe("Alice");
|
|
60
|
+
});
|
|
61
|
+
```
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: dev/D-docs-sync
|
|
3
|
+
category: dev
|
|
4
|
+
name: Docs Sync
|
|
5
|
+
description: 基于 git 差异增量同步 README、CHANGELOG、AGENTS 等对外文档
|
|
6
|
+
keywords: [docs-sync, changelog, readme, agents, documentation, 文档同步]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Docs Sync 工作流执行指引
|
|
10
|
+
|
|
11
|
+
本工作流是 `dev/D` 入口,用于把一段 git 差异映射回对外文档。它只做差量同步,不从零创建文档,也不做整页重写。
|
|
12
|
+
|
|
13
|
+
## 内置指引
|
|
14
|
+
|
|
15
|
+
### Iron Law
|
|
16
|
+
|
|
17
|
+
禁止在不读取 `.speculo/dev/docs-sync-state.json` 的 `last_sync_sha` 与当前 `HEAD` 之间 diff 的情况下修改任何对外文档。
|
|
18
|
+
|
|
19
|
+
如果 diff 为空,或只有文档自身变动,直接报告无需同步或空同步,并按规则推进 state;不要触碰无关文档。
|
|
20
|
+
|
|
21
|
+
### 输入
|
|
22
|
+
|
|
23
|
+
- `.speculo/dev/docs-sync-state.json`
|
|
24
|
+
- 当前 git `HEAD`
|
|
25
|
+
- state 中的 `tracked_docs` 列表
|
|
26
|
+
- 当前 change 目录:`.speculo/dev/<change>/`
|
|
27
|
+
|
|
28
|
+
### 输出
|
|
29
|
+
|
|
30
|
+
- `.speculo/dev/<change>/docs-sync-report.md`
|
|
31
|
+
- 更新后的 tracked docs
|
|
32
|
+
- 更新后的 `.speculo/dev/docs-sync-state.json`
|
|
33
|
+
|
|
34
|
+
### 渐进披露
|
|
35
|
+
|
|
36
|
+
- `readme-contract.md`:更新 README 类文档时读取。
|
|
37
|
+
- `agents-contract.md`:更新 AGENTS / AI 代理手册类文档时读取。
|
|
38
|
+
- `changelog-contract.md`:更新 CHANGELOG 类文档时读取。
|
|
39
|
+
- `state-json-schema.md`:初始化、读取或写回 docs-sync state 时读取。
|
|
40
|
+
|
|
41
|
+
## 阶段
|
|
42
|
+
|
|
43
|
+
### 1. State Read — 读取同步状态
|
|
44
|
+
- 规范:`docs-sync-state.md`
|
|
45
|
+
- 模板:`../_templates/docs-sync-state-template.json`
|
|
46
|
+
- 产物:`.speculo/dev/docs-sync-state.json`
|
|
47
|
+
- 完成准则:
|
|
48
|
+
- 已确定 `LAST_SYNC_SHA` 和 `HEAD_SHA`
|
|
49
|
+
- 首次运行时已初始化 state 并要求用户确认 `tracked_docs`
|
|
50
|
+
|
|
51
|
+
### 2. Diff Collect — 收集 git 差异
|
|
52
|
+
- 规范:`docs-sync-diff.md`
|
|
53
|
+
- 模板:无
|
|
54
|
+
- 产物:`docs-sync-report.md`
|
|
55
|
+
- 完成准则:
|
|
56
|
+
- 已记录 git log、name-status、shortstat 和路径分组
|
|
57
|
+
- 已判断是否需要修改文档
|
|
58
|
+
|
|
59
|
+
### 3. Docs Update — 差量更新文档
|
|
60
|
+
- 规范:`docs-sync-update.md`
|
|
61
|
+
- 模板:`../_templates/docs-sync-report-template.md`
|
|
62
|
+
- 产物:`docs-sync-report.md`
|
|
63
|
+
- 完成准则:
|
|
64
|
+
- 只修改 `tracked_docs` 中需要同步的文档
|
|
65
|
+
- README / CHANGELOG / AGENTS 类文档遵守对应 contract
|
|
66
|
+
- `docs-sync-report.md` 无残留 `[TODO:]`
|
|
67
|
+
|
|
68
|
+
### 4. State Write — 验证与写回状态
|
|
69
|
+
- 规范:`docs-sync-finish.md`
|
|
70
|
+
- 模板:`../_templates/docs-sync-report-template.md`
|
|
71
|
+
- 产物:`.speculo/dev/docs-sync-state.json`
|
|
72
|
+
- 完成准则:
|
|
73
|
+
- 已运行项目级校验或记录无法运行原因
|
|
74
|
+
- state 已原子写入
|
|
75
|
+
- 已向用户报告范围、改动文档和新基线
|
|
76
|
+
|
|
77
|
+
## 依赖
|
|
78
|
+
|
|
79
|
+
- 软依赖:无
|
|
80
|
+
- 硬依赖:git 仓库;首次运行需要用户确认 `tracked_docs`
|
|
81
|
+
|
|
82
|
+
## 状态扩展字段
|
|
83
|
+
|
|
84
|
+
本工作流需在同 change 的 `.status.json` 追加:
|
|
85
|
+
|
|
86
|
+
- `dev_entry` (string) — 固定为 `dev/D`
|
|
87
|
+
- `docs_sync_state_path` (string) — 固定为 `.speculo/dev/docs-sync-state.json`
|
|
88
|
+
- `docs_sync_range` (string) — `<LAST_SYNC_SHA>..HEAD`
|
|
89
|
+
- `tracked_docs` (array) — 本次纳入同步的文档
|
|
90
|
+
- `synced_docs` (array) — 本次实际修改的文档
|
|
91
|
+
- `docs_sync_status` (first-run | no-op | updating | synced | blocked) — 同步状态
|
|
92
|
+
|
|
93
|
+
## 完成与状态更新
|
|
94
|
+
|
|
95
|
+
- 进入每个 phase 时更新 `current_phase` 和 `phase_history`。
|
|
96
|
+
- 只有验证完成后才原子写回 `.speculo/dev/docs-sync-state.json`。
|
|
97
|
+
- 本 workflow 不自动完成 change;用户要求仅同步文档时,可在报告完成后把 `change_status` 置为 `completed`。
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# AI 代理手册类文档同步契约(通用)
|
|
2
|
+
|
|
3
|
+
AI 代理手册类文档(`AGENTS.md`、`CLAUDE.md`、`.cursorrules`、`.github/copilot-instructions.md` 等)是**给 AI 代理看的工作手册**,不是给用户看的营销页。它的受众是其他 AI 代理(Claude / Cursor / Kiro / Codex / GPT / Gemini 等),内容应是高信息密度的结构化陈述。
|
|
4
|
+
|
|
5
|
+
本契约给出通用写作与同步规则;具体章节结构由项目自身现有文档决定,同步时保留既有结构做差量更新。
|
|
6
|
+
|
|
7
|
+
## 文档定位
|
|
8
|
+
|
|
9
|
+
- 不是用户文档,不需要 Quick Start 式教程
|
|
10
|
+
- 不是营销文,不需要"它多强大"
|
|
11
|
+
- 是**事实手册**:项目身份、目录布局、关键命令、扩展机制、禁止与必须
|
|
12
|
+
- 是**惯例沉淀**:代码风格、测试要求、发布约定、常见陷阱
|
|
13
|
+
|
|
14
|
+
## 典型章节
|
|
15
|
+
|
|
16
|
+
以下是 AI 代理手册中**常见**的章节;实际是否存在、顺序如何,由项目决定:
|
|
17
|
+
|
|
18
|
+
| 常见章节 | 通用同步触发条件 |
|
|
19
|
+
|---------|-----------------|
|
|
20
|
+
| 项目身份 | `package.json` / `pyproject.toml` / `Cargo.toml` 等元信息变化(name / version / runtime 约束 / license) |
|
|
21
|
+
| 核心架构 | 顶层领域模型、核心抽象、关键常量集变化 |
|
|
22
|
+
| 仓库布局 | 顶层目录树变化(新增/删除/重命名) |
|
|
23
|
+
| 开发命令 | 项目任务运行器入口变化(scripts / Makefile / justfile) |
|
|
24
|
+
| CLI / API 速查 | CLI 入口或公共 API 变化 |
|
|
25
|
+
| 扩展机制 | 钩子、插件、生命周期钩子的 public API 变化 |
|
|
26
|
+
| 代理行为规约 | 代码风格、测试要求、发布约定的策略性调整(变化频率低) |
|
|
27
|
+
| 常见陷阱 | CI 失败复盘、重构遗留约定、新成员反复犯错 |
|
|
28
|
+
| 相关文档 | 新增/删除对外文档时 |
|
|
29
|
+
|
|
30
|
+
## 仓库布局小节的同步规则
|
|
31
|
+
|
|
32
|
+
如存在"仓库布局 / Repository Layout / 目录结构"章节,它是代码树的 ASCII 快照。**每次同步**都要对照实际顶层目录:
|
|
33
|
+
|
|
34
|
+
- 列顶层目录 + 关键子目录(建议最多两层)
|
|
35
|
+
- 用 `├──` `└──` `│` 表示树形
|
|
36
|
+
- 右侧注释简短,说明"这个目录是做什么的"
|
|
37
|
+
- 新增 / 删除 / 重命名顶层目录时必须跟进
|
|
38
|
+
|
|
39
|
+
## 开发命令与 CLI 速查
|
|
40
|
+
|
|
41
|
+
- 表格形式(两列:"场景 / 命令",或三列:"命令 / 作用 / 常用标志")
|
|
42
|
+
- 命令来自项目任务运行器(`package.json#scripts` / `Makefile` / etc.)或 CLI 入口源码
|
|
43
|
+
- 新增命令 → 加一行;改名 → 改行;删除 → 删行
|
|
44
|
+
- 与 README 的 CLI Reference **同源但更简略**:README 提供完整说明,代理手册只给速查
|
|
45
|
+
|
|
46
|
+
## 扩展机制
|
|
47
|
+
|
|
48
|
+
如项目提供钩子、插件、生命周期回调等二次开发入口,对应源文件的 public API 变化时必须同步此章节。代码示例应使用**实际存在的入口**,不要虚构。
|
|
49
|
+
|
|
50
|
+
## 代理行为规约
|
|
51
|
+
|
|
52
|
+
这是最稳定的章节。调整的触发条件有限:
|
|
53
|
+
|
|
54
|
+
- 工具链升级(例如 ESLint flat config / legacy 切换、测试框架替换)
|
|
55
|
+
- 构建 / 发布流水线改造
|
|
56
|
+
- 代码风格或命名约定的全仓级调整
|
|
57
|
+
|
|
58
|
+
## 常见陷阱
|
|
59
|
+
|
|
60
|
+
每一条是一个真实踩过的坑或设计隐患。
|
|
61
|
+
|
|
62
|
+
**添加条目的时机**:
|
|
63
|
+
|
|
64
|
+
- CI 失败排查后发现某类错误反复出现
|
|
65
|
+
- 重大重构后遗留的临时约定
|
|
66
|
+
- 新团队成员或 AI 代理反复犯的同一错
|
|
67
|
+
|
|
68
|
+
**删除条目的时机**:工具链或代码结构升级消除了该陷阱。
|
|
69
|
+
|
|
70
|
+
## 相关文档
|
|
71
|
+
|
|
72
|
+
指向项目的其他对外文档(README / CHANGELOG / CONTRIBUTING / spec 目录等)。新增顶层文档(如增加 `CONTRIBUTING.md`)时同步本小节。
|
|
73
|
+
|
|
74
|
+
## 语言与风格
|
|
75
|
+
|
|
76
|
+
- 全文使用**项目主要贡献者的工作语言**(中文项目用中文,英文项目用英文)
|
|
77
|
+
- 代码实体(命令、路径、字段名、配置键、类名)保持**原文**,不翻译
|
|
78
|
+
- 列表式陈述优先于长段落
|
|
79
|
+
- 表格优先于散文
|
|
80
|
+
- 代码块优先于描述
|
|
81
|
+
- 使用硬约束语言:**禁止 / 必须 / 不得 / 强制**
|
|
82
|
+
- 避免营销语、惊叹号、表情符号
|
|
83
|
+
- 避免模糊词:"通常 / 大概 / 可能"改为具体条件
|
|
84
|
+
|
|
85
|
+
## 长度预算
|
|
86
|
+
|
|
87
|
+
建议全文控制在 500 行以内(与渐进披露 L2 阈值一致)。超过时把具体细节下沉到 `references/` 子文档并在主文档中引用。
|
|
88
|
+
|
|
89
|
+
## 不做的事
|
|
90
|
+
|
|
91
|
+
- 不复述 README 里已讲过的"它解决什么问题"
|
|
92
|
+
- 不写命令的详细 usage(`--help` 已经提供,速查表已经够)
|
|
93
|
+
- 不加 Quick Start 类步骤教程(那是 README 的工作)
|
|
94
|
+
- 不罗列借鉴项目清单(README 的致谢小节已经有了)
|
|
95
|
+
- 不做版本变更历史(那是 CHANGELOG 的工作)
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# CHANGELOG 类文档同步契约(通用)
|
|
2
|
+
|
|
3
|
+
CHANGELOG 类文档(`CHANGELOG.md`、`CHANGELOGS.md`、`HISTORY.md`、`RELEASES.md`)遵循 [Keep a Changelog 1.1.0](https://keepachangelog.com/1.1.0/) 格式与 [SemVer 2.0.0](https://semver.org/)。语言由项目决定(中/英/其他),日期建议采用 ISO 8601(UTC 或带时区偏移)。
|
|
4
|
+
|
|
5
|
+
## 文档骨架(Keep a Changelog 约定)
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
# Changelog
|
|
9
|
+
|
|
10
|
+
<简短介绍段:声明遵循 KaC + SemVer 等约定>
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## [Unreleased]
|
|
15
|
+
|
|
16
|
+
### Added / 新增
|
|
17
|
+
### Changed / 变更
|
|
18
|
+
### Deprecated / 弃用
|
|
19
|
+
### Removed / 移除
|
|
20
|
+
### Fixed / 修复
|
|
21
|
+
### Security / 安全
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## [x.y.z] — YYYY-MM-DD
|
|
26
|
+
|
|
27
|
+
<同样的分节>
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 版本链接 / Links
|
|
32
|
+
|
|
33
|
+
- [Unreleased](<compare-url>/vLATEST...HEAD)
|
|
34
|
+
- [x.y.z](<releases-url>/tag/vx.y.z)
|
|
35
|
+
- ...
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`[Unreleased]` 顶部段落**永远存在**,即使内容为空。
|
|
39
|
+
|
|
40
|
+
## 标准分节与可选扩展
|
|
41
|
+
|
|
42
|
+
**Keep a Changelog 标准 6 节**(必须用标准名,语言本地化即可):
|
|
43
|
+
|
|
44
|
+
| 标准节 | 语义 |
|
|
45
|
+
|------|------|
|
|
46
|
+
| Added / 新增 | 新功能、新命令、新模板、新技能 |
|
|
47
|
+
| Changed / 变更 | 既有能力的行为/默认值调整 |
|
|
48
|
+
| Deprecated / 弃用 | 将来会移除但本版本仍能用 |
|
|
49
|
+
| Removed / 移除 | 已从代码中删除的能力 |
|
|
50
|
+
| Fixed / 修复 | bug 修复 |
|
|
51
|
+
| Security / 安全 | 安全修复、CVE 响应、鉴权相关调整 |
|
|
52
|
+
|
|
53
|
+
**常见非标准扩展**(项目可选):
|
|
54
|
+
|
|
55
|
+
| 扩展节 | 语义 |
|
|
56
|
+
|-------|------|
|
|
57
|
+
| Planned / 计划中 | 明确声明"即将做但未动工"的事项,用于路线图沟通 |
|
|
58
|
+
| Docs / 文档 | 对外文档的更新(README / AGENTS / references 等) |
|
|
59
|
+
| Performance / 性能 | 性能优化但行为未变 |
|
|
60
|
+
| Dependencies / 依赖 | 依赖升级聚合(非 Security) |
|
|
61
|
+
|
|
62
|
+
项目一旦采用某扩展节就在整个 CHANGELOG 内一致使用,不要忽隐忽现。**没有内容的分节不要列出空标题**;保留有内容的即可。
|
|
63
|
+
|
|
64
|
+
## 把 git 变更写成 Changelog 条目
|
|
65
|
+
|
|
66
|
+
[Conventional Commits](https://www.conventionalcommits.org/) 前缀对应分节(按项目采用的 commit 约定调整):
|
|
67
|
+
|
|
68
|
+
| 前缀 | 分节 |
|
|
69
|
+
|------|------|
|
|
70
|
+
| `feat:` / `feat(...):` | Added / 新增 |
|
|
71
|
+
| `fix:` / `fix(...):` | Fixed / 修复 |
|
|
72
|
+
| `refactor:` / `perf:` | Changed / 变更(若有行为影响)或 Performance |
|
|
73
|
+
| `docs:` | Docs / 文档(如项目采用该扩展节);否则不写 |
|
|
74
|
+
| `chore:` / `ci:` / `build:` / `style:` / `test:` | 默认不写;仅在用户能感知时写入相应分节 |
|
|
75
|
+
| `revert:` | 视被 revert 的内容归类 |
|
|
76
|
+
| 依赖升级(Dependabot 等) | Security(有 CVE) / Dependencies 或 Changed(常规) |
|
|
77
|
+
|
|
78
|
+
**不要把每一个 commit 都写成一行**。聚合为"主题条目":
|
|
79
|
+
|
|
80
|
+
- 同一主题下的多个 commit → 一条 bullet,列出关键细节
|
|
81
|
+
- `chore:` 类型整批的 Dependabot 升级 → 一条"依赖周更"条目
|
|
82
|
+
- 只影响开发体验(测试配置调整、lint 规则微调)通常不进 CHANGELOG
|
|
83
|
+
|
|
84
|
+
示例(原始 commits → Changelog 条目):
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
git log
|
|
88
|
+
feat(cli): add --json flag to status command
|
|
89
|
+
fix(status): handle missing config gracefully
|
|
90
|
+
test(status): cover --json output
|
|
91
|
+
|
|
92
|
+
→ CHANGELOG 的 [Unreleased] 下:
|
|
93
|
+
### Added
|
|
94
|
+
- **CLI**:`status --json` 支持机器可读输出,缺失配置时给出空结构而非报错
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Tag 发版时的迁移
|
|
98
|
+
|
|
99
|
+
当检测到区间内发生了版本 tag(即项目元信息中的 version 变化 + 新 `v*` tag):
|
|
100
|
+
|
|
101
|
+
1. 确定 tag 创建日期:`git log -1 --format=%aI vX.Y.Z`
|
|
102
|
+
2. 把 `[Unreleased]` 下除"Planned / 计划中"外的所有条目整体移动到新版本段落 `## [X.Y.Z] — YYYY-MM-DD`
|
|
103
|
+
3. 清空 `[Unreleased]`(保留空的"Planned / 计划中"区块,如项目使用该扩展节)
|
|
104
|
+
4. 更新底部版本链接:
|
|
105
|
+
- 新增 `[X.Y.Z]` 链接行
|
|
106
|
+
- 把 `[Unreleased]` 的 compare 基线改为 `vX.Y.Z...HEAD`
|
|
107
|
+
5. 如果 tag 之后还有新 commit,按正常流程把这些 commit 写入新的 `[Unreleased]`
|
|
108
|
+
|
|
109
|
+
## 版本链接契约
|
|
110
|
+
|
|
111
|
+
底部链接段落固定结构:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
- [Unreleased](<repo>/compare/vLATEST...HEAD)
|
|
115
|
+
- [X.Y.Z](<repo>/releases/tag/vX.Y.Z)
|
|
116
|
+
- [X.Y.Z-1](...)
|
|
117
|
+
- ...
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
每发一个新版本 → 加一行;`[Unreleased]` compare 基线始终指向最新 tag。仓库 URL 由项目决定(GitHub / GitLab / Gitea / Bitbucket)。
|
|
121
|
+
|
|
122
|
+
## 条目写作规范
|
|
123
|
+
|
|
124
|
+
- 每个 bullet 以**能力名或模块名**加粗开头,如 `**CLI**:...`、`**API**:...`、`**templates**:...`、`**build**:...`、`**CI**:...`
|
|
125
|
+
- 用户视角描述"发生了什么",不描述"怎么改的"
|
|
126
|
+
- 路径、命令、标志、版本号保留代码格式(反引号)
|
|
127
|
+
- 不使用表情符号
|
|
128
|
+
- 一条 bullet 不超过两行;更长拆成子列表
|
|
129
|
+
|
|
130
|
+
## 不做的事
|
|
131
|
+
|
|
132
|
+
- **不要**重写已发布版本段落的条目措辞 —— 这些是历史档案
|
|
133
|
+
- **不要**在 `[Unreleased]` 里保留已被移入正式版本的条目
|
|
134
|
+
- **不要**反向覆盖:用 GitHub / GitLab 自动生成的 release notes 盖掉人工整理的 CHANGELOG
|
|
135
|
+
- **不要**把文档自身同步写成 `Added / Changed` —— 如项目采用"Docs / 文档"扩展节归入该节;否则不写
|
|
136
|
+
- **不要**把内部重构写成新功能
|
|
137
|
+
|
|
138
|
+
## 示例:典型同步产物
|
|
139
|
+
|
|
140
|
+
```markdown
|
|
141
|
+
## [Unreleased]
|
|
142
|
+
|
|
143
|
+
### Added
|
|
144
|
+
|
|
145
|
+
- **CLI**:`status --json` 输出机器可读状态
|
|
146
|
+
- **templates**:新增 authentication 模板,覆盖常见登录模式
|
|
147
|
+
|
|
148
|
+
### Changed
|
|
149
|
+
|
|
150
|
+
- **doctor**:`--check-deps` 在检测到未知依赖时改为 warn(原 error)
|
|
151
|
+
|
|
152
|
+
### Docs
|
|
153
|
+
|
|
154
|
+
- 新增 `.agents/skills/docs-sync/`,用于基于 git diff 同步对外文档
|
|
155
|
+
```
|