@fitlab-ai/agent-infra 0.4.2 → 0.4.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 (137) hide show
  1. package/README.md +24 -34
  2. package/README.zh-CN.md +24 -34
  3. package/lib/defaults.json +5 -0
  4. package/lib/init.js +1 -0
  5. package/lib/update.js +13 -1
  6. package/package.json +3 -3
  7. package/templates/.agents/README.md +16 -2
  8. package/templates/.agents/README.zh-CN.md +16 -2
  9. package/templates/.agents/rules/issue-sync.md +194 -0
  10. package/templates/.agents/rules/issue-sync.zh-CN.md +194 -0
  11. package/templates/.agents/rules/milestone-inference.md +102 -0
  12. package/templates/.agents/rules/milestone-inference.zh-CN.md +102 -0
  13. package/templates/.agents/scripts/validate-artifact.js +1444 -0
  14. package/templates/.agents/skills/analyze-task/SKILL.md +24 -1
  15. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +24 -1
  16. package/templates/.agents/skills/analyze-task/config/verify.json +43 -0
  17. package/templates/.agents/skills/archive-tasks/SKILL.md +40 -0
  18. package/templates/.agents/skills/archive-tasks/SKILL.zh-CN.md +40 -0
  19. package/templates/.agents/skills/archive-tasks/scripts/archive-tasks.sh +403 -0
  20. package/templates/.agents/skills/block-task/SKILL.md +25 -37
  21. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +25 -37
  22. package/templates/.agents/skills/block-task/config/verify.json +28 -0
  23. package/templates/.agents/skills/cancel-task/SKILL.md +142 -0
  24. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +142 -0
  25. package/templates/.agents/skills/cancel-task/config/verify.json +30 -0
  26. package/templates/.agents/skills/close-codescan/SKILL.md +7 -0
  27. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +7 -0
  28. package/templates/.agents/skills/close-dependabot/SKILL.md +7 -0
  29. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +7 -0
  30. package/templates/.agents/skills/commit/SKILL.md +17 -0
  31. package/templates/.agents/skills/commit/SKILL.zh-CN.md +17 -0
  32. package/templates/.agents/skills/commit/config/verify.json +22 -0
  33. package/templates/.agents/skills/complete-task/SKILL.md +25 -10
  34. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +25 -10
  35. package/templates/.agents/skills/complete-task/config/verify.json +35 -0
  36. package/templates/.agents/skills/create-issue/SKILL.md +42 -6
  37. package/templates/.agents/skills/create-issue/SKILL.zh-CN.md +42 -6
  38. package/templates/.agents/skills/create-issue/config/verify.json +29 -0
  39. package/templates/.agents/skills/create-issue/reference/label-and-type.md +13 -12
  40. package/templates/.agents/skills/create-issue/reference/label-and-type.zh-CN.md +13 -12
  41. package/templates/.agents/skills/create-pr/SKILL.md +44 -10
  42. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +44 -10
  43. package/templates/.agents/skills/create-pr/config/verify.json +27 -0
  44. package/templates/.agents/skills/create-pr/reference/branch-strategy.md +3 -3
  45. package/templates/.agents/skills/create-pr/reference/branch-strategy.zh-CN.md +3 -3
  46. package/templates/.agents/skills/{sync-pr → create-pr}/reference/comment-publish.md +6 -6
  47. package/templates/.agents/skills/{sync-pr → create-pr}/reference/comment-publish.zh-CN.md +6 -6
  48. package/templates/.agents/skills/create-pr/reference/pr-body-template.md +8 -7
  49. package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +8 -7
  50. package/templates/.agents/skills/create-task/SKILL.md +25 -3
  51. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +25 -3
  52. package/templates/.agents/skills/create-task/config/verify.json +24 -0
  53. package/templates/.agents/skills/implement-task/SKILL.md +47 -8
  54. package/templates/.agents/skills/implement-task/SKILL.zh-CN.md +47 -8
  55. package/templates/.agents/skills/implement-task/config/verify.json +43 -0
  56. package/templates/.agents/skills/implement-task/reference/branch-management.md +48 -0
  57. package/templates/.agents/skills/implement-task/reference/branch-management.zh-CN.md +49 -0
  58. package/templates/.agents/skills/implement-task/reference/output-template.md +20 -0
  59. package/templates/.agents/skills/implement-task/reference/output-template.zh-CN.md +20 -0
  60. package/templates/.agents/skills/import-codescan/SKILL.md +18 -7
  61. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +18 -7
  62. package/templates/.agents/skills/import-codescan/config/verify.json +24 -0
  63. package/templates/.agents/skills/import-dependabot/SKILL.md +18 -7
  64. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +18 -7
  65. package/templates/.agents/skills/import-dependabot/config/verify.json +24 -0
  66. package/templates/.agents/skills/import-issue/SKILL.md +28 -1
  67. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +28 -1
  68. package/templates/.agents/skills/import-issue/config/verify.json +27 -0
  69. package/templates/.agents/skills/init-labels/SKILL.md +40 -10
  70. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +40 -10
  71. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +1 -22
  72. package/templates/.agents/skills/init-milestones/SKILL.md +13 -0
  73. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +13 -0
  74. package/templates/.agents/skills/plan-task/SKILL.md +29 -75
  75. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +29 -75
  76. package/templates/.agents/skills/plan-task/config/verify.json +44 -0
  77. package/templates/.agents/skills/refine-task/SKILL.md +41 -2
  78. package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +41 -2
  79. package/templates/.agents/skills/refine-task/config/verify.json +39 -0
  80. package/templates/.agents/skills/refine-task/reference/fix-workflow.md +7 -7
  81. package/templates/.agents/skills/refine-task/reference/fix-workflow.zh-CN.md +7 -7
  82. package/templates/.agents/skills/refine-title/SKILL.md +10 -2
  83. package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +10 -2
  84. package/templates/.agents/skills/restore-task/SKILL.md +159 -0
  85. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +159 -0
  86. package/templates/.agents/skills/restore-task/config/verify.json +24 -0
  87. package/templates/.agents/skills/review-task/SKILL.md +25 -1
  88. package/templates/.agents/skills/review-task/SKILL.zh-CN.md +25 -1
  89. package/templates/.agents/skills/review-task/config/verify.json +42 -0
  90. package/templates/.agents/skills/update-agent-infra/SKILL.md +11 -0
  91. package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +11 -0
  92. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +6 -1
  93. package/templates/.agents/templates/task.md +3 -7
  94. package/templates/.agents/templates/task.zh-CN.md +3 -7
  95. package/templates/.claude/commands/archive-tasks.md +9 -0
  96. package/templates/.claude/commands/archive-tasks.zh-CN.md +9 -0
  97. package/templates/.claude/commands/cancel-task.md +9 -0
  98. package/templates/.claude/commands/cancel-task.zh-CN.md +9 -0
  99. package/templates/.claude/commands/restore-task.md +9 -0
  100. package/templates/.claude/commands/restore-task.zh-CN.md +9 -0
  101. package/templates/.gemini/commands/_project_/archive-tasks.toml +10 -0
  102. package/templates/.gemini/commands/_project_/archive-tasks.zh-CN.toml +10 -0
  103. package/templates/.gemini/commands/_project_/cancel-task.toml +8 -0
  104. package/templates/.gemini/commands/_project_/cancel-task.zh-CN.toml +8 -0
  105. package/templates/.gemini/commands/_project_/restore-task.toml +8 -0
  106. package/templates/.gemini/commands/_project_/restore-task.zh-CN.toml +8 -0
  107. package/templates/.github/workflows/status-label.yml +85 -0
  108. package/templates/.opencode/commands/archive-tasks.md +11 -0
  109. package/templates/.opencode/commands/archive-tasks.zh-CN.md +11 -0
  110. package/templates/.opencode/commands/cancel-task.md +11 -0
  111. package/templates/.opencode/commands/cancel-task.zh-CN.md +11 -0
  112. package/templates/.opencode/commands/restore-task.md +11 -0
  113. package/templates/.opencode/commands/restore-task.zh-CN.md +11 -0
  114. package/templates/.agents/skills/sync-issue/SKILL.md +0 -93
  115. package/templates/.agents/skills/sync-issue/SKILL.zh-CN.md +0 -93
  116. package/templates/.agents/skills/sync-issue/reference/comment-publish.md +0 -84
  117. package/templates/.agents/skills/sync-issue/reference/comment-publish.zh-CN.md +0 -84
  118. package/templates/.agents/skills/sync-issue/reference/label-sync.md +0 -62
  119. package/templates/.agents/skills/sync-issue/reference/label-sync.zh-CN.md +0 -62
  120. package/templates/.agents/skills/sync-issue/reference/milestone-sync.md +0 -37
  121. package/templates/.agents/skills/sync-issue/reference/milestone-sync.zh-CN.md +0 -37
  122. package/templates/.agents/skills/sync-pr/SKILL.md +0 -87
  123. package/templates/.agents/skills/sync-pr/SKILL.zh-CN.md +0 -87
  124. package/templates/.agents/skills/sync-pr/reference/delivery-detection.md +0 -54
  125. package/templates/.agents/skills/sync-pr/reference/delivery-detection.zh-CN.md +0 -54
  126. package/templates/.claude/commands/sync-issue.md +0 -8
  127. package/templates/.claude/commands/sync-issue.zh-CN.md +0 -8
  128. package/templates/.claude/commands/sync-pr.md +0 -8
  129. package/templates/.claude/commands/sync-pr.zh-CN.md +0 -8
  130. package/templates/.gemini/commands/_project_/sync-issue.toml +0 -8
  131. package/templates/.gemini/commands/_project_/sync-issue.zh-CN.toml +0 -8
  132. package/templates/.gemini/commands/_project_/sync-pr.toml +0 -8
  133. package/templates/.gemini/commands/_project_/sync-pr.zh-CN.toml +0 -8
  134. package/templates/.opencode/commands/sync-issue.md +0 -11
  135. package/templates/.opencode/commands/sync-issue.zh-CN.md +0 -11
  136. package/templates/.opencode/commands/sync-pr.md +0 -11
  137. package/templates/.opencode/commands/sync-pr.zh-CN.md +0 -11
@@ -0,0 +1,194 @@
1
+ # Issue 同步规则
2
+
3
+ 在任务技能需要更新 GitHub Issue 时先读取本文件。
4
+
5
+ ## status: label 直设
6
+
7
+ 如果 task.md 中存在有效的 `issue_number`(非空、非 `N/A`),且 Issue 状态为 `OPEN`,则替换所有 `status:` label 并设置目标值:
8
+
9
+ ```bash
10
+ state=$(gh issue view {issue-number} --json state --jq '.state' 2>/dev/null)
11
+ if [ "$state" = "OPEN" ]; then
12
+ gh issue view {issue-number} --json labels \
13
+ --jq '.labels[].name | select(startswith("status:"))' 2>/dev/null \
14
+ | while IFS= read -r label; do
15
+ [ -z "$label" ] && continue
16
+ gh issue edit {issue-number} --remove-label "$label" 2>/dev/null || true
17
+ done
18
+ gh issue edit {issue-number} --add-label "{target-status-label}" 2>/dev/null || true
19
+ fi
20
+ ```
21
+
22
+ 使用 `while IFS= read -r label` 按行处理,可避免 `status: in-progress` 这类含空格 label 被 shell 按空格拆开。
23
+
24
+ 如果 `gh` 命令失败,跳过并继续,不中断技能执行。
25
+
26
+ ## Assignee 同步
27
+
28
+ 当技能创建或导入 Issue 时,自动将当前执行者添加为 assignee:
29
+
30
+ - `create-issue`:在 `gh issue create` 命令中使用 `--assignee @me` 参数
31
+ - `import-issue`:导入后执行 `gh issue edit {issue-number} --add-assignee @me 2>/dev/null || true`
32
+
33
+ `@me` 由 `gh` CLI 自动解析为当前认证用户。此操作是幂等的(重复添加不会报错)。如果命令失败(如权限不足),跳过并继续。
34
+
35
+ ## `in:` label 同步
36
+
37
+ 读取 `.agents/.airc.json` 的 `labels.in` 映射。
38
+
39
+ ```bash
40
+ git diff {base-branch}...HEAD --name-only
41
+ ```
42
+
43
+ `{base-branch}` 通常为 `main`;如果在 PR 上下文中,则使用 PR 的 base branch。
44
+
45
+ ### 有映射时(精确增删)
46
+
47
+ 1. 获取分支全部改动文件
48
+ 2. 对每个文件按目录前缀匹配 `labels.in` 中的值,得到"应有的 `in:` labels"集合
49
+ 3. 查询 Issue/PR 当前的 `in:` labels
50
+ 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`
53
+
54
+ ### 无映射时(只增不删回退)
55
+
56
+ 如果 `.airc.json` 中不存在 `labels.in` 或为空对象:
57
+ 1. 查询仓库已有 `in:` labels
58
+ 2. 从改动文件提取第一级目录
59
+ 3. 仅添加匹配的 label,不移除已有 `in:` label
60
+
61
+ ## 产物评论发布
62
+
63
+ 隐藏标记必须保持兼容:
64
+
65
+ ```html
66
+ <!-- sync-issue:{task-id}:{file-stem} -->
67
+ ```
68
+
69
+ 发布前先检查是否已存在同标记评论:
70
+
71
+ ```bash
72
+ gh api "repos/{owner}/{repo}/issues/{issue-number}/comments" \
73
+ --paginate --jq '.[].body' \
74
+ | grep -qF "<!-- sync-issue:{task-id}:{file-stem} -->"
75
+ ```
76
+
77
+ 如果已存在则跳过。
78
+
79
+ 发布流程:
80
+
81
+ 1. 先读取本地产物文件全文
82
+ 2. 将文件全文作为 `{artifact body}` 原文内联到评论中
83
+ 3. 禁止自行组织摘要、改写或截断正文
84
+
85
+ 评论格式统一为:
86
+
87
+ ```markdown
88
+ <!-- sync-issue:{task-id}:{file-stem} -->
89
+ ## {artifact-title}
90
+
91
+ {artifact body}
92
+
93
+ ---
94
+ *由 AI 自动生成 · 内部追踪:{task-id}*
95
+ ```
96
+
97
+ `summary` 评论需要额外处理:
98
+ - 先查找已有 `<!-- sync-issue:{task-id}:summary -->` 评论的 ID
99
+ - 不存在则创建
100
+ - 已存在且正文有变化时,使用 `gh api "repos/{owner}/{repo}/issues/comments/{comment-id}" -X PATCH -f body=...` 原地更新
101
+
102
+ ```bash
103
+ summary_comment_id=$(gh api "repos/{owner}/{repo}/issues/{issue-number}/comments" \
104
+ --paginate --jq '.[] | select(.body | startswith("<!-- sync-issue:{task-id}:summary -->")) | .id' \
105
+ | head -n 1)
106
+ gh api "repos/{owner}/{repo}/issues/comments/{comment-id}" -X PATCH -f body="$(cat <<'EOF'
107
+ {comment-body}
108
+ EOF
109
+ )"
110
+ ```
111
+
112
+ ## task.md 评论同步
113
+
114
+ 隐藏标记:
115
+
116
+ ```html
117
+ <!-- sync-issue:{task-id}:task -->
118
+ ```
119
+
120
+ `task.md` 使用幂等更新路径:
121
+
122
+ 1. 读取 `task.md` 全文
123
+ 2. 将 YAML frontmatter(`---` 到 `---` 之间的内容)包裹在 `<details><summary>元数据 (frontmatter)</summary>` 和 `` ```yaml `` 代码块中,其余正文保持原样作为 Markdown 渲染
124
+ 3. 使用 `task` 作为 `{file-stem}`
125
+ 4. 查找已有标记评论 ID
126
+ 5. 不存在则创建
127
+ 6. 已存在且正文有变化则 PATCH 原地更新
128
+ 7. 已存在且正文相同则跳过
129
+
130
+ task.md 评论格式:
131
+
132
+ ```markdown
133
+ <!-- sync-issue:{task-id}:task -->
134
+ ## 任务文件
135
+
136
+ <details><summary>元数据 (frontmatter)</summary>
137
+
138
+ ​```yaml
139
+ ---
140
+ {frontmatter fields}
141
+ ---
142
+ ​```
143
+
144
+ </details>
145
+
146
+ {task.md body after frontmatter}
147
+
148
+ ---
149
+ *由 AI 自动生成 · 内部追踪:{task-id}*
150
+ ```
151
+
152
+ 还原时,从 `<details>` 块中提取 frontmatter,与正文拼合恢复为原始 `task.md`。
153
+
154
+ 评论标题映射:
155
+ - `task` -> `任务文件`
156
+
157
+ ## 补发规则(`/complete-task` 归档前执行)
158
+
159
+ - 扫描任务目录中的 `task.md`、`analysis*.md`、`plan*.md`、`implementation*.md`、`review*.md`、`refinement*.md`
160
+ - 对每个 `{file-stem}` 用隐藏标记检查是否已发布;未发布则补发,已发布则跳过
161
+ - 补发只追加缺失评论,不删除或重排已有评论
162
+ - 位置说明从 Activity Log 推导时间线中的前后邻居,并加在评论标题下方:
163
+
164
+ ```markdown
165
+ > ⚠️ 本评论为补发产物,按时间线应位于「{前一个产物标题}」之后、「{后一个产物标题}」之前。
166
+ ```
167
+
168
+ - 如果只有前邻居或后邻居,仅保留存在的一侧说明;如果两侧都不存在,则不添加位置说明
169
+
170
+ 标题映射:
171
+ - `task` -> `任务文件`
172
+ - `analysis` / `analysis-r{N}` -> `需求分析` / `需求分析(Round {N})`
173
+ - `plan` / `plan-r{N}` -> `技术方案` / `技术方案(Round {N})`
174
+ - `implementation` / `implementation-r{N}` -> `实现报告(Round 1)` / `实现报告(Round {N})`
175
+ - `review` / `review-r{N}` -> `审查报告(Round 1)` / `审查报告(Round {N})`
176
+ - `refinement` / `refinement-r{N}` -> `修复报告(Round 1)` / `修复报告(Round {N})`
177
+ - `summary` -> `交付摘要`
178
+
179
+ ## 需求复选框同步
180
+
181
+ 从 task.md 的 `## 需求` 段落提取已勾选的 `- [x]` 条目;如果没有,跳过。
182
+
183
+ 读取 Issue 当前正文:
184
+
185
+ ```bash
186
+ gh issue view {issue-number} --json body --jq '.body'
187
+ ```
188
+
189
+ 按复选框文本匹配,将对应的 `- [ ] {text}` 单向替换为 `- [x] {text}`。只有正文实际变化时,才使用 `gh api` PATCH 更新完整 body。
190
+
191
+ ## Shell 安全规则
192
+
193
+ 1. 先用 Read 工具读取产物全文,再把实际文本内联到 heredoc 中;禁止在 `<<'EOF'` 内使用命令替换或变量展开。
194
+ 2. 构造含 `<!-- -->` 的内容时禁止使用 `echo`;统一使用 `cat <<'EOF'` heredoc 或 `printf '%s\n'`。
@@ -0,0 +1,102 @@
1
+ # Milestone Inference Rules
2
+
3
+ Read this file before `create-issue`, `implement-task`, or `create-pr` handles a milestone.
4
+
5
+ ## General Principles
6
+
7
+ - Narrow the milestone over the skill lifecycle: release line -> concrete version -> reuse
8
+ - Every phase must fall back safely instead of blocking the skill
9
+ - If `gh` is unavailable, unauthenticated, or the GitHub API call fails, skip milestone handling and continue
10
+ - Only use milestones that actually exist in the repository; if a target milestone is unavailable, apply the fallback for that phase
11
+
12
+ ## Branch Mode Detection
13
+
14
+ Use the following command to detect whether the repository has remote release-line branches:
15
+
16
+ ```bash
17
+ git branch -r | grep -v 'HEAD' | grep -E 'origin/[0-9]+\.[0-9]+\.x$'
18
+ ```
19
+
20
+ - Any output: multi-version branch mode
21
+ - No output: trunk mode
22
+
23
+ ## Phase 1: `create-issue`
24
+
25
+ Goal: choose a coarse-grained release line when the Issue is created.
26
+
27
+ Priority:
28
+ 1. If task.md provides a valid explicit `milestone`, use it
29
+ 2. Otherwise infer a release line:
30
+ - Trunk mode: query open `X.Y.x` milestones and choose the lowest release line
31
+ - Multi-version branch mode: try open `X.Y.x` milestones and choose the lowest release line; if that is not reliable, fall back to `General Backlog`
32
+ 3. If the inferred release line does not exist, fall back to `General Backlog`
33
+ 4. If `General Backlog` also does not exist, omit `--milestone`
34
+
35
+ Suggested release-line query:
36
+
37
+ ```bash
38
+ gh api "repos/{owner}/{repo}/milestones?state=open&per_page=100" \
39
+ --jq '.[].title'
40
+ ```
41
+
42
+ Only match titles in `X.Y.x` format and choose the smallest major/minor pair numerically.
43
+
44
+ ## Phase 2: `implement-task`
45
+
46
+ Goal: narrow the Issue milestone from a release line to a concrete version when implementation starts.
47
+
48
+ Preconditions:
49
+ - task.md contains a valid `issue_number`
50
+ - the current Issue milestone matches the release-line format `X.Y.x`
51
+
52
+ Sequence:
53
+ 1. Query the current Issue milestone
54
+ 2. If it is not in `X.Y.x` format, treat it as already specific enough and keep it unchanged
55
+ 3. If it is in `X.Y.x` format, narrow it according to branch mode:
56
+ - Trunk mode: query open concrete-version milestones on that release line (for example `0.4.4`) and choose the latest one
57
+ - Multi-version branch mode:
58
+ - If the task branch was created from `origin/X.Y.x`, choose the latest concrete version on that line
59
+ - If the task branch was created from `main`, find the highest release line and choose the latest concrete version on that line
60
+ 4. When a target concrete version is found, run:
61
+
62
+ ```bash
63
+ gh issue edit {issue-number} --milestone "{version}"
64
+ ```
65
+
66
+ 5. If the target milestone does not exist or the branch ancestry cannot be determined reliably, keep the original milestone unchanged
67
+
68
+ Suggested concrete-version query:
69
+
70
+ ```bash
71
+ gh api "repos/{owner}/{repo}/milestones?state=open&per_page=100" \
72
+ --jq '.[].title'
73
+ ```
74
+
75
+ - Release-line match: `^X\.Y\.x$`
76
+ - Concrete-version match: `^X\.Y\.[0-9]+$`
77
+ - "Latest" means the largest patch number
78
+
79
+ Suggested branch-origin checks:
80
+
81
+ ```bash
82
+ git merge-base --is-ancestor origin/{release-line} HEAD
83
+ git merge-base --is-ancestor origin/main HEAD
84
+ ```
85
+
86
+ If neither check is reliable or the remote refs are unavailable, keep the original milestone and avoid guessing.
87
+
88
+ ## Phase 3: `create-pr`
89
+
90
+ Goal: reuse the linked Issue milestone on the PR instead of inferring a new one.
91
+
92
+ Sequence:
93
+ 1. If `issue_number` exists, query the Issue milestone
94
+ 2. If the Issue has a milestone, run:
95
+
96
+ ```bash
97
+ gh pr edit {pr-number} --milestone "{milestone}"
98
+ ```
99
+
100
+ 3. If the Issue has no milestone, skip PR milestone assignment
101
+
102
+ Do not infer a PR milestone separately from task.md, branch names, tags, or `General Backlog`.
@@ -0,0 +1,102 @@
1
+ # Milestone 推断规则
2
+
3
+ 在 `create-issue`、`implement-task` 或 `create-pr` 处理 milestone 之前先读取本文件。
4
+
5
+ ## 通用原则
6
+
7
+ - milestone 在技能生命周期中逐步收窄:版本线 -> 具体版本 -> 复用
8
+ - 任一步骤推断失败时都必须回退,不得阻塞技能执行
9
+ - 如果 `gh` CLI 不可用、未认证,或 GitHub API 请求失败,跳过 milestone 处理并继续
10
+ - 只使用仓库中实际存在的 milestone;目标 milestone 不存在时按各阶段 fallback 处理
11
+
12
+ ## 分支模式检测
13
+
14
+ 使用以下命令检测仓库是否存在远程 release line 分支:
15
+
16
+ ```bash
17
+ git branch -r | grep -v 'HEAD' | grep -E 'origin/[0-9]+\.[0-9]+\.x$'
18
+ ```
19
+
20
+ - 有输出:多版本分支模式
21
+ - 无输出:主干模式
22
+
23
+ ## 阶段 1:`create-issue`
24
+
25
+ 目标:在创建 Issue 时先确定粗粒度版本线。
26
+
27
+ 优先级:
28
+ 1. `task.md` 显式存在 `milestone` 字段且值有效 -> 直接使用
29
+ 2. 否则推断版本线:
30
+ - 主干模式:查询 open 的 `X.Y.x` 里程碑,取最低版本线
31
+ - 多版本分支模式:优先查询 open 的 `X.Y.x` 里程碑,取最低版本线;如果无法确定则回退到 `General Backlog`
32
+ 3. 推断出的版本线不存在 -> 回退到 `General Backlog`
33
+ 4. `General Backlog` 也不存在 -> 省略 `--milestone`
34
+
35
+ 版本线查询建议:
36
+
37
+ ```bash
38
+ gh api "repos/{owner}/{repo}/milestones?state=open&per_page=100" \
39
+ --jq '.[].title'
40
+ ```
41
+
42
+ 只匹配 `X.Y.x` 格式的标题;按 major、minor 数值升序取最小版本线。
43
+
44
+ ## 阶段 2:`implement-task`
45
+
46
+ 目标:开始开发时,把 Issue milestone 从版本线收窄到具体版本。
47
+
48
+ 前置条件:
49
+ - `task.md` 存在有效 `issue_number`
50
+ - 当前 Issue milestone 为版本线格式 `X.Y.x`
51
+
52
+ 执行顺序:
53
+ 1. 查询 Issue 当前 milestone
54
+ 2. 如果 milestone 不是 `X.Y.x` 格式 -> 视为已足够具体,保持不变
55
+ 3. 如果 milestone 是 `X.Y.x` -> 按分支模式收窄:
56
+ - 主干模式:查询该版本线下 open 的具体版本 milestone(如 `0.4.4`),取最新版本
57
+ - 多版本分支模式:
58
+ - 当前任务分支来自 `origin/X.Y.x` release line -> 在该版本线下取最新具体版本
59
+ - 当前任务分支来自 `main` -> 找最高版本线,再取该版本线下的最新具体版本
60
+ 4. 找到目标具体版本后,执行:
61
+
62
+ ```bash
63
+ gh issue edit {issue-number} --milestone "{version}"
64
+ ```
65
+
66
+ 5. 如果目标 milestone 不存在或无法可靠判断 -> 保持原 milestone 不变
67
+
68
+ 具体版本查询建议:
69
+
70
+ ```bash
71
+ gh api "repos/{owner}/{repo}/milestones?state=open&per_page=100" \
72
+ --jq '.[].title'
73
+ ```
74
+
75
+ - 版本线匹配:`^X\.Y\.x$`
76
+ - 具体版本匹配:`^X\.Y\.[0-9]+$`
77
+ - “最新”按 patch 数值最大确定
78
+
79
+ 分支来源判断建议:
80
+
81
+ ```bash
82
+ git merge-base --is-ancestor origin/{release-line} HEAD
83
+ git merge-base --is-ancestor origin/main HEAD
84
+ ```
85
+
86
+ 如果两个判断都不可靠或远程引用缺失,保持原 milestone,不做错误推断。
87
+
88
+ ## 阶段 3:`create-pr`
89
+
90
+ 目标:PR 直接复用关联 Issue 的 milestone,不再独立推断。
91
+
92
+ 执行顺序:
93
+ 1. 如果存在 `issue_number`,查询 Issue milestone
94
+ 2. Issue 有 milestone -> 执行:
95
+
96
+ ```bash
97
+ gh pr edit {pr-number} --milestone "{milestone}"
98
+ ```
99
+
100
+ 3. Issue 没有 milestone -> 跳过,不设置 PR milestone
101
+
102
+ 不要再使用 `task.md`、分支名、tag 或 `General Backlog` 为 PR 单独推断 milestone。