@fitlab-ai/agent-infra 0.5.3 → 0.5.5

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 (69) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/lib/defaults.json +1 -0
  4. package/package.json +1 -1
  5. package/templates/.agents/rules/issue-pr-commands.github.en.md +35 -10
  6. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +35 -10
  7. package/templates/.agents/rules/issue-sync.github.en.md +118 -28
  8. package/templates/.agents/rules/issue-sync.github.zh-CN.md +112 -22
  9. package/templates/.agents/rules/milestone-inference.github.en.md +13 -6
  10. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +13 -6
  11. package/templates/.agents/rules/pr-sync.github.en.md +3 -1
  12. package/templates/.agents/rules/pr-sync.github.zh-CN.md +3 -1
  13. package/templates/.agents/scripts/platform-adapters/platform-sync.github.js +1118 -0
  14. package/templates/.agents/scripts/validate-artifact.js +51 -802
  15. package/templates/.agents/skills/analyze-task/SKILL.en.md +2 -2
  16. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +2 -2
  17. package/templates/.agents/skills/analyze-task/config/verify.json +1 -1
  18. package/templates/.agents/skills/block-task/SKILL.en.md +2 -2
  19. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +2 -2
  20. package/templates/.agents/skills/block-task/config/verify.json +1 -1
  21. package/templates/.agents/skills/cancel-task/SKILL.en.md +6 -6
  22. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +6 -6
  23. package/templates/.agents/skills/cancel-task/config/verify.json +1 -1
  24. package/templates/.agents/skills/commit/SKILL.en.md +14 -2
  25. package/templates/.agents/skills/commit/SKILL.zh-CN.md +14 -2
  26. package/templates/.agents/skills/commit/config/verify.json +2 -1
  27. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +23 -0
  28. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +23 -0
  29. package/templates/.agents/skills/complete-task/SKILL.en.md +2 -2
  30. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +2 -2
  31. package/templates/.agents/skills/complete-task/config/verify.json +1 -1
  32. package/templates/.agents/skills/create-issue/SKILL.en.md +3 -1
  33. package/templates/.agents/skills/create-issue/SKILL.zh-CN.md +3 -1
  34. package/templates/.agents/skills/create-issue/config/verify.json +1 -1
  35. package/templates/.agents/skills/create-issue/reference/label-and-type.en.md +6 -1
  36. package/templates/.agents/skills/create-issue/reference/label-and-type.zh-CN.md +6 -1
  37. package/templates/.agents/skills/create-pr/SKILL.en.md +4 -4
  38. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +4 -4
  39. package/templates/.agents/skills/create-pr/config/verify.json +3 -1
  40. package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +9 -6
  41. package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +9 -6
  42. package/templates/.agents/skills/create-release-note/SKILL.en.md +27 -2
  43. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +27 -2
  44. package/templates/.agents/skills/create-task/config/verify.json +1 -1
  45. package/templates/.agents/skills/implement-task/SKILL.en.md +4 -4
  46. package/templates/.agents/skills/implement-task/SKILL.zh-CN.md +4 -4
  47. package/templates/.agents/skills/implement-task/config/verify.json +1 -2
  48. package/templates/.agents/skills/import-codescan/config/verify.json +1 -1
  49. package/templates/.agents/skills/import-dependabot/config/verify.json +1 -1
  50. package/templates/.agents/skills/import-issue/SKILL.en.md +1 -1
  51. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +1 -1
  52. package/templates/.agents/skills/import-issue/config/verify.json +1 -1
  53. package/templates/.agents/skills/plan-task/SKILL.en.md +2 -2
  54. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +2 -2
  55. package/templates/.agents/skills/plan-task/config/verify.json +1 -1
  56. package/templates/.agents/skills/refine-task/SKILL.en.md +2 -4
  57. package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +2 -4
  58. package/templates/.agents/skills/refine-task/config/verify.json +1 -2
  59. package/templates/.agents/skills/refine-title/SKILL.en.md +5 -1
  60. package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +5 -1
  61. package/templates/.agents/skills/restore-task/config/verify.json +1 -1
  62. package/templates/.agents/skills/review-task/SKILL.en.md +2 -2
  63. package/templates/.agents/skills/review-task/SKILL.zh-CN.md +2 -2
  64. package/templates/.agents/skills/review-task/config/verify.json +1 -1
  65. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +2 -1
  66. package/templates/.github/scripts/sync-labels-to-set.sh +110 -0
  67. package/templates/.github/workflows/metadata-sync.yml +118 -0
  68. package/templates/.github/workflows/pr-label.yml +66 -0
  69. package/templates/.github/workflows/status-label.yml +20 -30
@@ -54,7 +54,7 @@ git rev-parse v<prev-version>
54
54
  - 后续步骤 7 生成发布说明时,**必须**同时参考步骤 3 的历史格式风格和完整分类清单,保持版本间的一致性
55
55
  - 如果没有历史发布说明,则使用步骤 7 中定义的默认格式
56
56
 
57
- ### 4. 收集已合并的 PR
57
+ ### 4. 收集已合并的 PR 与贡献者
58
58
 
59
59
  获取标签之间的日期范围,然后查询已合并的 PR:
60
60
 
@@ -71,6 +71,17 @@ git log v<version> --format=%aI -1
71
71
  git log v<prev-version>..v<version> --format="%H %s" --no-merges
72
72
  ```
73
73
 
74
+ 从 commit `Co-authored-by` trailer 中收集协作贡献者:
75
+
76
+ ```bash
77
+ git log v<prev-version>..v<version> \
78
+ --no-merges \
79
+ --format='%(trailers:key=Co-authored-by,valueonly,unfold)' \
80
+ | grep -v '^$' | sort | uniq -c | sort -rn
81
+ ```
82
+
83
+ 输出每行一个 `Name <email>`(`uniq -c` 给出该身份在范围内作为 co-author 的 commit 数)。
84
+
74
85
  ### 5. 收集关联 Issue
75
86
 
76
87
  从每个 PR body 中提取关联的 Issue:
@@ -115,7 +126,21 @@ git log v<prev-version>..v<version> --format="%H %s" --no-merges
115
126
  1. 条目格式:`- [scope] Description by @author in [#N](url)`
116
127
  2. Issue + PR:`in [#Issue](url) and [#PR](url)`
117
128
  3. 描述:使用 PR 标题,移除 `type(scope):` 前缀,首字母大写
118
- 4. 贡献者:去重,按贡献数量降序排列
129
+ 4. **贡献者搜集**:
130
+ - **数据源**:
131
+ - PR author:来自步骤 4 的 `gh pr list --json author`
132
+ - Commit co-authors:来自步骤 4 的 `git log ... --format='%(trailers:key=Co-authored-by,valueonly,unfold)'`
133
+ - **贡献数定义**:`该人的 PR 数 + 该人作为 co-author 的 commit 数`(同一身份跨来源合并计数)
134
+ - **Name → `@login` 映射**:
135
+ - `Co-authored-by` 原始格式为 `Name <email>`,需要推断对应的 GitHub `@login`
136
+ - 优先从 email 提取:匹配 `(\d+\+)?(\S+?)@users\.noreply\.github\.com` 时,取第二个捕获组并转为小写;该正则同时覆盖 `{id}+{login}@users.noreply.github.com` 与 `{login}@users.noreply.github.com`
137
+ - 否则按 Name 启发式:取首个空格前的 token 并转为小写(例如 `Claude Opus 4.6 (1M context)` → `@claude`、`Codex` → `@codex`、`Gemini` → `@gemini`)
138
+ - 已出现在 PR author 列表中的 login,必须按该 login 合并计数,避免把 `Claude` 和 `@claude` 拆成两个条目
139
+ - 同一 login 的所有 Name 变体都必须归并后再计数与排序;例如 `Claude` 与 `Claude Opus 4.6 (1M context)` 都映射到 `@claude` 时,应先合并为同一个贡献者
140
+ - Bot 身份保留原样(如 `dependabot[bot]`)
141
+ - 若仍无法可靠确定 login,则输出 `@{Name 首 token 小写}`,并在 `Contributors` 段落下追加 `<!-- TODO(reviewer): 确认 {原始 Name <email>} 的 GitHub login -->`
142
+ - **排序**:按贡献数降序;贡献数相同时按 login 字典序
143
+ - **去重**:以最终映射后的 `@login` 为键
119
144
  5. 空部分:省略没有条目的部分
120
145
 
121
146
  ### 8. 展示并确认
@@ -20,6 +20,6 @@
20
20
  "expected_action_pattern": "Task Created",
21
21
  "freshness_minutes": 30
22
22
  },
23
- "github-sync": null
23
+ "platform-sync": null
24
24
  }
25
25
  }
@@ -39,7 +39,7 @@ After this step, write the final branch name back to `task.md`.
39
39
 
40
40
  ### 3. Narrow the Milestone
41
41
 
42
- If task.md contains a valid `issue_number`, read `.agents/rules/milestone-inference.md` and follow "Phase 2: `implement-task`" to narrow the Issue milestone before implementation starts.
42
+ If task.md contains a valid `issue_number`, read `.agents/rules/issue-sync.md` first to complete upstream repository detection plus permission detection; then read `.agents/rules/milestone-inference.md` and follow "Phase 2: `implement-task`" to narrow the Issue milestone before implementation starts; if `has_triage=false`, keep the current milestone unchanged.
43
43
 
44
44
  ### 4. Determine the Input Plan and Implementation Round
45
45
 
@@ -93,9 +93,9 @@ Update `.agents/workspace/active/{task-id}/task.md`:
93
93
  - append:
94
94
  `- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Implementation (Round {N})** by {agent} — Code implemented, {n} files modified, {n} tests passed → {implementation-artifact}`
95
95
 
96
- If task.md contains a valid `issue_number`, perform these sync actions (skip and continue on any failure; read `.agents/rules/issue-sync.md` first):
97
- - Set `status: in-progress` and refine `in:` labels from the branch diff by following `.agents/rules/issue-sync.md` (add/remove when a mapping exists, add-only when it does not)
98
- - Sync checked `## Requirements` items to the Issue body and publish the `{implementation-artifact}` comment
96
+ If task.md contains a valid `issue_number`, perform these sync actions (skip and continue on any failure; read `.agents/rules/issue-sync.md` first and complete upstream repository detection plus permission detection):
97
+ - Set `status: in-progress` by following issue-sync.md
98
+ - Publish the `{implementation-artifact}` comment
99
99
  - Create or update the `<!-- sync-issue:{task-id}:task -->` comment (follow the task.md comment sync rule in issue-sync.md)
100
100
 
101
101
  ### 10. Verification Gate
@@ -39,7 +39,7 @@ description: "根据技术方案实施任务并输出报告"
39
39
 
40
40
  ### 3. 收窄里程碑
41
41
 
42
- 如果 task.md 中存在有效的 `issue_number`,按 `.agents/rules/milestone-inference.md` 的「阶段 2:`implement-task`」收窄 Issue milestone。执行前先读取该文件。
42
+ 如果 task.md 中存在有效的 `issue_number`,执行前先读取 `.agents/rules/issue-sync.md`,完成 upstream 仓库检测和权限检测;再读取 `.agents/rules/milestone-inference.md`,按其中的「阶段 2:`implement-task`」收窄 Issue milestone;如果 `has_triage=false`,则保持原 milestone 不变。
43
43
 
44
44
  ### 4. 确定输入方案与实现轮次
45
45
 
@@ -93,9 +93,9 @@ date "+%Y-%m-%d %H:%M:%S%:z"
93
93
  - 追加:
94
94
  `- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Implementation (Round {N})** by {agent} — Code implemented, {n} files modified, {n} tests passed → {implementation-artifact}`
95
95
 
96
- 如果 task.md 中存在有效的 `issue_number`,执行以下同步操作(任一失败则跳过并继续;执行前先读取 `.agents/rules/issue-sync.md`):
97
- - 设置 `status: in-progress`,并按 `.agents/rules/issue-sync.md` `in:` label 同步规则,基于分支改动精修 `in:` label(有映射时可增可删,无映射时仅补充)
98
- - 同步 `## 需求` 中已勾选项到 Issue body,并发布 `{implementation-artifact}` 评论
96
+ 如果 task.md 中存在有效的 `issue_number`,执行以下同步操作(任一失败则跳过并继续;执行前先读取 `.agents/rules/issue-sync.md`,完成 upstream 仓库检测和权限检测):
97
+ - issue-sync.md 设置 `status: in-progress`
98
+ - 发布 `{implementation-artifact}` 评论
99
99
  - 创建或更新 `<!-- sync-issue:{task-id}:task -->` 评论(按 issue-sync.md 的 task.md 评论同步规则)
100
100
 
101
101
  ### 10. 完成校验
@@ -29,13 +29,12 @@
29
29
  "expected_action_pattern": "Implementation \\(Round \\d+\\)",
30
30
  "freshness_minutes": 30
31
31
  },
32
- "github-sync": {
32
+ "platform-sync": {
33
33
  "when": "issue_number_exists",
34
34
  "expected_status_label": "status: in-progress",
35
35
  "expected_comment_marker": "<!-- sync-issue:{task-id}:{artifact-stem} -->",
36
36
  "verify_comment_content": true,
37
37
  "verify_task_comment_content": true,
38
- "sync_checked_requirements": true,
39
38
  "verify_issue_type": true,
40
39
  "verify_milestone": true
41
40
  }
@@ -19,6 +19,6 @@
19
19
  "expected_action_pattern": "Import Code Scanning Alert",
20
20
  "freshness_minutes": 30
21
21
  },
22
- "github-sync": null
22
+ "platform-sync": null
23
23
  }
24
24
  }
@@ -19,6 +19,6 @@
19
19
  "expected_action_pattern": "Import Dependabot Alert",
20
20
  "freshness_minutes": 30
21
21
  },
22
- "github-sync": null
22
+ "platform-sync": null
23
23
  }
24
24
  }
@@ -17,7 +17,7 @@ Import the specified GitHub Issue and create a task. Argument: issue number.
17
17
 
18
18
  ### 1. Retrieve Issue Information
19
19
 
20
- Read `.agents/rules/issue-pr-commands.md` first, then use its "Read an Issue" command to load the Issue data.
20
+ Read `.agents/rules/issue-pr-commands.md` first, follow its prerequisite steps to complete authentication and code-hosting platform detection, then load the Issue data with its "Read an Issue" command.
21
21
 
22
22
  Extract: issue number, title, description, and labels.
23
23
  Use the Issue title as-is for the task title (preserve the Issue's original language).
@@ -17,7 +17,7 @@ description: "从 GitHub Issue 导入并创建任务"
17
17
 
18
18
  ### 1. 获取 Issue 信息
19
19
 
20
- 执行前先读取 `.agents/rules/issue-pr-commands.md`,并按其中的 “读取 Issue” 命令获取 Issue 信息。
20
+ 执行前先读取 `.agents/rules/issue-pr-commands.md`,并按其中的前置步骤完成认证和代码托管平台检测;随后按其中的 “读取 Issue” 命令获取 Issue 信息。
21
21
 
22
22
  提取:issue 编号、标题、描述、标签。
23
23
  任务标题直接使用 Issue 的原始标题(保持 Issue 标题的原始语言)。
@@ -20,7 +20,7 @@
20
20
  "expected_action_pattern": "Import Issue",
21
21
  "freshness_minutes": 30
22
22
  },
23
- "github-sync": {
23
+ "platform-sync": {
24
24
  "when": "issue_number_exists",
25
25
  "issue_must_exist": true
26
26
  }
@@ -97,8 +97,8 @@ Update `.agents/workspace/active/{task-id}/task.md`:
97
97
  ```
98
98
 
99
99
  If task.md contains a valid `issue_number`, perform these sync actions (skip and continue on any failure):
100
- - Read `.agents/rules/issue-sync.md` before syncing
101
- - Set `status: pending-design-work`
100
+ - Read `.agents/rules/issue-sync.md` before syncing, and complete upstream repository detection plus permission detection
101
+ - Set `status: pending-design-work` by following issue-sync.md
102
102
  - Publish the `{plan-artifact}` comment
103
103
  - Create or update the `<!-- sync-issue:{task-id}:task -->` comment (follow the task.md comment sync rule in issue-sync.md)
104
104
 
@@ -97,8 +97,8 @@ date "+%Y-%m-%d %H:%M:%S%:z"
97
97
  ```
98
98
 
99
99
  如果 task.md 中存在有效的 `issue_number`,执行以下同步操作(任一失败则跳过并继续):
100
- - 执行前先读取 `.agents/rules/issue-sync.md`
101
- - 设置 `status: pending-design-work`
100
+ - 执行前先读取 `.agents/rules/issue-sync.md`,完成 upstream 仓库检测和权限检测
101
+ - 按 issue-sync.md 设置 `status: pending-design-work`
102
102
  - 发布 `{plan-artifact}` 评论
103
103
  - 创建或更新 `<!-- sync-issue:{task-id}:task -->` 评论(按 issue-sync.md 的 task.md 评论同步规则)
104
104
 
@@ -31,7 +31,7 @@
31
31
  "expected_action_pattern": "Technical Design \\(Round \\d+\\)",
32
32
  "freshness_minutes": 30
33
33
  },
34
- "github-sync": {
34
+ "platform-sync": {
35
35
  "when": "issue_number_exists",
36
36
  "expected_status_label": "status: pending-design-work",
37
37
  "expected_comment_marker": "<!-- sync-issue:{task-id}:{artifact-stem} -->",
@@ -60,10 +60,8 @@ Update task.md:
60
60
  `- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Refinement (Round {N}, for {review-artifact})** by {agent} — Fixed {n} blockers, {n} major, {n} minor issues → {refinement-artifact}`
61
61
 
62
62
  If task.md contains a valid `issue_number`, perform these sync actions (skip and continue on any failure):
63
- - Read `.agents/rules/issue-sync.md` before syncing
64
- - Set `status: in-progress`
65
- - Refine `in:` labels from the branch diff by following `.agents/rules/issue-sync.md` (add/remove when a mapping exists, add-only when it does not)
66
- - Sync checked `## Requirements` items to the Issue body
63
+ - Read `.agents/rules/issue-sync.md` before syncing, and complete upstream repository detection plus permission detection
64
+ - Set `status: in-progress` by following issue-sync.md
67
65
  - Publish the `{refinement-artifact}` comment
68
66
  - Create or update the `<!-- sync-issue:{task-id}:task -->` comment (follow the task.md comment sync rule in issue-sync.md)
69
67
 
@@ -60,10 +60,8 @@ date "+%Y-%m-%d %H:%M:%S%:z"
60
60
  `- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Refinement (Round {N}, for {review-artifact})** by {agent} — Fixed {n} blockers, {n} major, {n} minor issues → {refinement-artifact}`
61
61
 
62
62
  如果 task.md 中存在有效的 `issue_number`,执行以下同步操作(任一失败则跳过并继续):
63
- - 执行前先读取 `.agents/rules/issue-sync.md`
64
- - 设置 `status: in-progress`
65
- - 按 `.agents/rules/issue-sync.md` 的 `in:` label 同步规则,基于分支改动精修 `in:` label(有映射时可增可删,无映射时仅补充)
66
- - 同步 `## 需求` 中已勾选项到 Issue body
63
+ - 执行前先读取 `.agents/rules/issue-sync.md`,完成 upstream 仓库检测和权限检测
64
+ - 按 issue-sync.md 设置 `status: in-progress`
67
65
  - 发布 `{refinement-artifact}` 评论
68
66
  - 创建或更新 `<!-- sync-issue:{task-id}:task -->` 评论(按 issue-sync.md 的 task.md 评论同步规则)
69
67
 
@@ -25,13 +25,12 @@
25
25
  "expected_action_pattern": "Refinement \\(Round \\d+, for .+\\)",
26
26
  "freshness_minutes": 30
27
27
  },
28
- "github-sync": {
28
+ "platform-sync": {
29
29
  "when": "issue_number_exists",
30
30
  "expected_status_label": "status: in-progress",
31
31
  "expected_comment_marker": "<!-- sync-issue:{task-id}:{artifact-stem} -->",
32
32
  "verify_comment_content": true,
33
33
  "verify_task_comment_content": true,
34
- "sync_checked_requirements": true,
35
34
  "verify_issue_type": true,
36
35
  "verify_milestone": true
37
36
  }
@@ -11,7 +11,7 @@ Reformat the title of the specified Issue or PR to Conventional Commits format b
11
11
 
12
12
  ### 1. Identify Target and Fetch Information
13
13
 
14
- Read `.agents/rules/issue-pr-commands.md` before this step.
14
+ Read `.agents/rules/issue-pr-commands.md` before this step, and follow its prerequisite steps to complete authentication and code-hosting platform detection.
15
15
 
16
16
  Try to determine if the ID is an Issue or PR:
17
17
  - first fetch Issue data by following the "Read an Issue" command in the rule file
@@ -58,6 +58,8 @@ If the user confirms:
58
58
  - for an Issue, update the title by following the "Update Issues" command in `.agents/rules/issue-pr-commands.md`
59
59
  - for a PR, update the title by following the "Update PRs" command in `.agents/rules/issue-pr-commands.md`
60
60
 
61
+ Title changes require write permission. Follow the permission-degradation rules in `.agents/rules/issue-pr-commands.md` and `.agents/rules/issue-sync.md`; if permission is unavailable, skip the change and inform the user.
62
+
61
63
  ### 5. Inform User
62
64
 
63
65
  > **IMPORTANT**: All TUI command formats listed below must be output in full. Do not show only the format for the current AI agent.
@@ -66,6 +68,8 @@ If the skill updated an Issue title, explain that no extra sync command is requi
66
68
 
67
69
  If the skill updated a PR title, explain that `create-pr` now publishes the reviewer summary inline, so no extra sync command is needed; continue with the workflow skill that matches the task's current stage.
68
70
 
71
+ If title modification was skipped due to insufficient permissions, additionally remind the user that the suggested title can still be applied manually on the code-hosting platform page.
72
+
69
73
  ## Advantages
70
74
 
71
75
  This skill:
@@ -11,7 +11,7 @@ description: "重构 Issue/PR 标题为 Conventional Commits 格式"
11
11
 
12
12
  ### 1. 识别目标并获取信息
13
13
 
14
- 执行前先读取 `.agents/rules/issue-pr-commands.md`。
14
+ 执行前先读取 `.agents/rules/issue-pr-commands.md`,并按其中的前置步骤完成认证和代码托管平台检测。
15
15
 
16
16
  尝试判断 ID 是 Issue 还是 PR:
17
17
  - 先按规则文件中的“读取 Issue”命令获取 Issue 信息
@@ -58,6 +58,8 @@ Issue/PR #{id} 分析结果:
58
58
  - 对于 Issue:按 `.agents/rules/issue-pr-commands.md` 中的 “Issue 更新” 命令设置标题
59
59
  - 对于 PR:按 `.agents/rules/issue-pr-commands.md` 中的 “PR 更新” 命令设置标题
60
60
 
61
+ 标题修改需要写权限,按 `.agents/rules/issue-pr-commands.md` 与 `.agents/rules/issue-sync.md` 中的权限降级规则执行;无权限时跳过修改操作并告知用户。
62
+
61
63
  ### 5. 告知用户
62
64
 
63
65
  > **重要**:以下「下一步」中列出的所有 TUI 命令格式必须完整输出,不要只展示当前 AI 代理对应的格式。
@@ -66,6 +68,8 @@ Issue/PR #{id} 分析结果:
66
68
 
67
69
  如果修改了 PR 标题,提示 `create-pr` 已内联发布 reviewer 摘要,无需额外同步命令;后续按任务当前阶段继续执行对应工作流技能。
68
70
 
71
+ 如果因权限不足跳过了标题修改,额外提示用户建议标题仍可手动应用到代码托管平台页面。
72
+
69
73
  ## 优势
70
74
 
71
75
  本技能的优势:
@@ -19,6 +19,6 @@
19
19
  "expected_action_pattern": "Restore Task",
20
20
  "freshness_minutes": 30
21
21
  },
22
- "github-sync": null
22
+ "platform-sync": null
23
23
  }
24
24
  }
@@ -54,8 +54,8 @@ Update task.md and append:
54
54
  `- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Code Review (Round {N})** by {agent} — Verdict: {Approved/Changes Requested/Rejected}, blockers: {n}, major: {n}, minor: {n} → {artifact-filename}`
55
55
 
56
56
  If task.md contains a valid `issue_number`, perform these sync actions (skip and continue on any failure):
57
- - Read `.agents/rules/issue-sync.md` before syncing
58
- - Set `status: in-progress`
57
+ - Read `.agents/rules/issue-sync.md` before syncing, and complete upstream repository detection plus permission detection
58
+ - Set `status: in-progress` by following issue-sync.md
59
59
  - Publish the `{review-artifact}` comment
60
60
  - Create or update the `<!-- sync-issue:{task-id}:task -->` comment (follow the task.md comment sync rule in issue-sync.md)
61
61
 
@@ -54,8 +54,8 @@ date "+%Y-%m-%d %H:%M:%S%:z"
54
54
  `- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Code Review (Round {N})** by {agent} — Verdict: {Approved/Changes Requested/Rejected}, blockers: {n}, major: {n}, minor: {n} → {artifact-filename}`
55
55
 
56
56
  如果 task.md 中存在有效的 `issue_number`,执行以下同步操作(任一失败则跳过并继续):
57
- - 执行前先读取 `.agents/rules/issue-sync.md`
58
- - 设置 `status: in-progress`
57
+ - 执行前先读取 `.agents/rules/issue-sync.md`,完成 upstream 仓库检测和权限检测
58
+ - 按 issue-sync.md 设置 `status: in-progress`
59
59
  - 发布 `{review-artifact}` 评论
60
60
  - 创建或更新 `<!-- sync-issue:{task-id}:task -->` 评论(按 issue-sync.md 的 task.md 评论同步规则)
61
61
 
@@ -29,7 +29,7 @@
29
29
  "expected_action_pattern": "Code Review \\(Round \\d+\\)",
30
30
  "freshness_minutes": 30
31
31
  },
32
- "github-sync": {
32
+ "platform-sync": {
33
33
  "when": "issue_number_exists",
34
34
  "expected_status_label": "status: in-progress",
35
35
  "expected_comment_marker": "<!-- sync-issue:{task-id}:{artifact-stem} -->",
@@ -56,6 +56,7 @@ const DEFAULTS = {
56
56
  ".claude/hooks/",
57
57
  ".gemini/commands/",
58
58
  ".github/hooks/check-version-format.sh",
59
+ ".github/scripts/",
59
60
  ".opencode/commands/"
60
61
  ],
61
62
  "merged": [
@@ -76,7 +77,7 @@ const DEFAULTS = {
76
77
  }
77
78
  };
78
79
 
79
- const INSTALLER_VERSION = "v0.5.3";
80
+ const INSTALLER_VERSION = "v0.5.5";
80
81
  const PACKAGE_NAME = '@fitlab-ai/agent-infra';
81
82
  // Add a new identifier here only after shipping matching .{platform}. template variants.
82
83
  const KNOWN_PLATFORMS = new Set(['github']);
@@ -0,0 +1,110 @@
1
+ #!/bin/sh
2
+ # Ensure the labels matching --prefix on an issue or PR equal the set passed via
3
+ # repeated --target flags (0, 1, or N labels).
4
+ # Algorithm must stay in sync with .agents/rules/issue-sync.md.
5
+
6
+ set -e
7
+
8
+ usage() {
9
+ printf 'Usage: %s --repo <owner/repo> (--issue <number> | --pr <number>) --prefix <prefix> [--target <label> ...]\n' "$0" >&2
10
+ exit 1
11
+ }
12
+
13
+ append_target() {
14
+ if [ -n "$targets" ]; then
15
+ targets=$(printf '%s\n%s' "$targets" "$1")
16
+ else
17
+ targets=$1
18
+ fi
19
+ }
20
+
21
+ repo=""
22
+ number=""
23
+ kind=""
24
+ prefix=""
25
+ targets=""
26
+
27
+ while [ $# -gt 0 ]; do
28
+ case "$1" in
29
+ --repo)
30
+ [ $# -ge 2 ] || usage
31
+ repo=$2
32
+ shift 2
33
+ ;;
34
+ --issue)
35
+ [ $# -ge 2 ] || usage
36
+ [ -z "$kind" ] || usage
37
+ kind="issue"
38
+ number=$2
39
+ shift 2
40
+ ;;
41
+ --pr)
42
+ [ $# -ge 2 ] || usage
43
+ [ -z "$kind" ] || usage
44
+ kind="pr"
45
+ number=$2
46
+ shift 2
47
+ ;;
48
+ --prefix)
49
+ [ $# -ge 2 ] || usage
50
+ prefix=$2
51
+ shift 2
52
+ ;;
53
+ --target)
54
+ [ $# -ge 2 ] || usage
55
+ append_target "$2"
56
+ shift 2
57
+ ;;
58
+ *)
59
+ printf 'Unknown argument: %s\n' "$1" >&2
60
+ usage
61
+ ;;
62
+ esac
63
+ done
64
+
65
+ [ -n "$repo" ] || usage
66
+ [ -n "$number" ] || usage
67
+ [ -n "$kind" ] || usage
68
+ [ -n "$prefix" ] || usage
69
+
70
+ while IFS= read -r label; do
71
+ [ -z "$label" ] && continue
72
+ case "$label" in
73
+ "$prefix"*) ;;
74
+ *)
75
+ printf 'Target "%s" must start with prefix "%s"\n' "$label" "$prefix" >&2
76
+ exit 1
77
+ ;;
78
+ esac
79
+ done <<EOF
80
+ $targets
81
+ EOF
82
+
83
+ current_labels=$(gh "$kind" view "$number" \
84
+ --repo "$repo" \
85
+ --json labels --jq ".labels[].name | select(startswith(\"$prefix\"))" \
86
+ 2>/dev/null || true)
87
+
88
+ while IFS= read -r label; do
89
+ [ -z "$label" ] && continue
90
+ if ! printf '%s\n' "$targets" | grep -qxF "$label"; then
91
+ gh "$kind" edit "$number" \
92
+ --repo "$repo" \
93
+ --remove-label "$label" \
94
+ 2>/dev/null || true
95
+ fi
96
+ done <<EOF
97
+ $current_labels
98
+ EOF
99
+
100
+ while IFS= read -r label; do
101
+ [ -z "$label" ] && continue
102
+ if ! printf '%s\n' "$current_labels" | grep -qxF "$label"; then
103
+ gh "$kind" edit "$number" \
104
+ --repo "$repo" \
105
+ --add-label "$label" \
106
+ 2>/dev/null || true
107
+ fi
108
+ done <<EOF
109
+ $targets
110
+ EOF
@@ -0,0 +1,118 @@
1
+ name: Metadata Sync
2
+
3
+ on:
4
+ issue_comment:
5
+ types: [created, edited]
6
+
7
+ permissions:
8
+ issues: write
9
+
10
+ jobs:
11
+ sync-metadata:
12
+ runs-on: ubuntu-latest
13
+ if: ${{ !github.event.issue.pull_request }}
14
+ steps:
15
+ - name: Extract metadata from task comment
16
+ id: metadata
17
+ run: |
18
+ body=$(jq -r '.comment.body' "$GITHUB_EVENT_PATH")
19
+ if ! printf '%s' "$body" | grep -qE '<!-- sync-issue:TASK-[0-9]{8}-[0-9]{6}:task -->'; then
20
+ printf 'is_task_comment=false\n' >> "$GITHUB_OUTPUT"
21
+ exit 0
22
+ fi
23
+
24
+ frontmatter=$(printf '%s\n' "$body" \
25
+ | tr -d '\r' \
26
+ | awk '
27
+ BEGIN { capture = 0; separators = 0 }
28
+ $0 == "---" {
29
+ separators += 1
30
+ if (separators == 1) {
31
+ capture = 1
32
+ next
33
+ }
34
+ if (separators == 2) {
35
+ exit
36
+ }
37
+ }
38
+ capture { print }
39
+ ')
40
+
41
+ type=$(printf '%s\n' "$frontmatter" \
42
+ | sed -n 's/^type:[[:space:]]*//p' \
43
+ | head -n 1 \
44
+ | sed 's/[[:space:]]*#.*$//' \
45
+ | sed 's/^[[:space:]]*//; s/[[:space:]]*$//' \
46
+ | tr '[:upper:]' '[:lower:]')
47
+
48
+ milestone=$(printf '%s\n' "$frontmatter" \
49
+ | sed -n 's/^milestone:[[:space:]]*//p' \
50
+ | head -n 1 \
51
+ | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
52
+
53
+ printf 'is_task_comment=true\n' >> "$GITHUB_OUTPUT"
54
+ printf 'type=%s\n' "$type" >> "$GITHUB_OUTPUT"
55
+ printf 'milestone=%s\n' "$milestone" >> "$GITHUB_OUTPUT"
56
+
57
+ - name: Checkout shared scripts
58
+ if: steps.metadata.outputs.is_task_comment == 'true' && steps.metadata.outputs.type != ''
59
+ uses: actions/checkout@v4
60
+ with:
61
+ sparse-checkout: .github/scripts
62
+ sparse-checkout-cone-mode: false
63
+
64
+ - name: Sync type label
65
+ if: steps.metadata.outputs.is_task_comment == 'true' && steps.metadata.outputs.type != ''
66
+ env:
67
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
68
+ ISSUE_NUMBER: ${{ github.event.issue.number }}
69
+ TYPE: ${{ steps.metadata.outputs.type }}
70
+ run: |
71
+ case "$TYPE" in
72
+ bug|bugfix) TYPE_LABEL="type: bug" ;;
73
+ feature) TYPE_LABEL="type: feature" ;;
74
+ enhancement|refactor|refactoring) TYPE_LABEL="type: enhancement" ;;
75
+ docs|documentation) TYPE_LABEL="type: documentation" ;;
76
+ dependency-upgrade) TYPE_LABEL="type: dependency-upgrade" ;;
77
+ task|chore) TYPE_LABEL="type: task" ;;
78
+ *) TYPE_LABEL="" ;;
79
+ esac
80
+
81
+ if [ -n "$TYPE_LABEL" ]; then
82
+ .github/scripts/sync-labels-to-set.sh \
83
+ --repo "$GITHUB_REPOSITORY" \
84
+ --issue "$ISSUE_NUMBER" \
85
+ --prefix "type:" \
86
+ --target "$TYPE_LABEL"
87
+ fi
88
+
89
+ - name: Sync milestone
90
+ if: steps.metadata.outputs.is_task_comment == 'true' && steps.metadata.outputs.milestone != ''
91
+ env:
92
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
93
+ ISSUE_NUMBER: ${{ github.event.issue.number }}
94
+ MILESTONE: ${{ steps.metadata.outputs.milestone }}
95
+ run: |
96
+ gh issue edit "$ISSUE_NUMBER" \
97
+ --repo "$GITHUB_REPOSITORY" \
98
+ --milestone "$MILESTONE" \
99
+ 2>/dev/null || true
100
+
101
+ - name: Sync issue type
102
+ if: steps.metadata.outputs.is_task_comment == 'true' && steps.metadata.outputs.type != ''
103
+ env:
104
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
105
+ ISSUE_NUMBER: ${{ github.event.issue.number }}
106
+ TYPE: ${{ steps.metadata.outputs.type }}
107
+ run: |
108
+ case "$TYPE" in
109
+ bug|bugfix) ISSUE_TYPE="Bug" ;;
110
+ feature|enhancement) ISSUE_TYPE="Feature" ;;
111
+ *) ISSUE_TYPE="Task" ;;
112
+ esac
113
+
114
+ gh api "repos/$GITHUB_REPOSITORY/issues/$ISSUE_NUMBER" \
115
+ -X PATCH \
116
+ -f type="$ISSUE_TYPE" \
117
+ --silent \
118
+ 2>/dev/null || true