flower-trellis 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/README.md +113 -0
- package/bin/flower-trellis.js +4 -0
- package/enhancements/0.5/.agents/skills/trellis-analyze-task/SKILL.md +142 -0
- package/enhancements/0.5/.agents/skills/trellis-check-all/SKILL.md +324 -0
- package/enhancements/0.5/.agents/skills/trellis-create-command/SKILL.md +258 -0
- package/enhancements/0.5/.agents/skills/trellis-create-prd/SKILL.md +197 -0
- package/enhancements/0.5/.agents/skills/trellis-draw-uml/SKILL.md +148 -0
- package/enhancements/0.5/.agents/skills/trellis-migrate-skill/SKILL.md +216 -0
- package/enhancements/0.5/.agents/skills/trellis-plan-version/SKILL.md +140 -0
- package/enhancements/0.5/.agents/skills/trellis-push/SKILL.md +240 -0
- package/enhancements/0.5/.agents/skills/trellis-re-implement/SKILL.md +166 -0
- package/enhancements/0.5/.agents/skills/trellis-route/SKILL.md +159 -0
- package/enhancements/0.5/.agents/skills/trellis-run-full-chain/SKILL.md +402 -0
- package/enhancements/0.5/.agents/skills/trellis-sync-prd/SKILL.md +150 -0
- package/enhancements/0.5/.agents/skills/trellis-verify-prd/SKILL.md +217 -0
- package/enhancements/0.5/.claude/skills/trellis-analyze-task/SKILL.md +142 -0
- package/enhancements/0.5/.claude/skills/trellis-check-all/SKILL.md +324 -0
- package/enhancements/0.5/.claude/skills/trellis-create-command/SKILL.md +258 -0
- package/enhancements/0.5/.claude/skills/trellis-create-prd/SKILL.md +197 -0
- package/enhancements/0.5/.claude/skills/trellis-draw-uml/SKILL.md +148 -0
- package/enhancements/0.5/.claude/skills/trellis-migrate-skill/SKILL.md +216 -0
- package/enhancements/0.5/.claude/skills/trellis-plan-version/SKILL.md +140 -0
- package/enhancements/0.5/.claude/skills/trellis-push/SKILL.md +240 -0
- package/enhancements/0.5/.claude/skills/trellis-re-implement/SKILL.md +166 -0
- package/enhancements/0.5/.claude/skills/trellis-route/SKILL.md +159 -0
- package/enhancements/0.5/.claude/skills/trellis-run-full-chain/SKILL.md +402 -0
- package/enhancements/0.5/.claude/skills/trellis-sync-prd/SKILL.md +150 -0
- package/enhancements/0.5/.claude/skills/trellis-verify-prd/SKILL.md +217 -0
- package/enhancements/0.5/overrides/trellis-route.md +52 -0
- package/enhancements/0.6/.agents/skills/trellis-check-all/SKILL.md +342 -0
- package/enhancements/0.6/.agents/skills/trellis-create-command/SKILL.md +293 -0
- package/enhancements/0.6/.agents/skills/trellis-draw-uml/SKILL.md +148 -0
- package/enhancements/0.6/.agents/skills/trellis-extract-prd/SKILL.md +197 -0
- package/enhancements/0.6/.agents/skills/trellis-plan-version/SKILL.md +140 -0
- package/enhancements/0.6/.agents/skills/trellis-push/SKILL.md +316 -0
- package/enhancements/0.6/.agents/skills/trellis-route/SKILL.md +159 -0
- package/enhancements/0.6/.agents/skills/trellis-run-full-chain/SKILL.md +402 -0
- package/enhancements/0.6/.agents/skills/trellis-verify-task/SKILL.md +360 -0
- package/enhancements/0.6/.claude/skills/trellis-check-all/SKILL.md +342 -0
- package/enhancements/0.6/.claude/skills/trellis-create-command/SKILL.md +293 -0
- package/enhancements/0.6/.claude/skills/trellis-draw-uml/SKILL.md +148 -0
- package/enhancements/0.6/.claude/skills/trellis-extract-prd/SKILL.md +197 -0
- package/enhancements/0.6/.claude/skills/trellis-plan-version/SKILL.md +140 -0
- package/enhancements/0.6/.claude/skills/trellis-push/SKILL.md +316 -0
- package/enhancements/0.6/.claude/skills/trellis-route/SKILL.md +159 -0
- package/enhancements/0.6/.claude/skills/trellis-run-full-chain/SKILL.md +402 -0
- package/enhancements/0.6/.claude/skills/trellis-verify-task/SKILL.md +360 -0
- package/enhancements/0.6/overrides/workflow-states/in_progress-inline.md +5 -0
- package/enhancements/0.6/overrides/workflow-states/in_progress.md +7 -0
- package/enhancements/0.6/overrides/workflow-states/no_task.md +6 -0
- package/enhancements/0.6/overrides/workflow-states/planning.md +6 -0
- package/enhancements/0.6/overrides/workflow.md +53 -0
- package/enhancements/MANIFEST.json +109 -0
- package/enhancements/old/.agents/skills/analyze-task/SKILL.md +143 -0
- package/enhancements/old/.agents/skills/check-all/SKILL.md +128 -0
- package/enhancements/old/.agents/skills/check-impl/SKILL.md +159 -0
- package/enhancements/old/.agents/skills/check-prd/SKILL.md +219 -0
- package/enhancements/old/.agents/skills/check-prd-impl/SKILL.md +190 -0
- package/enhancements/old/.agents/skills/create-prd/SKILL.md +154 -0
- package/enhancements/old/.agents/skills/draw-uml/SKILL.md +148 -0
- package/enhancements/old/.agents/skills/plan-version/SKILL.md +140 -0
- package/enhancements/old/.agents/skills/push/SKILL.md +191 -0
- package/enhancements/old/.agents/skills/re-implement/SKILL.md +166 -0
- package/enhancements/old/.agents/skills/sync-prd/SKILL.md +146 -0
- package/enhancements/old/.claude/commands/trellis/analyze-task.md +139 -0
- package/enhancements/old/.claude/commands/trellis/check-all.md +124 -0
- package/enhancements/old/.claude/commands/trellis/check-impl.md +154 -0
- package/enhancements/old/.claude/commands/trellis/check-prd-impl.md +186 -0
- package/enhancements/old/.claude/commands/trellis/check-prd.md +215 -0
- package/enhancements/old/.claude/commands/trellis/create-prd.md +150 -0
- package/enhancements/old/.claude/commands/trellis/draw-uml.md +144 -0
- package/enhancements/old/.claude/commands/trellis/plan-version.md +136 -0
- package/enhancements/old/.claude/commands/trellis/push.md +187 -0
- package/enhancements/old/.claude/commands/trellis/re-implement.md +162 -0
- package/enhancements/old/.claude/commands/trellis/sync-prd.md +142 -0
- package/package.json +39 -0
- package/src/cli.js +151 -0
- package/src/commands/init.js +66 -0
- package/src/commands/uninstall.js +85 -0
- package/src/commands/update.js +42 -0
- package/src/constants.js +50 -0
- package/src/lib/apply-enhancements.js +133 -0
- package/src/lib/banner.js +45 -0
- package/src/lib/codex-tweaks.js +112 -0
- package/src/lib/copy-skills.js +91 -0
- package/src/lib/fs-utils.js +60 -0
- package/src/lib/legacy-blocks.js +70 -0
- package/src/lib/manifest.js +32 -0
- package/src/lib/paths.js +16 -0
- package/src/lib/pick-platforms.js +57 -0
- package/src/lib/trellis-runner.js +190 -0
- package/src/lib/variant.js +40 -0
- package/src/lib/versions.js +30 -0
- package/src/lib/workflow-inject.js +193 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: trellis-run-full-chain
|
|
3
|
+
description: "Run full-chain behavior verification across UI + API + DB — cross-layer (browser driver + HTTP client + DB client), NOT frontend-only e2e like Playwright/Cypress test suites. Input is a 场景-路径-期望 scenario table; executes each row, logs pass/fail, and restores test data when feasible. Triggers: 「跑全链路」「全链路测试」「跨层验证」「跑E2E」「端到端验证」「自动化测试场景」「跑场景测试」「e2e test」. Not for lint/unit/spec-only (use trellis-check); not for frontend-only e2e suites."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Run Full-Chain Verification — 跨层自动化验证
|
|
7
|
+
|
|
8
|
+
以"场景-路径-期望"三列表为输入,逐条跨层执行并验证:UI 驱动 + HTTP 调用 + DB 断言三种能力配合使用。最后汇总结果与**尽力而为**的数据恢复。
|
|
9
|
+
|
|
10
|
+
> **何时用**:PR 前 UAT、功能端到端验收、单测覆盖不到的跨层流程验证。
|
|
11
|
+
> **何时不用**:只跑 lint/typecheck/spec 合规(去 `trellis-check`);只做 PRD↔代码静态对照(去 `trellis-check-all`)。
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 本 skill 的定位
|
|
16
|
+
|
|
17
|
+
skill 只描述**方法论骨架**:三列表场景设计、跨层交叉验证、Toast 观测、回滚边界、偏差立停。所有 URL / header / token 键名 / 表名 / 测试账号 / 可用测试数据等 **项目特定**信息应写在项目的 E2E playbook 里(见下节)。skill 执行时优先加载它;本次运行探测/学到的新条目会在 Step 5.5 以 diff 形式提交给用户确认后回写 playbook,**下次直接复用,无需再探测**。
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 项目 Playbook(自动沉淀)
|
|
22
|
+
|
|
23
|
+
固定位置:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
.trellis/spec/guides/e2e-playbook.md
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Playbook 内容范围(**跨任务可复用的环境常量**,不含具体场景):
|
|
30
|
+
|
|
31
|
+
- **URL 模板**:前端 dev server、后端 API base、账号切换入口
|
|
32
|
+
- **Auth header 模板**:`authorization` 形式、是否需要自定义 header(如 dev-mode 开关)、token 存储键名(sessionStorage/localStorage/cookie)
|
|
33
|
+
- **测试数据指纹**:哪些项目/用户/租户可以用;哪些不能碰(生产数据、他人在用的数据)
|
|
34
|
+
- **表命名约定**:主要业务表、审计/流转日志表、幂等去重表
|
|
35
|
+
- **不可逆副作用清单**:哪些动作会触发外部通知 / 上链 / MQ 投递 / 缓存污染
|
|
36
|
+
- **常见数据重置方式**:有无 truncate-and-seed 脚本、快照恢复、savepoint 惯例
|
|
37
|
+
|
|
38
|
+
**沉淀机制**:
|
|
39
|
+
|
|
40
|
+
- **已有 playbook**:Step 0 加载;Step 0–4 执行中若发现 playbook 未记录或与实际不一致的条目,标记进"待沉淀缓存";Step 5.5 汇总成 diff 让用户确认后增量写入(**append-only 心态**,默认不删旧条目;冲突项单列供人工裁决)
|
|
41
|
+
- **无 playbook**:按通用流程探测;Step 5.5 把整份探测结果作为"全新 playbook" diff 给用户,确认后创建文件
|
|
42
|
+
|
|
43
|
+
**不纳入 playbook 的内容**(避免污染):
|
|
44
|
+
|
|
45
|
+
- 具体测试场景表、任务级一次性测试数据(如本次新建的项目 ID)、PRD 推导出的断言 — 这些留在任务目录 `.trellis/tasks/<task>/research/` 或任务报告里
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 能力矩阵(Step 0 自检用)
|
|
50
|
+
|
|
51
|
+
每一行是一种测试能力。**首选**不可用时逐级降级;**不可用时**仍应让 skill 能跑(哪怕只跑部分场景)。
|
|
52
|
+
|
|
53
|
+
| 能力 | 首选工具 | 备选 | 不可用时降级 |
|
|
54
|
+
|------|---------|------|-------------|
|
|
55
|
+
| UI 驱动 | Playwright MCP(`browser_*` 工具族) | Selenium / Puppeteer CLI;手动 Chrome DevTools 协议 | 让用户在浏览器里手点,把观察到的 toast/状态粘回对话 |
|
|
56
|
+
| HTTP 调用 | `curl` | HTTPie / Postman CLI | 让用户手调并粘贴响应 |
|
|
57
|
+
| DB 断言 | 对应数据库的 MCP(MySQL / PG / SQLite 等) | `mysql` / `psql` / `sqlite3` CLI | 让用户手查并粘贴结果;或 skill 只做 UI+API 层断言 |
|
|
58
|
+
| 抓 Auth 信息 | 浏览器里 `browser_evaluate` 读 storage / cookie | 让用户登录后手动粘贴 token | 同左 |
|
|
59
|
+
| 抓真实 header | `browser_network_requests` 观察一次真实 XHR | 浏览器 DevTools Network 截图 | 让用户粘贴任一 XHR 的请求头 |
|
|
60
|
+
|
|
61
|
+
**缺能力时的行为**:
|
|
62
|
+
- Step 0 把缺项列给用户,附推荐安装/启用方式("首选 X,可参考 <官方链接>;不装也可以用 Y 替代;完全没有时我会让你手点并把结果粘回来")
|
|
63
|
+
- 不要擅自跳过;让用户选"安装 / 降级 / 跳过该类场景"
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 执行步骤
|
|
68
|
+
|
|
69
|
+
### Step 0: 环境自检 + 加载 Playbook + 抓登录态
|
|
70
|
+
|
|
71
|
+
1. **读 playbook**(`.trellis/spec/guides/e2e-playbook.md`,若存在),拿到 URL/header/测试数据候选。同时**初始化"待沉淀缓存"**——后续 Step 0–4 探测到的"playbook 未记录的新条目 / 与 playbook 不一致的条目"都追加进来,Step 5.5 用
|
|
72
|
+
2. **能力矩阵自检**(上表),缺项时暂停
|
|
73
|
+
3. **前后端可达性**:`curl -sI <frontend-url>`、`curl -sI <backend-api-base>` — 若 URL 由探测得来(playbook 未覆盖或不一致),写入待沉淀缓存
|
|
74
|
+
4. **抓登录态 & header 模板**:通过浏览器驱动读 token(playbook 未指明则列出所有 storage keys 供识别),再触发一次真实业务 XHR,从 `browser_network_requests` 观察所需 header,作为后续 `curl` 模板。**确认后的 token 键名 / header 模板**写入待沉淀缓存
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
// 通用 token 探测(不要猜键名)
|
|
78
|
+
() => ({
|
|
79
|
+
sessionKeys: Object.keys(sessionStorage),
|
|
80
|
+
localKeys: Object.keys(localStorage),
|
|
81
|
+
cookies: document.cookie,
|
|
82
|
+
})
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Step 1: 构造/加载场景表
|
|
86
|
+
|
|
87
|
+
**首选**:用户已经整理好 "场景 / 路径 / 期望" 三列表。照抄即可。
|
|
88
|
+
|
|
89
|
+
**次选:列全候选后交用户抉择**
|
|
90
|
+
|
|
91
|
+
从任务 `prd.md` 列出**所有可端到端验证**的场景候选,来源包括但不限于:
|
|
92
|
+
|
|
93
|
+
- Goal / Requirements — 功能目标与需求项
|
|
94
|
+
- Acceptance Criteria — 验收标准(通常 1:1 映射为场景)
|
|
95
|
+
- Business Rules — 校验 / 容错 / 边界
|
|
96
|
+
- 实现决策(如 DEC 节)— 运行时有副作用的决策(数据迁移、文件生成、快照回写等)
|
|
97
|
+
- UI 交互细节 — Toast / 弹窗 / 状态流转 / 权限隐藏
|
|
98
|
+
- 跨层数据流 — 前端 → API → DB 链路
|
|
99
|
+
- 副作用点 — 外部通知 / 异步回写 / 幂等键
|
|
100
|
+
|
|
101
|
+
**不自行筛选**:不以"成本高"、"静态已验证"、"非核心"、"不好构造"为由提前裁掉候选。把所有可想到的场景都摆上桌。
|
|
102
|
+
|
|
103
|
+
输出完整场景表(模板如下)并**交用户抉择**:
|
|
104
|
+
|
|
105
|
+
| 场景 ID | 路径类型 | 操作 | 期望 |
|
|
106
|
+
|---------|---------|------|------|
|
|
107
|
+
| S1 | UI | 走页面 X → 点按钮 Y → 填 Z | 弹窗/状态/提示 A |
|
|
108
|
+
| S2 | API | POST <path> body `{...}` | 返回 code=0,DB 字段 X=Y |
|
|
109
|
+
| S3 | DB+API | 先查基线 → 调接口 → 再查 | 某字段从 X 变 Y + 新流转日志 `Z` |
|
|
110
|
+
| S4 | 跨层 | UI 触发 → 后端副作用 → DB 对账 | 所有层一致 |
|
|
111
|
+
|
|
112
|
+
每条必须有明确的**可观察信号**(UI 文案、HTTP code、DB 字段值),避免 "应该能跑"。
|
|
113
|
+
|
|
114
|
+
**可推荐**:附一份"建议跑 / 可选 / 可跳过"分级(附理由),供用户快速决策。但必须让用户明确圈选后才进 Step 2,不得替用户决定。
|
|
115
|
+
|
|
116
|
+
超过 10 条或需分批时尤其要问优先级或时间预算。
|
|
117
|
+
|
|
118
|
+
### Step 2: 识别测试数据 + 基线设计(可隔离优先)
|
|
119
|
+
|
|
120
|
+
**优先可隔离**:测试前就避免污染共享数据,而不是事后清理。依次尝试:
|
|
121
|
+
|
|
122
|
+
1. **独立测试数据 / 租户** — 用 playbook 里列出的"可用测试数据",或为本次测试新建一条专用项目/任务/用户
|
|
123
|
+
2. **事务 savepoint / rollback** — 数据库支持时(PG、支持 BEGIN 的 MySQL 会话等)
|
|
124
|
+
3. **快照恢复** — 有 sandbox/snapshot 机制的环境
|
|
125
|
+
4. **共享数据 + 手动回滚**(底线) — 前提是场景改动有限、回滚步骤清晰
|
|
126
|
+
|
|
127
|
+
对每个场景:
|
|
128
|
+
|
|
129
|
+
1. **基线快照**:从 DB 查出被测目标的当前状态(状态、计数、外键引用),作为"Before"写入对话上下文
|
|
130
|
+
2. **回滚信息**:对每个会被改动的字段,记录原值 / 原关联 ID,便于 UPDATE 回去
|
|
131
|
+
3. **不可逆副作用清单**(见下节)必须在动手前**显式列出**
|
|
132
|
+
|
|
133
|
+
#### 不可逆副作用清单(执行前必检)
|
|
134
|
+
|
|
135
|
+
场景如果可能触发以下任一,**事前告知用户**,并问清楚"是否可接受":
|
|
136
|
+
|
|
137
|
+
- 发送外部通知(邮件、IM、Webhook)
|
|
138
|
+
- 推送到 MQ / 事件总线(被其他系统消费)
|
|
139
|
+
- 写入流水账户 / 区块链 / 审计不可删表
|
|
140
|
+
- 调用第三方付费 API(短信、支付、邮件发送)
|
|
141
|
+
- 更新只读缓存的上游数据(缓存 TTL 内持续污染)
|
|
142
|
+
- 写入生产级日志存储(ELK、Datadog),不能擦除
|
|
143
|
+
|
|
144
|
+
**原则**:如果清单非空且用户未确认,不要跑该场景。
|
|
145
|
+
|
|
146
|
+
### Step 3: 逐场景执行
|
|
147
|
+
|
|
148
|
+
按 ID 顺序执行每个场景,每条遵循以下模板:
|
|
149
|
+
|
|
150
|
+
```markdown
|
|
151
|
+
#### Sx: <场景名>
|
|
152
|
+
- Path: <UI/API/DB/跨层>
|
|
153
|
+
- Pre: <基线>(从 DB 查到的 Before)
|
|
154
|
+
- Act:
|
|
155
|
+
- UI: 浏览器驱动动作(snapshot → click/type → wait)
|
|
156
|
+
- API: curl 带 header 调接口
|
|
157
|
+
- DB: 用 DB 客户端预改数据(仅当场景要求,如临时改状态模拟某前置条件)
|
|
158
|
+
- Expect:
|
|
159
|
+
- UI: 截图 / 文本快照 / Toast 观测
|
|
160
|
+
- API: 返回体 code/msg 匹配
|
|
161
|
+
- DB: 字段变化 + 审计/日志条目新增
|
|
162
|
+
- Result: ✅ / ❌ + 差异说明
|
|
163
|
+
- Restore: <必要的 UPDATE 恢复现场>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**UI 细节**:
|
|
167
|
+
|
|
168
|
+
- Toast 文案通常 2-3 秒自动消失,**别等**——先装 MutationObserver 抓文案,再触发点击:
|
|
169
|
+
|
|
170
|
+
```js
|
|
171
|
+
window.__toasts = [];
|
|
172
|
+
new MutationObserver(() => {
|
|
173
|
+
for (const el of document.querySelectorAll('*')) {
|
|
174
|
+
const t = el.textContent?.trim() || '';
|
|
175
|
+
if (t.includes('<关键字>') && t.length < 200 && el.children.length < 3) {
|
|
176
|
+
if (!window.__toasts.includes(t)) window.__toasts.push(t);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}).observe(document.body, { childList: true, subtree: true });
|
|
180
|
+
// 再触发按钮点击
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
- 下拉/autocomplete 可能依赖聚焦事件。先 click 让输入框聚焦,再 type,避免 fill 类 API 绕过 focus handler 而不触发下拉
|
|
184
|
+
|
|
185
|
+
**API 细节**:
|
|
186
|
+
|
|
187
|
+
- Header **完全对齐**前端抓到的真实请求(authorization、自定义开关头、trace ID)。401 多是 header 差一条,别去改服务端
|
|
188
|
+
- 回调/Webhook 类接口通常**不带用户 token**(外部系统身份),业务接口必须带
|
|
189
|
+
- 幂等键(requestId / externalNo / idempotency-key)**每次用新值**,否则被去重机制吞掉
|
|
190
|
+
|
|
191
|
+
**DB 细节**:
|
|
192
|
+
|
|
193
|
+
- 查询用 `SELECT ... AS <alias>` 让返回 key 可读
|
|
194
|
+
- 写 DML 前 `SELECT` 一次记录基线;写后 `SELECT` 一次对比
|
|
195
|
+
- 某些 MCP / 客户端不支持 multi-statement,**一次只发一条 SQL**
|
|
196
|
+
|
|
197
|
+
### Step 4: 发现偏差时暂停
|
|
198
|
+
|
|
199
|
+
任意一条 ❌:**立即暂停**,向用户说明:
|
|
200
|
+
|
|
201
|
+
- 场景 ID + 具体差异(文案差一个字 / 状态没变 / 日志没新增)
|
|
202
|
+
- **先排部署滞后再排代码 BUG**:若行为完全像旧代码,先核验部署版本(git hash / artifact timestamp / 健康检查版本端点),再改代码
|
|
203
|
+
- 建议下一步(改代码 / 重新部署 / 换测试数据 / 调整场景)
|
|
204
|
+
|
|
205
|
+
具体的"部署滞后"诊断命令因技术栈而异,见文末附录 B。
|
|
206
|
+
|
|
207
|
+
不要硬跑完再总结 — 早发现早暂停更省时间。
|
|
208
|
+
|
|
209
|
+
### Step 5: 尽力恢复 + 显式告知
|
|
210
|
+
|
|
211
|
+
> 回滚是**尽力而为**,不是充要条件。Step 2 的隔离设计做得越好,这一步越轻。
|
|
212
|
+
|
|
213
|
+
用前面备份的基线逐条 UPDATE 回去;结束后**再查一次**确认每条改动都复原。最终报告必须列出:
|
|
214
|
+
|
|
215
|
+
- ✅ 已恢复的改动(条数 + 影响表)
|
|
216
|
+
- ⚠️ 未能完全恢复 / 超出能力范围的项(外部通知、MQ、上链……)
|
|
217
|
+
- 🔧 用户需自行处理的善后(如通知接收方忽略测试记录)
|
|
218
|
+
|
|
219
|
+
**警告**:
|
|
220
|
+
- 别盲目 `UPDATE ... WHERE id=...` — 并发环境下别人可能已经改过,回滚反而破坏后续工作;先比对"当前值 vs 测试后值"再决定是否需要恢复
|
|
221
|
+
- 触发器 / 物化视图 / 异步 outbox 即便主表回滚,**下游可能已发出副作用**,需在报告里强调
|
|
222
|
+
|
|
223
|
+
### Step 5.5: Playbook 沉淀(diff 确认)
|
|
224
|
+
|
|
225
|
+
把 Step 0–4 收集的"待沉淀缓存"与现有 `.trellis/spec/guides/e2e-playbook.md` 做比对,以 diff 清单形式列给用户确认后再写入。**用户未确认之前不写文件。**
|
|
226
|
+
|
|
227
|
+
**diff 预览模板**:
|
|
228
|
+
|
|
229
|
+
```markdown
|
|
230
|
+
## 📒 Playbook 沉淀预览(待确认)
|
|
231
|
+
|
|
232
|
+
### ➕ 新增(playbook 无此条目)
|
|
233
|
+
- 前端 dev server: `http://localhost:5173`
|
|
234
|
+
- token 存储位置: `sessionStorage["iqs-token"]`
|
|
235
|
+
- 业务 XHR 必带 header: `authorization: Bearer …`, `x-dev-mode: 1`
|
|
236
|
+
- 流转日志表: `iqs_dispatch_log`
|
|
237
|
+
- 不可逆副作用 / 飞书审批: `POST /fs/approve` 会触发真实飞书通知
|
|
238
|
+
|
|
239
|
+
### ✏️ 变更(playbook 已有但与实测不一致)
|
|
240
|
+
- 后端 API base: `http://localhost:8080/api` → `http://localhost:8081/api`(旧值端口疑似过期)
|
|
241
|
+
|
|
242
|
+
### ⚠️ 冲突(需人工裁决,默认不写)
|
|
243
|
+
- playbook 记录 token 在 `localStorage`,本次实测在 `sessionStorage`。可能是环境差异,请判断是否覆盖
|
|
244
|
+
|
|
245
|
+
### ⏸️ 保持不变(已与 playbook 一致,仅列出确认)
|
|
246
|
+
- 测试账号列表、常见数据重置方式
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**用户回应处理**:
|
|
250
|
+
|
|
251
|
+
- ✅ 全部接受 → 写入 `.trellis/spec/guides/e2e-playbook.md`(不存在则 Write 新建;存在则对应条目用 Edit 增补/修改,**不删除旧条目**)
|
|
252
|
+
- 🟨 部分接受 → 按用户圈选的条目写入
|
|
253
|
+
- ❌ 拒绝 / 跳过 → 不写文件,仅在 Step 6 汇总里标注"N 条新发现未沉淀"
|
|
254
|
+
- **diff 为空**(playbook 已完备) → 静默跳过本步,不打扰用户
|
|
255
|
+
|
|
256
|
+
**原则**:
|
|
257
|
+
|
|
258
|
+
- 沉淀的只能是**跨任务可复用**的环境常量;**任务级一次性数据**(新建的项目 ID、本次构造的用例、临时测试凭据)**不进 playbook**
|
|
259
|
+
- 冲突项(⚠️)不擅自覆盖 — 让用户判断是环境差异还是 playbook 过期
|
|
260
|
+
- append-only 心态:旧条目只增不删;用户明确要删才动
|
|
261
|
+
|
|
262
|
+
### Step 6: 汇总报告
|
|
263
|
+
|
|
264
|
+
```markdown
|
|
265
|
+
## 🎯 E2E 测试汇总
|
|
266
|
+
|
|
267
|
+
| 场景 | 路径 | 期望 | 结果 |
|
|
268
|
+
|------|------|------|:---:|
|
|
269
|
+
| S1 | UI | ... | ✅ |
|
|
270
|
+
| S2 | API+DB | ... | ✅ |
|
|
271
|
+
| S3 | 跨层 | ... | ❌:<差异说明> |
|
|
272
|
+
|
|
273
|
+
### 覆盖统计
|
|
274
|
+
- 通过:X / 总 N
|
|
275
|
+
- 失败:Y(需修复)
|
|
276
|
+
- 跳过:Z(未具备前置条件)
|
|
277
|
+
|
|
278
|
+
### 数据影响
|
|
279
|
+
- 已恢复:<N 条 / 涉及表>
|
|
280
|
+
- 未恢复 / 不可逆:<如果有>
|
|
281
|
+
- 需用户善后:<如果有>
|
|
282
|
+
|
|
283
|
+
### Playbook 同步
|
|
284
|
+
- 写入条目:<M 条 / 文件路径>(或"N 条新发现未沉淀(用户跳过)",或"无变化")
|
|
285
|
+
- 未解决冲突:<如果有,注明待用户裁决的项>
|
|
286
|
+
|
|
287
|
+
### 建议下一步
|
|
288
|
+
- <根据失败/跳过场景的具体建议>
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## 核心原则
|
|
294
|
+
|
|
295
|
+
| 原则 | 为什么 |
|
|
296
|
+
|------|--------|
|
|
297
|
+
| **先对齐场景再动手** | "想当然测" = 白跑;文案/状态一个字都要写入期望 |
|
|
298
|
+
| **跨层交叉验证** | UI 看绿 ≠ DB 真的改了;只查 DB ≠ 用户能用 |
|
|
299
|
+
| **Header 与真实请求一致** | 401 大多是 header 差一个,不是服务端 bug |
|
|
300
|
+
| **隔离优先于回滚** | 事前设计可隔离 > 事后打扫现场 |
|
|
301
|
+
| **差异立即停** | 一条 ❌ 可能说明整批假设都错了,别继续堆无效结果 |
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## 反模式(避免)
|
|
306
|
+
|
|
307
|
+
- ❌ 浏览器驱动只截图就下结论 — 文案可能已消失 / 被 overlay 遮挡,必须文本快照或 DOM 断言
|
|
308
|
+
- ❌ Toast 断言用 `sleep + screenshot` — 2-3s 够消失的,必须 MutationObserver 实时抓
|
|
309
|
+
- ❌ 跑完忘记恢复 — 污染后续测试,特别是状态类的"临时改成 X"
|
|
310
|
+
- ❌ 幂等键重用 — 被去重机制返回 success,但实际没执行任何逻辑
|
|
311
|
+
- ❌ 发现一处失败就假设整批代码错 — 先核验部署版本,再怀疑代码
|
|
312
|
+
- ❌ 场景表里写"大致正常" / "应该能用" — 没有可观察信号就无法判定通过
|
|
313
|
+
- ❌ 把 DB 写操作塞进一个 multi-statement string — 拆开更稳
|
|
314
|
+
- ❌ 跳过 Step 0 环境自检直接点按钮 — 浪费好几轮才发现 token 失效或未登录
|
|
315
|
+
- ❌ 跳过"不可逆副作用清单"— 测完才发现发了真的飞书通知,救不回来
|
|
316
|
+
- ❌ 习惯性跳过 Step 5.5 沉淀 — playbook 永远空白,下次还得从零探测
|
|
317
|
+
- ❌ 把任务级一次性数据(新建的项目 ID / 本次才构造的用例)塞进 playbook — 污染跨任务复用,下次用错数据
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## 与其他入口的区别
|
|
322
|
+
|
|
323
|
+
| 入口 | 形态 | 用途 |
|
|
324
|
+
|------|------|------|
|
|
325
|
+
| `trellis-check` | skill | lint / typecheck / spec 规范 |
|
|
326
|
+
| `trellis-check-all` | skill | PRD→代码 静态对照 + 假设验证 |
|
|
327
|
+
| **`trellis-run-full-chain`** | skill(本技能)| **运行时行为跨层验证(UI+API+DB)** |
|
|
328
|
+
| `trellis-verify-prd` | skill | PRD↔源需求文档对账 |
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## 附录 A:通用诊断片段
|
|
333
|
+
|
|
334
|
+
### A.1 MutationObserver 抓 Toast(已在 Step 3 给出,此处为参考)
|
|
335
|
+
|
|
336
|
+
见 Step 3 "UI 细节" 段。
|
|
337
|
+
|
|
338
|
+
### A.2 Playwright 聚焦后输入
|
|
339
|
+
|
|
340
|
+
```js
|
|
341
|
+
// 错:fill 可能绕过 focus handler
|
|
342
|
+
// await page.fill('#autocomplete', 'keyword');
|
|
343
|
+
|
|
344
|
+
// 对:先 click 聚焦,再 type 触发 input 事件
|
|
345
|
+
await page.click('#autocomplete');
|
|
346
|
+
await page.type('#autocomplete', 'keyword');
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### A.3 API 通过浏览器抓出的 header 直接转 curl
|
|
350
|
+
|
|
351
|
+
```js
|
|
352
|
+
// browser_evaluate
|
|
353
|
+
() => {
|
|
354
|
+
const req = performance.getEntriesByType('resource')
|
|
355
|
+
.filter(e => e.name.includes('/api/'))[0];
|
|
356
|
+
return req?.name;
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Playwright `browser_network_requests` 直接给出已发的请求 header 列表,复制模板即可。
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## 附录 B:部署滞后排查(按技术栈)
|
|
365
|
+
|
|
366
|
+
行为像旧代码时,先核对部署版本再改代码。以下按栈列常见诊断:
|
|
367
|
+
|
|
368
|
+
### Java / JVM
|
|
369
|
+
|
|
370
|
+
```bash
|
|
371
|
+
# 字节码是否含新逻辑
|
|
372
|
+
javap -c -p <class-file> | grep -A 2 <new-method-or-keyword>
|
|
373
|
+
|
|
374
|
+
# 进程启动时间 vs class 文件 mtime
|
|
375
|
+
ps -eo pid,lstart,cmd | grep <app>
|
|
376
|
+
stat <path-to-class-or-jar>
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
- IDE 热重载(JRebel / Spring DevTools)对 **lambda / method reference** 经常失败;让用户执行 IDE 的 "Rebuild Project" 或重启应用
|
|
380
|
+
|
|
381
|
+
### Node / 前端(Vite / Webpack / Next)
|
|
382
|
+
|
|
383
|
+
- Vite HMR 对部分改动(路由定义、全局 state 初始化)不触发重载,需要**强制刷新浏览器(Ctrl/Cmd + Shift + R)**
|
|
384
|
+
- DevTools Network 看 bundle/chunk 的 hash 是否变化;没变就是浏览器在用缓存
|
|
385
|
+
- Service Worker 缓存:Application → Service Workers → Unregister
|
|
386
|
+
|
|
387
|
+
### Go
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
# 进程编译时间
|
|
391
|
+
go version -m <binary> | grep build
|
|
392
|
+
# 对比 source mtime 看是否重编译
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### Python / Ruby
|
|
396
|
+
|
|
397
|
+
- 解释型语言理论上重启即新,但 `gunicorn` / `uWSGI` 有 worker 预载;看进程启动时间、用 `kill -HUP` 重载
|
|
398
|
+
|
|
399
|
+
### 通用
|
|
400
|
+
|
|
401
|
+
- 部署流水线是否真的把你的 commit 推上了 — 看生产环境的版本端点(`/version` / `/health` / `/actuator/info`),对比 `git rev-parse HEAD`
|
|
402
|
+
- 容器化场景:容器镜像 tag 是否更新、pod 是否真的换了(`kubectl get pods -o wide` 看 `AGE` 和 `IMAGE`)
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: trellis-sync-prd
|
|
3
|
+
description: "Reconcile an out-of-date prd.md with code/requirement changes that landed without PRD update: gather diffs + user adjustments, confirm, update body, append change-log. Triggers: 「PRD 没同步」「同步 PRD」「事后回补 PRD」「sync PRD」. Not for initial PRD generation (trellis-brainstorm), source-fidelity audit (trellis-verify-prd), or re-running impl after PRD change (trellis-re-implement)."
|
|
4
|
+
---
|
|
5
|
+
# 同步 PRD - 代码/需求变更后回补 PRD
|
|
6
|
+
|
|
7
|
+
当你直接修改了任务相关的代码或需求,但没有同步更新任务的 `prd.md` 时,使用此技能将 PRD 与实际变更对齐。
|
|
8
|
+
|
|
9
|
+
**时机**:代码或需求已变更,但 PRD 未同步更新
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 使用场景
|
|
14
|
+
|
|
15
|
+
- 直接改了代码逻辑,但没更新 PRD 中的需求描述
|
|
16
|
+
- 用户口头调整了需求,代码已改但 PRD 仍是旧版本
|
|
17
|
+
- Code Review 后修改了实现方式,PRD 未反映
|
|
18
|
+
- 多次小修改累积后,PRD 与实际实现已出现偏差
|
|
19
|
+
- 任务完成前的最终检查,确认 PRD 是文档真实来源
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 执行步骤
|
|
24
|
+
|
|
25
|
+
### Step 1: 确认当前任务 `[AI]`
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
python3 ./.trellis/scripts/get_context.py
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
确认:
|
|
32
|
+
- 当前有激活的任务(`.trellis/.current-task` 已设置)
|
|
33
|
+
- 任务目录路径和 PRD 文件存在
|
|
34
|
+
|
|
35
|
+
如果没有激活的任务,询问用户要同步哪个任务的 PRD。
|
|
36
|
+
|
|
37
|
+
### Step 2: 读取现有 PRD `[AI]`
|
|
38
|
+
|
|
39
|
+
读取任务目录下的 `prd.md`,理解当前文档化的需求。
|
|
40
|
+
|
|
41
|
+
### Step 3: 收集实际变更 `[AI]`
|
|
42
|
+
|
|
43
|
+
从多个来源收集实际变更信息:
|
|
44
|
+
|
|
45
|
+
**3a. 代码变更**(如有):
|
|
46
|
+
|
|
47
|
+
后端/前端的实际包目录因项目而异(如 `srm-boot` / `iqs` / `iqs-front-human` / `backend` 等),按当前项目实际包路径替换 `<pkg-dir>`。如任务仅改根仓库,可省略 `cd`。
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# 查看当前未提交的变更
|
|
51
|
+
cd <pkg-dir> && git diff --name-only && git diff --cached --name-only
|
|
52
|
+
# 查看最近与任务相关的提交
|
|
53
|
+
cd <pkg-dir> && git log --oneline -20
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**3b. 用户描述**:
|
|
57
|
+
- 询问用户:"相比 PRD 中记录的内容,实际做了哪些不同的变更?"
|
|
58
|
+
- 提供多选引导:
|
|
59
|
+
- 需求范围变了(增加/删减了功能点)
|
|
60
|
+
- 实现方式变了(技术方案调整)
|
|
61
|
+
- 接口/字段变了(API、数据库、DTO 等)
|
|
62
|
+
- 业务规则变了(校验逻辑、流程等)
|
|
63
|
+
- 其他
|
|
64
|
+
|
|
65
|
+
### Step 4: 对比分析 `[AI]`
|
|
66
|
+
|
|
67
|
+
将 PRD 内容与实际变更进行对比,识别差异:
|
|
68
|
+
|
|
69
|
+
```markdown
|
|
70
|
+
## PRD 偏差分析
|
|
71
|
+
|
|
72
|
+
### 新增(PRD 中没有,但实际已实现)
|
|
73
|
+
- <变更 1>
|
|
74
|
+
|
|
75
|
+
### 删除(PRD 中有,但实际未实现或已移除)
|
|
76
|
+
- <变更 2>
|
|
77
|
+
|
|
78
|
+
### 修改(PRD 描述与实际实现不一致)
|
|
79
|
+
- <变更 3>: PRD 说 X,实际是 Y
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
将分析结果展示给用户确认。
|
|
83
|
+
|
|
84
|
+
### Step 5: 更新 PRD `[AI]`
|
|
85
|
+
|
|
86
|
+
经用户确认后,更新 `prd.md`:
|
|
87
|
+
|
|
88
|
+
1. **更新主体内容**:修改 Goal、Requirements、Acceptance Criteria 等章节,使其反映实际状态
|
|
89
|
+
2. **追加变更记录**:在文末追加变更日志
|
|
90
|
+
|
|
91
|
+
**变更记录格式**:
|
|
92
|
+
|
|
93
|
+
```markdown
|
|
94
|
+
## 变更记录
|
|
95
|
+
|
|
96
|
+
### 变更 <N>: <简要描述> (YYYY-MM-DD)
|
|
97
|
+
- **变更类型**: 需求变更 / 实现调整 / 范围变更
|
|
98
|
+
- **变更内容**: <具体改了什么>
|
|
99
|
+
- **原因**: <为什么改>
|
|
100
|
+
- **PRD 同步方式**: 事后回补(代码先行)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Step 6: 报告结果 `[AI]`
|
|
104
|
+
|
|
105
|
+
```markdown
|
|
106
|
+
## PRD 同步完成
|
|
107
|
+
|
|
108
|
+
### 偏差摘要
|
|
109
|
+
- 新增 <N> 项需求/实现
|
|
110
|
+
- 删除 <N> 项需求/实现
|
|
111
|
+
- 修改 <N> 项描述
|
|
112
|
+
|
|
113
|
+
### 更新的章节
|
|
114
|
+
- <章节 1>: <做了什么调整>
|
|
115
|
+
- <章节 2>: <做了什么调整>
|
|
116
|
+
|
|
117
|
+
### 下一步
|
|
118
|
+
- 确认 PRD 内容准确
|
|
119
|
+
- 如有后续开发,PRD 已可作为最新参考
|
|
120
|
+
- 如任务已完成,可运行 `trellis-finish-work`
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 与其他入口的区别
|
|
126
|
+
|
|
127
|
+
| 入口 | 形态 | 阶段 | 说明 |
|
|
128
|
+
|------|------|------|------|
|
|
129
|
+
| `trellis-brainstorm` | skill | 需求梳理 | PRD 从零创建,边讨论边完善 |
|
|
130
|
+
| `trellis-verify-prd` | skill | 开发前 | 对照原始需求文档校验 PRD(准确性 + 覆盖度) |
|
|
131
|
+
| `trellis-sync-prd` | skill(本技能) | 事后回补 | 代码已改,PRD 未同步,回补文档 |
|
|
132
|
+
| `trellis-re-implement` | skill | 需求变更 | 先更新 PRD,再调 Implement Agent |
|
|
133
|
+
| `trellis-finish-work` | 命令 | 完成检查 | 提交前整体检查清单 |
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
典型流程:
|
|
137
|
+
PRD → 实现 → PRD 同步 # 理想流程(re-implement)
|
|
138
|
+
PRD → 实现 → 偏差 → sync-prd # 补救流程(本技能)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 核心原则
|
|
144
|
+
|
|
145
|
+
| 原则 | 说明 |
|
|
146
|
+
|------|------|
|
|
147
|
+
| **PRD 是真实来源** | PRD 应始终反映任务的最新状态,而非初始计划 |
|
|
148
|
+
| **事后回补优于不补** | 即使是事后同步,也比让 PRD 过时不管要好 |
|
|
149
|
+
| **记录变更原因** | 追加变更记录,让后续开发者理解演变过程 |
|
|
150
|
+
| **用户确认为准** | 对比分析需经用户确认后再更新,避免错误同步 |
|