@fitlab-ai/agent-infra 0.5.3 → 0.5.4

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.
Files changed (65) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/package.json +1 -1
  4. package/templates/.agents/rules/issue-pr-commands.github.en.md +25 -9
  5. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +25 -9
  6. package/templates/.agents/rules/issue-sync.github.en.md +111 -23
  7. package/templates/.agents/rules/issue-sync.github.zh-CN.md +105 -17
  8. package/templates/.agents/rules/milestone-inference.github.en.md +13 -6
  9. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +13 -6
  10. package/templates/.agents/rules/pr-sync.github.en.md +3 -1
  11. package/templates/.agents/rules/pr-sync.github.zh-CN.md +3 -1
  12. package/templates/.agents/scripts/platform-adapters/platform-sync.github.js +1080 -0
  13. package/templates/.agents/scripts/validate-artifact.js +51 -802
  14. package/templates/.agents/skills/analyze-task/SKILL.en.md +2 -2
  15. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +2 -2
  16. package/templates/.agents/skills/analyze-task/config/verify.json +1 -1
  17. package/templates/.agents/skills/block-task/SKILL.en.md +2 -2
  18. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +2 -2
  19. package/templates/.agents/skills/block-task/config/verify.json +1 -1
  20. package/templates/.agents/skills/cancel-task/SKILL.en.md +6 -6
  21. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +6 -6
  22. package/templates/.agents/skills/cancel-task/config/verify.json +1 -1
  23. package/templates/.agents/skills/commit/SKILL.en.md +14 -2
  24. package/templates/.agents/skills/commit/SKILL.zh-CN.md +14 -2
  25. package/templates/.agents/skills/commit/config/verify.json +2 -1
  26. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +23 -0
  27. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +23 -0
  28. package/templates/.agents/skills/complete-task/SKILL.en.md +2 -2
  29. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +2 -2
  30. package/templates/.agents/skills/complete-task/config/verify.json +1 -1
  31. package/templates/.agents/skills/create-issue/SKILL.en.md +3 -1
  32. package/templates/.agents/skills/create-issue/SKILL.zh-CN.md +3 -1
  33. package/templates/.agents/skills/create-issue/config/verify.json +1 -1
  34. package/templates/.agents/skills/create-issue/reference/label-and-type.en.md +6 -1
  35. package/templates/.agents/skills/create-issue/reference/label-and-type.zh-CN.md +6 -1
  36. package/templates/.agents/skills/create-pr/SKILL.en.md +4 -4
  37. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +4 -4
  38. package/templates/.agents/skills/create-pr/config/verify.json +1 -1
  39. package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +9 -5
  40. package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +9 -5
  41. package/templates/.agents/skills/create-task/config/verify.json +1 -1
  42. package/templates/.agents/skills/implement-task/SKILL.en.md +4 -4
  43. package/templates/.agents/skills/implement-task/SKILL.zh-CN.md +4 -4
  44. package/templates/.agents/skills/implement-task/config/verify.json +1 -2
  45. package/templates/.agents/skills/import-codescan/config/verify.json +1 -1
  46. package/templates/.agents/skills/import-dependabot/config/verify.json +1 -1
  47. package/templates/.agents/skills/import-issue/SKILL.en.md +1 -1
  48. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +1 -1
  49. package/templates/.agents/skills/import-issue/config/verify.json +1 -1
  50. package/templates/.agents/skills/plan-task/SKILL.en.md +2 -2
  51. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +2 -2
  52. package/templates/.agents/skills/plan-task/config/verify.json +1 -1
  53. package/templates/.agents/skills/refine-task/SKILL.en.md +2 -4
  54. package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +2 -4
  55. package/templates/.agents/skills/refine-task/config/verify.json +1 -2
  56. package/templates/.agents/skills/refine-title/SKILL.en.md +5 -1
  57. package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +5 -1
  58. package/templates/.agents/skills/restore-task/config/verify.json +1 -1
  59. package/templates/.agents/skills/review-task/SKILL.en.md +2 -2
  60. package/templates/.agents/skills/review-task/SKILL.zh-CN.md +2 -2
  61. package/templates/.agents/skills/review-task/config/verify.json +1 -1
  62. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +1 -1
  63. package/templates/.github/workflows/metadata-sync.yml +127 -0
  64. package/templates/.github/workflows/pr-label.yml +75 -0
  65. package/templates/.github/workflows/status-label.yml +12 -8
@@ -2,38 +2,112 @@
2
2
 
3
3
  在任务技能需要更新 GitHub Issue 时先读取本文件。
4
4
 
5
- ## status: label 直设
5
+ ## Upstream 仓库检测
6
+
7
+ 外部开发者在 fork 仓库中执行 `gh` 命令时,默认目标会指向 fork,而不是原始仓库。所有后续 `gh issue` 和 `gh api "repos/..."` 操作都必须先检测 upstream 仓库,并统一复用 `upstream_repo`。
8
+
9
+ ```bash
10
+ upstream_repo=$(gh api "repos/$(gh repo view --json nameWithOwner -q .nameWithOwner)" \
11
+ --jq 'if .fork then .parent.full_name else .full_name end' 2>/dev/null)
12
+ ```
13
+
14
+ - 非 fork 仓库:返回当前仓库自身的 `full_name`
15
+ - fork 仓库:返回父仓库的 `full_name`
16
+ - 后续所有 `gh issue` 命令统一使用 `-R "$upstream_repo"`
17
+ - 后续所有 `gh api "repos/..."` 命令统一使用 `"repos/$upstream_repo/..."`
18
+
19
+ ## 权限检测
20
+
21
+ 所有需要写权限的操作都先对 upstream 仓库做一次权限检测。检测失败时按无权限处理,确保安全降级。
22
+
23
+ ```bash
24
+ repo_perms=$(gh api "repos/$upstream_repo" --jq '.permissions' 2>/dev/null || echo '{}')
25
+ has_triage=$(printf '%s' "$repo_perms" | grep -q '"triage":true' 2>/dev/null && echo true || echo false)
26
+ has_push=$(printf '%s' "$repo_perms" | grep -q '"push":true' 2>/dev/null && echo true || echo false)
27
+ ```
28
+
29
+ 操作与权限映射:
30
+
31
+ | 操作 | 所需权限 | 说明 |
32
+ |------|---------|------|
33
+ | 设置/移除 label | `has_triage` | triage 是最低权限 |
34
+ | 设置/移除 milestone | `has_triage` | 同上 |
35
+ | 编辑 Issue body | `has_triage` | 需求复选框同步使用 |
36
+ | 设置 Issue Type | `has_push` | 需要 write 权限 |
37
+ | 设置 assignee | 不检测 | 无权限时直接跳过 |
38
+ | 发布/更新评论 | 无需检测 | 公开仓库中认证用户可执行 |
39
+
40
+ ## 降级行为定义
41
+
42
+ | 层级 | 操作类型 | 有权限 | 无权限 |
43
+ |------|---------|--------|--------|
44
+ | 静默降级 | label / milestone / Issue Type | 直接执行 `gh` 命令,同时更新 task 留言 | 跳过 `gh` 直接操作,仅更新 task 留言,由 bot 补位 |
45
+ | 直接跳过 | assignee | 直接执行 `gh` 命令 | 不做任何替代 |
46
+ | 正常执行 | 评论 | 正常执行 | 正常执行 |
47
+
48
+ 关键原则:
49
+
50
+ - 无论是否有写权限,task 留言同步都必须继续执行
51
+ - 权限不足只影响直接写 Issue 元数据的步骤,不中断整个技能
52
+ - 现有 `2>/dev/null || true` 容错模式保持不变
53
+
54
+ ## 外部开发者锁定机制
55
+
56
+ 维护者(`has_triage=true`)不受限制。外部开发者(`has_triage=false`)在开始任务前,必须先检查 Issue 上是否已有当前任务的 `task` 留言作者。
57
+
58
+ ```bash
59
+ task_comment_author=$(gh api "repos/$upstream_repo/issues/{issue-number}/comments" \
60
+ --paginate --jq '[.[] | select(.body | test("<!-- sync-issue:{task-id}:task -->")) | .user.login] | first' \
61
+ 2>/dev/null || echo "")
62
+ current_user=$(gh api user --jq '.login' 2>/dev/null || echo "")
63
+ ```
64
+
65
+ 判定规则:
66
+
67
+ - 没有 `task` 留言:允许开始
68
+ - `task` 留言作者等于当前用户:允许继续
69
+ - `task` 留言作者不等于当前用户:立即停止,并提示先与维护者协调,避免多人同时接手同一任务
70
+
71
+ ## status label 设置
6
72
 
7
73
  如果 task.md 中存在有效的 `issue_number`(非空、非 `N/A`),且 Issue 状态为 `OPEN`,则替换所有 `status:` label 并设置目标值:
8
74
 
9
75
  ```bash
10
- state=$(gh issue view {issue-number} --json state --jq '.state' 2>/dev/null)
76
+ state=$(gh issue view {issue-number} -R "$upstream_repo" --json state --jq '.state' 2>/dev/null)
11
77
  if [ "$state" = "OPEN" ]; then
12
- gh issue view {issue-number} --json labels \
78
+ gh issue view {issue-number} -R "$upstream_repo" --json labels \
13
79
  --jq '.labels[].name | select(startswith("status:"))' 2>/dev/null \
14
80
  | while IFS= read -r label; do
15
81
  [ -z "$label" ] && continue
16
- gh issue edit {issue-number} --remove-label "$label" 2>/dev/null || true
82
+ if [ "$has_triage" = "true" ]; then
83
+ gh issue edit {issue-number} -R "$upstream_repo" --remove-label "$label" 2>/dev/null || true
84
+ fi
17
85
  done
18
- gh issue edit {issue-number} --add-label "{target-status-label}" 2>/dev/null || true
86
+ if [ "$has_triage" = "true" ]; then
87
+ gh issue edit {issue-number} -R "$upstream_repo" --add-label "{target-status-label}" 2>/dev/null || true
88
+ fi
19
89
  fi
20
90
  ```
21
91
 
22
92
  使用 `while IFS= read -r label` 按行处理,可避免 `status: in-progress` 这类含空格 label 被 shell 按空格拆开。
23
93
 
94
+ 如果 `has_triage=false`,则跳过直接设置 label,只更新 task 留言,由 bot 根据最新 task 元数据补位。
95
+
24
96
  如果 `gh` 命令失败,跳过并继续,不中断技能执行。
25
97
 
26
98
  ## Assignee 同步
27
99
 
28
100
  当技能创建或导入 Issue 时,自动将当前执行者添加为 assignee:
29
101
 
30
- - `create-issue`:在 `gh issue create` 命令中使用 `--assignee @me` 参数
31
- - `import-issue`:导入后执行 `gh issue edit {issue-number} --add-assignee @me 2>/dev/null || true`
102
+ - `create-issue`:在 `gh issue create` 命令中使用 `--assignee @me` 参数,并附带 `-R "$upstream_repo"`
103
+ - `import-issue`:导入后执行 `gh issue edit {issue-number} -R "$upstream_repo" --add-assignee @me 2>/dev/null || true`
32
104
 
33
- `@me` 由 `gh` CLI 自动解析为当前认证用户。此操作是幂等的(重复添加不会报错)。如果命令失败(如权限不足),跳过并继续。
105
+ `@me` 由 `gh` CLI 自动解析为当前认证用户。此操作是幂等的(重复添加不会报错)。如果命令失败(如权限不足),直接跳过,不做任何替代。
34
106
 
35
107
  ## `in:` label 同步
36
108
 
109
+ > **触发时机**:`in:` label 同步应在代码提交后(commit 技能)执行,不在 implement-task 或 refine-task 阶段执行。create-pr 阶段仅从 Issue 复制到 PR,不重新计算。
110
+
37
111
  读取 `.agents/.airc.json` 的 `labels.in` 映射。
38
112
 
39
113
  ```bash
@@ -48,15 +122,18 @@ git diff {base-branch}...HEAD --name-only
48
122
  2. 对每个文件按目录前缀匹配 `labels.in` 中的值,得到"应有的 `in:` labels"集合
49
123
  3. 查询 Issue/PR 当前的 `in:` labels
50
124
  4. 差集比较:
51
- - 应有但没有 `gh issue edit {issue-number} --add-label "in: {module}" 2>/dev/null || true`
52
- - 有但不应有 `gh issue edit {issue-number} --remove-label "in: {module}" 2>/dev/null || true`
125
+ - 应有但没有:仅当 `has_triage=true` 时执行 `gh issue edit {issue-number} -R "$upstream_repo" --add-label "in: {module}" 2>/dev/null || true`
126
+ - 有但不应有:仅当 `has_triage=true` 时执行 `gh issue edit {issue-number} -R "$upstream_repo" --remove-label "in: {module}" 2>/dev/null || true`
53
127
 
54
128
  ### 无映射时(只增不删回退)
55
129
 
56
130
  如果 `.airc.json` 中不存在 `labels.in` 或为空对象:
131
+
57
132
  1. 查询仓库已有 `in:` labels
58
133
  2. 从改动文件提取第一级目录
59
- 3. 仅添加匹配的 label,不移除已有 `in:` label
134
+ 3. 仅当 `has_triage=true` 时添加匹配的 label,不移除已有 `in:` label
135
+
136
+ 如果 `has_triage=false`,则跳过直接修改 `in:` label,只保留 task 留言同步,由后续自动化补位。
60
137
 
61
138
  ## 产物评论发布
62
139
 
@@ -69,7 +146,7 @@ git diff {base-branch}...HEAD --name-only
69
146
  发布前先检查是否已存在同标记评论:
70
147
 
71
148
  ```bash
72
- gh api "repos/{owner}/{repo}/issues/{issue-number}/comments" \
149
+ gh api "repos/$upstream_repo/issues/{issue-number}/comments" \
73
150
  --paginate --jq '.[].body' \
74
151
  | grep -qF "<!-- sync-issue:{task-id}:{file-stem} -->"
75
152
  ```
@@ -99,20 +176,23 @@ gh api "repos/{owner}/{repo}/issues/{issue-number}/comments" \
99
176
  其中 `{agent}` 使用当前执行该技能的 AI 代理名称(如 `claude`、`codex`、`gemini`)。
100
177
 
101
178
  `summary` 评论需要额外处理:
179
+
102
180
  - 先查找已有 `<!-- sync-issue:{task-id}:summary -->` 评论的 ID
103
181
  - 不存在则创建
104
- - 已存在且正文有变化时,使用 `gh api "repos/{owner}/{repo}/issues/comments/{comment-id}" -X PATCH -f body=...` 原地更新
182
+ - 已存在且正文有变化时,使用 `gh api "repos/$upstream_repo/issues/comments/{comment-id}" -X PATCH -f body=...` 原地更新
105
183
 
106
184
  ```bash
107
- summary_comment_id=$(gh api "repos/{owner}/{repo}/issues/{issue-number}/comments" \
185
+ summary_comment_id=$(gh api "repos/$upstream_repo/issues/{issue-number}/comments" \
108
186
  --paginate --jq '.[] | select(.body | startswith("<!-- sync-issue:{task-id}:summary -->")) | .id' \
109
187
  | head -n 1)
110
- gh api "repos/{owner}/{repo}/issues/comments/{comment-id}" -X PATCH -f body="$(cat <<'EOF'
188
+ gh api "repos/$upstream_repo/issues/comments/{comment-id}" -X PATCH -f body="$(cat <<'EOF'
111
189
  {comment-body}
112
190
  EOF
113
191
  )"
114
192
  ```
115
193
 
194
+ 评论发布不受 `has_triage` / `has_push` 限制,认证用户可正常执行。
195
+
116
196
  ## task.md 评论同步
117
197
 
118
198
  隐藏标记:
@@ -158,8 +238,11 @@ task.md 评论格式:
158
238
  还原时,从 `<details>` 块中提取 frontmatter,与正文拼合恢复为原始 `task.md`。
159
239
 
160
240
  评论标题映射:
241
+
161
242
  - `task` -> `任务文件`
162
243
 
244
+ task 留言同步始终执行,不受权限降级影响。
245
+
163
246
  ## 补发规则(`/complete-task` 归档前执行)
164
247
 
165
248
  - 扫描任务目录中的 `task.md`、`analysis*.md`、`plan*.md`、`implementation*.md`、`review*.md`、`refinement*.md`
@@ -178,6 +261,7 @@ task.md 评论格式:
178
261
  - 如果只有前邻居或后邻居,仅保留存在的一侧说明;如果两侧都不存在,则不添加位置说明
179
262
 
180
263
  标题映射:
264
+
181
265
  - `task` -> `任务文件`
182
266
  - `analysis` / `analysis-r{N}` -> `需求分析` / `需求分析(Round {N})`
183
267
  - `plan` / `plan-r{N}` -> `技术方案` / `技术方案(Round {N})`
@@ -186,6 +270,8 @@ task.md 评论格式:
186
270
  - `refinement` / `refinement-r{N}` -> `修复报告(Round 1)` / `修复报告(Round {N})`
187
271
  - `summary` -> `交付摘要`
188
272
 
273
+ 补发评论同样不受 `has_triage` / `has_push` 限制。
274
+
189
275
  ## 需求复选框同步
190
276
 
191
277
  从 task.md 的 `## 需求` 段落提取已勾选的 `- [x]` 条目;如果没有,跳过。
@@ -193,10 +279,12 @@ task.md 评论格式:
193
279
  读取 Issue 当前正文:
194
280
 
195
281
  ```bash
196
- gh issue view {issue-number} --json body --jq '.body'
282
+ gh issue view {issue-number} -R "$upstream_repo" --json body --jq '.body'
197
283
  ```
198
284
 
199
- 按复选框文本匹配,将对应的 `- [ ] {text}` 单向替换为 `- [x] {text}`。只有正文实际变化时,才使用 `gh api` PATCH 更新完整 body。
285
+ 按复选框文本匹配,将对应的 `- [ ] {text}` 单向替换为 `- [x] {text}`。只有正文实际变化且 `has_triage=true` 时,才使用 `gh api` PATCH 更新完整 body。
286
+
287
+ 如果 `has_triage=false`,则跳过正文 PATCH,只更新 task 留言,由 bot 根据最新任务状态补位。
200
288
 
201
289
  ## Shell 安全规则
202
290
 
@@ -7,6 +7,7 @@ Read this file before `create-issue`, `implement-task`, or `create-pr` handles a
7
7
  - Narrow the milestone over the skill lifecycle: release line -> concrete version -> reuse
8
8
  - Every phase must fall back safely instead of blocking the skill
9
9
  - If `gh` is unavailable, unauthenticated, or the GitHub API call fails, skip milestone handling and continue
10
+ - Before any repository-scoped `gh api`, `gh issue edit`, or Issue lookup runs, the caller must resolve `upstream_repo` and `has_triage`
10
11
  - Only use milestones that actually exist in the repository; if a target milestone is unavailable, apply the fallback for that phase
11
12
 
12
13
  ## Branch Mode Detection
@@ -35,12 +36,14 @@ Priority:
35
36
  Suggested release-line query:
36
37
 
37
38
  ```bash
38
- gh api "repos/{owner}/{repo}/milestones?state=open&per_page=100" \
39
+ gh api "repos/$upstream_repo/milestones?state=open&per_page=100" \
39
40
  --jq '.[].title'
40
41
  ```
41
42
 
42
43
  Only match titles in `X.Y.x` format and choose the smallest major/minor pair numerically.
43
44
 
45
+ Direct milestone writes are triage-gated. When the caller detected `has_triage=false`, omit `--milestone` and continue.
46
+
44
47
  ## Phase 2: `implement-task`
45
48
 
46
49
  Goal: narrow the Issue milestone from a release line to a concrete version when implementation starts.
@@ -60,15 +63,17 @@ Sequence:
60
63
  4. When a target concrete version is found, run:
61
64
 
62
65
  ```bash
63
- gh issue edit {issue-number} --milestone "{version}"
66
+ if [ "$has_triage" = "true" ]; then
67
+ gh issue edit {issue-number} -R "$upstream_repo" --milestone "{version}"
68
+ fi
64
69
  ```
65
70
 
66
- 5. If the target milestone does not exist or the branch ancestry cannot be determined reliably, keep the original milestone unchanged
71
+ 5. If `has_triage=false`, the target milestone does not exist, or the branch ancestry cannot be determined reliably, keep the original milestone unchanged
67
72
 
68
73
  Suggested concrete-version query:
69
74
 
70
75
  ```bash
71
- gh api "repos/{owner}/{repo}/milestones?state=open&per_page=100" \
76
+ gh api "repos/$upstream_repo/milestones?state=open&per_page=100" \
72
77
  --jq '.[].title'
73
78
  ```
74
79
 
@@ -94,9 +99,11 @@ Sequence:
94
99
  2. If the Issue has a milestone, run:
95
100
 
96
101
  ```bash
97
- gh pr edit {pr-number} --milestone "{milestone}"
102
+ if [ "$has_triage" = "true" ]; then
103
+ gh pr edit {pr-number} --milestone "{milestone}"
104
+ fi
98
105
  ```
99
106
 
100
- 3. If the Issue has no milestone, skip PR milestone assignment
107
+ 3. If the Issue has no milestone, or `has_triage=false`, skip PR milestone assignment
101
108
 
102
109
  Do not infer a PR milestone separately from task.md, branch names, tags, or `General Backlog`.
@@ -7,6 +7,7 @@
7
7
  - milestone 在技能生命周期中逐步收窄:版本线 -> 具体版本 -> 复用
8
8
  - 任一步骤推断失败时都必须回退,不得阻塞技能执行
9
9
  - 如果 `gh` CLI 不可用、未认证,或 GitHub API 请求失败,跳过 milestone 处理并继续
10
+ - 在执行 repo 级 `gh api`、`gh issue edit` 或 Issue 查询前,调用方必须先完成 `upstream_repo` / `has_triage` 检测
10
11
  - 只使用仓库中实际存在的 milestone;目标 milestone 不存在时按各阶段 fallback 处理
11
12
 
12
13
  ## 分支模式检测
@@ -35,12 +36,14 @@ git branch -r | grep -v 'HEAD' | grep -E 'origin/[0-9]+\.[0-9]+\.x$'
35
36
  版本线查询建议:
36
37
 
37
38
  ```bash
38
- gh api "repos/{owner}/{repo}/milestones?state=open&per_page=100" \
39
+ gh api "repos/$upstream_repo/milestones?state=open&per_page=100" \
39
40
  --jq '.[].title'
40
41
  ```
41
42
 
42
43
  只匹配 `X.Y.x` 格式的标题;按 major、minor 数值升序取最小版本线。
43
44
 
45
+ Milestone 设置属于 `has_triage` 权限范围;如果调用方检测到 `has_triage=false`,则省略 `--milestone` 并继续。
46
+
44
47
  ## 阶段 2:`implement-task`
45
48
 
46
49
  目标:开始开发时,把 Issue milestone 从版本线收窄到具体版本。
@@ -60,15 +63,17 @@ gh api "repos/{owner}/{repo}/milestones?state=open&per_page=100" \
60
63
  4. 找到目标具体版本后,执行:
61
64
 
62
65
  ```bash
63
- gh issue edit {issue-number} --milestone "{version}"
66
+ if [ "$has_triage" = "true" ]; then
67
+ gh issue edit {issue-number} -R "$upstream_repo" --milestone "{version}"
68
+ fi
64
69
  ```
65
70
 
66
- 5. 如果目标 milestone 不存在或无法可靠判断 -> 保持原 milestone 不变
71
+ 5. 如果 `has_triage=false`、目标 milestone 不存在,或无法可靠判断 -> 保持原 milestone 不变
67
72
 
68
73
  具体版本查询建议:
69
74
 
70
75
  ```bash
71
- gh api "repos/{owner}/{repo}/milestones?state=open&per_page=100" \
76
+ gh api "repos/$upstream_repo/milestones?state=open&per_page=100" \
72
77
  --jq '.[].title'
73
78
  ```
74
79
 
@@ -94,9 +99,11 @@ git merge-base --is-ancestor origin/main HEAD
94
99
  2. Issue 有 milestone -> 执行:
95
100
 
96
101
  ```bash
97
- gh pr edit {pr-number} --milestone "{milestone}"
102
+ if [ "$has_triage" = "true" ]; then
103
+ gh pr edit {pr-number} --milestone "{milestone}"
104
+ fi
98
105
  ```
99
106
 
100
- 3. Issue 没有 milestone -> 跳过,不设置 PR milestone
107
+ 3. Issue 没有 milestone,或 `has_triage=false` -> 跳过,不设置 PR milestone
101
108
 
102
109
  不要再使用 `task.md`、分支名、tag 或 `General Backlog` 为 PR 单独推断 milestone。
@@ -70,6 +70,8 @@ Use this canonical comment body template:
70
70
 
71
71
  Fetch existing comments through the Issues comments API, not the dedicated PR comments API.
72
72
 
73
+ Before this section runs, the caller must resolve `upstream_repo` by following `.agents/rules/issue-pr-commands.md` / `.agents/rules/issue-sync.md`.
74
+
73
75
  Process:
74
76
  1. Fetch existing PR comments and locate the comment ID that starts with `<!-- sync-pr:{task-id}:summary -->`
75
77
  2. When rendering the body, always write the current `git rev-parse HEAD` result into `<!-- last-commit: {git-head-sha} -->`
@@ -80,7 +82,7 @@ Process:
80
82
  When updating an existing comment, use:
81
83
 
82
84
  ```bash
83
- gh api "repos/{owner}/{repo}/issues/comments/{comment-id}" -X PATCH -f body="$(cat <<'EOF'
85
+ gh api "repos/$upstream_repo/issues/comments/{comment-id}" -X PATCH -f body="$(cat <<'EOF'
84
86
  {comment-body}
85
87
  EOF
86
88
  )"
@@ -70,6 +70,8 @@
70
70
 
71
71
  已有评论必须通过 Issues comments API 获取,而不是单独的 PR comments API。
72
72
 
73
+ 调用方在执行本章节前,必须先按 `.agents/rules/issue-pr-commands.md` / `.agents/rules/issue-sync.md` 完成 `upstream_repo` 检测。
74
+
73
75
  处理顺序:
74
76
  1. 获取 PR 上现有 comments,查找以 `<!-- sync-pr:{task-id}:summary -->` 开头的评论 ID
75
77
  2. 渲染评论正文时,始终写入当前 `git rev-parse HEAD` 的结果到 `<!-- last-commit: {git-head-sha} -->`
@@ -80,7 +82,7 @@
80
82
  更新已有评论时,使用如下模式:
81
83
 
82
84
  ```bash
83
- gh api "repos/{owner}/{repo}/issues/comments/{comment-id}" -X PATCH -f body="$(cat <<'EOF'
85
+ gh api "repos/$upstream_repo/issues/comments/{comment-id}" -X PATCH -f body="$(cat <<'EOF'
84
86
  {comment-body}
85
87
  EOF
86
88
  )"