@ranger1/dx 0.1.48 → 0.1.50

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.
@@ -15,6 +15,19 @@ agent: sisyphus
15
15
  ## 输入
16
16
 
17
17
  - `{{PR_NUMBER}}`
18
+ - `round`(默认 1,由调用者/循环控制)
19
+
20
+ ## 唯一标识 runId(强制)
21
+
22
+ - 全局唯一标识 `runId` 格式:`<PR>-<ROUND>-<HEAD_SHORT>`
23
+ - 其中:
24
+ - `<PR>`:PR 编号
25
+ - `<ROUND>`:当前轮次
26
+ - `<HEAD_SHORT>`:`headOid` 的前 7 位(git rev-parse --short HEAD)
27
+ - 生成者:
28
+ - 第 1 步 `pr-context` 负责计算并返回 `runId`(基于当前 checkout 的 headOid)
29
+ - 后续所有步骤(reviewers, aggregate, fix)必须透传并使用该 `runId`
30
+ - 禁止任何下游步骤自行生成或篡改 `runId`
18
31
 
19
32
  ## Cache 约定(强制)
20
33
 
@@ -26,6 +39,7 @@ agent: sisyphus
26
39
  - `pr-precheck`
27
40
  - `pr-context`
28
41
  - `codex-reviewer`
42
+
29
43
  - `claude-reviewer`
30
44
  - `gemini-reviewer`
31
45
  - `gh-thread-reviewer`
@@ -37,14 +51,15 @@ agent: sisyphus
37
51
 
38
52
  0. Task: `pr-precheck`(强制 gate:编译/预检必须先通过)
39
53
 
40
- - prompt 必须包含:`PR #{{PR_NUMBER}}`
41
- - 若返回 `{"error":"..."}`:立即终止本轮并回传错误(不再调用 reviewers)
54
+ - prompt 必须包含:`PR #{{PR_NUMBER}}`、`round: <ROUND>`(precheck 需计算并返回 runId,格式同 context)
55
+ - 若返回 `{"error":"..."}`:立即终止本轮并回传错误
42
56
  - 若返回 `{"ok":false,"fixFile":"..."}`:
57
+ - 预检阶段 runId 同样基于 `headOid` 生成(`<PR>-<ROUND>-<HEAD_SHORT>`),可直接传给 fix。
43
58
  - 最多修复 2 次(防止无限循环):
44
- - 第 1 次:Task `pr-fix`(使用该 fixFile)→ 再 Task `pr-precheck`
59
+ - 第 1 次:Task `pr-fix`(传入 `fixFile`, `runId`, `round`)→ 再 Task `pr-precheck`
45
60
  - 若仍返回 `{"ok":false,"fixFile":"..."}`:第 2 次 Task `pr-fix` → 再 Task `pr-precheck`
46
61
  - 若仍不是 `{"ok":true}`:终止并回传错误(建议:`{"error":"PRECHECK_NOT_CLEAN_AFTER_FIX"}`)
47
-
62
+ - 注意:预检失败产生的修复也应记录在 Decision Log 中(essence: `__precheck__` 或具体错误信息,file: `__precheck__`),以便后续追踪。
48
63
 
49
64
  ## 循环(最多 3 轮)
50
65
 
@@ -61,7 +76,8 @@ agent: sisyphus
61
76
 
62
77
  - prompt 必须包含:`PR #{{PR_NUMBER}}`、`round: <ROUND>`
63
78
  - 若返回 `{"error":"..."}`:立即终止本轮并回传错误(不再调用 reviewers)
64
- - 取出:`contextFile`、`runId`、`headOid`(如有)
79
+ - 取出:`contextFile`、`runId`、`headOid`
80
+ - **runId 校验**:确认返回的 `runId` 符合 `<PR>-<ROUND>-<HEAD_SHORT>` 格式
65
81
  - **CRITICAL**: 必须等待此 Task 成功完成并获取到 `contextFile` 后,才能进入 Step 2
66
82
 
67
83
  **检查 Decision Log**:
@@ -77,14 +93,14 @@ agent: sisyphus
77
93
  - `round: <ROUND>`
78
94
  - `runId: <RUN_ID>`(来自 Step 1 的输出,必须透传,禁止自行生成)
79
95
  - `contextFile: ./.cache/<file>.md`(来自 Step 1 的输出)
80
- - `decisionLogFile: ./.cache/decision-log-pr{{PR_NUMBER}}.md`(如存在,来自检查后得出)
96
+ - `decisionLogFile: ./.cache/decision-log-pr{{PR_NUMBER}}.md`(如存在)
81
97
  - reviewer 默认读 `contextFile`;如果 `decisionLogFile` 存在,reviewer 应在 prompt 中提供该文件路径以参考前轮决策;必要时允许用 `git/gh` 只读命令拿 diff
82
98
  - 忽略问题:1.格式化代码引起的噪音 2.已经lint检查以外的格式问题 3.忽略单元测试不足的问题
83
99
  - 特别关注: 逻辑、安全、性能、可维护性
84
- - 同时要注意 pr 前面轮次的 修复和讨论,对于已经拒绝、已修复的问题不要反复的提出
85
- - 同时也要注意fix的过程中有没有引入新的问题。
86
-
87
- 备注:fixFile 分为 `IssuesToFix`(P0/P1,必须修)与 `OptionalIssues`(P2/P3,pr-fix 自主裁决)。
100
+ - 遵守 Decision Log:
101
+ - 已修复(Fixed):不再提
102
+ - 已拒绝(Rejected):除非优先级升级(P_new - P_old >= 2),否则不再提
103
+ - 任何新发现必须基于当前 `runId` 对应的代码状态
88
104
  - 每个 reviewer 输出:`reviewFile: ./.cache/<file>.md`(Markdown)
89
105
 
90
106
  3. Task: `pr-review-aggregate`
@@ -93,6 +109,10 @@ agent: sisyphus
93
109
  - 输出:`{"stop":true}` 或 `{"stop":false,"fixFile":"..."}`
94
110
  - 若 `stop=true`:本轮结束并退出循环
95
111
  - **唯一性约束**: 每轮只能发布一次 Review Summary;脚本内置幂等检查,重复调用不会重复发布
112
+ - 智能聚合:
113
+ - 使用 LLM 对比 decision-log 中的 `essence` 与新 finding
114
+ - 仅当问题本质相同且优先级 delta < 2 时,自动归为 Repeated/Ignored
115
+ - 否则视为 New Issue 或 Escalation
96
116
 
97
117
  4. Task: `pr-fix`
98
118
 
@@ -102,9 +122,13 @@ agent: sisyphus
102
122
  - `runId: <RUN_ID>`(来自 Step 1 的输出,必须透传,禁止自行生成)
103
123
  - `fixFile: ./.cache/<file>.md`
104
124
  - 约定:`pr-fix` 对每个 findingId 单独 commit + push(一个 findingId 一个 commit),结束后再 `git push` 兜底
105
-
125
+ - 决策记录:
126
+ - 修复成功:追加 Fixed 记录(含 `essence`)到 Decision Log
127
+ - 拒绝/无法修复:追加 Rejected 记录(含 `reason`, `essence`)到 Decision Log
128
+ - 范围限制:essence 匹配必须在 **同一个文件** 内(不支持跨文件/重命名追踪)
106
129
  - pr-fix 输出:`fixReportFile: ./.cache/<file>.md`(Markdown)
107
130
 
131
+
108
132
  5. Task: `pr-review-aggregate`(发布修复评论)
109
133
 
110
134
  - prompt 必须包含:`PR #{{PR_NUMBER}}`、`round: <ROUND>`、`runId: <RUN_ID>`、`fixReportFile: ./.cache/<file>.md`
@@ -119,6 +143,32 @@ agent: sisyphus
119
143
 
120
144
  - 回到 1(进入下一轮 reviewers)
121
145
 
146
+ ## 本地验证(脚本直跑)
147
+
148
+ ```bash
149
+ # 0) 先确保 gh 已认证(host 从 git remote origin 推断;必要时用 --hostname)
150
+ gh auth status
151
+
152
+ # 1) precheck(round 1)
153
+ python3 "./@opencode/agents/pr_precheck.py" --pr <PR_NUMBER> --round 1
154
+
155
+ # 2) context(round 1)
156
+ python3 "./@opencode/agents/pr_context.py" --pr <PR_NUMBER> --round 1
157
+
158
+ # 3) 校验:两者都必须输出单行 JSON,且 runId 必须一致
159
+ python3 "./@opencode/agents/pr_precheck.py" --pr <PR_NUMBER> --round 1 > ./.cache/_precheck.json
160
+ python3 "./@opencode/agents/pr_context.py" --pr <PR_NUMBER> --round 1 > ./.cache/_context.json
161
+ python3 - <<'PY'
162
+ import json
163
+ p=json.load(open('./.cache/_precheck.json'))
164
+ c=json.load(open('./.cache/_context.json'))
165
+ assert p.get('runId') == c.get('runId'), (p.get('runId'), c.get('runId'))
166
+ print('OK', p.get('runId'))
167
+ PY
168
+
169
+ # 4) 运行脚本相关测试(注意:pytest 把 @ 当作 argfile;必须加 ./ 并加引号)
170
+ python3 -m pytest -q "./@opencode/agents/test_pr_review_aggregate.py"
171
+ ```
122
172
 
123
173
  ## 终止与收尾(强制)
124
174
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ranger1/dx",
3
- "version": "0.1.48",
3
+ "version": "0.1.50",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {