@fitlab-ai/agent-infra 0.3.0 → 0.3.2

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 (51) hide show
  1. package/README.md +368 -51
  2. package/README.zh-CN.md +369 -52
  3. package/bin/cli.js +1 -1
  4. package/lib/version.js +2 -1
  5. package/package.json +1 -1
  6. package/templates/.agents/README.md +12 -0
  7. package/templates/.agents/README.zh-CN.md +12 -0
  8. package/templates/.agents/skills/analyze-task/SKILL.md +106 -105
  9. package/templates/.agents/skills/check-task/SKILL.md +108 -94
  10. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +12 -0
  11. package/templates/.agents/skills/close-codescan/SKILL.md +64 -63
  12. package/templates/.agents/skills/close-dependabot/SKILL.md +71 -70
  13. package/templates/.agents/skills/commit/SKILL.md +19 -4
  14. package/templates/.agents/skills/commit/SKILL.zh-CN.md +19 -4
  15. package/templates/.agents/skills/complete-task/SKILL.md +11 -1
  16. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +11 -1
  17. package/templates/.agents/skills/create-issue/SKILL.md +302 -0
  18. package/templates/.agents/skills/create-issue/SKILL.zh-CN.md +302 -0
  19. package/templates/.agents/skills/create-pr/SKILL.md +140 -5
  20. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +140 -5
  21. package/templates/.agents/skills/create-release-note/SKILL.md +18 -11
  22. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +18 -11
  23. package/templates/.agents/skills/create-task/SKILL.md +80 -78
  24. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -6
  25. package/templates/.agents/skills/implement-task/SKILL.md +7 -2
  26. package/templates/.agents/skills/implement-task/SKILL.zh-CN.md +7 -2
  27. package/templates/.agents/skills/import-codescan/SKILL.md +54 -53
  28. package/templates/.agents/skills/import-dependabot/SKILL.md +57 -56
  29. package/templates/.agents/skills/import-issue/SKILL.md +58 -58
  30. package/templates/.agents/skills/init-labels/SKILL.md +8 -0
  31. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -0
  32. package/templates/.agents/skills/plan-task/SKILL.md +151 -149
  33. package/templates/.agents/skills/refine-task/SKILL.md +147 -137
  34. package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +10 -2
  35. package/templates/.agents/skills/review-task/SKILL.md +196 -186
  36. package/templates/.agents/skills/review-task/SKILL.zh-CN.md +13 -4
  37. package/templates/.agents/skills/sync-issue/SKILL.md +252 -272
  38. package/templates/.agents/skills/sync-issue/SKILL.zh-CN.md +26 -47
  39. package/templates/.agents/skills/sync-pr/SKILL.md +274 -82
  40. package/templates/.agents/skills/sync-pr/SKILL.zh-CN.md +251 -59
  41. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +1 -1
  42. package/templates/.claude/CLAUDE.md +13 -0
  43. package/templates/.claude/CLAUDE.zh-CN.md +13 -0
  44. package/templates/.claude/commands/create-issue.md +8 -0
  45. package/templates/.claude/commands/create-issue.zh-CN.md +8 -0
  46. package/templates/.gemini/commands/_project_/create-issue.toml +8 -0
  47. package/templates/.gemini/commands/_project_/create-issue.zh-CN.toml +8 -0
  48. package/templates/.opencode/commands/create-issue.md +11 -0
  49. package/templates/.opencode/commands/create-issue.zh-CN.md +11 -0
  50. package/templates/AGENTS.md +13 -0
  51. package/templates/AGENTS.zh-CN.md +13 -0
@@ -0,0 +1,302 @@
1
+ ---
2
+ name: create-issue
3
+ description: >
4
+ Create a GitHub Issue from a task file.
5
+ Triggered when the user asks to create an Issue for a task. Argument: task-id.
6
+ ---
7
+
8
+ # Create Issue
9
+
10
+ ## Boundary / Critical Rules
11
+
12
+ - The only outputs of this skill are a newly created GitHub Issue and the `issue_number` field written back to `task.md`
13
+ - Build the Issue title and body from `task.md` only. Do not read `analysis.md`, `plan.md`, `implementation.md`, or other task artifacts
14
+ - If the project has Issue templates, they only provide body structure, field labels, default labels, and a candidate Issue Type. All actual body content values must still come from `task.md`
15
+ - Do not sync analysis, design, implementation, or review details in this skill; that belongs to `sync-issue`
16
+ - After executing this skill, you **must** immediately update task status in `task.md`
17
+
18
+ ## Steps
19
+
20
+ ### 1. Verify Prerequisites
21
+
22
+ Check required file:
23
+ - `.agent-workspace/active/{task-id}/task.md` - Task file
24
+
25
+ Check that GitHub CLI is available and authenticated:
26
+
27
+ ```bash
28
+ gh auth status
29
+ ```
30
+
31
+ Note: `{task-id}` format is `TASK-{yyyyMMdd-HHmmss}`, e.g. `TASK-20260306-143022`
32
+
33
+ If the task file does not exist, prompt `Task {task-id} not found`.
34
+
35
+ If the `issue_number` field already exists in task.md front matter and its value is neither empty nor `N/A`, ask the user whether to reuse the existing Issue or create a new one.
36
+
37
+ ### 2. Extract Task Information
38
+
39
+ Read from `task.md` only:
40
+ - Task title
41
+ - `## Description` content
42
+ - `## Requirements` list
43
+ - `type` field
44
+ - `milestone` field (if present)
45
+
46
+ If the description is empty, prompt the user to update the task description first.
47
+
48
+ ### 3. Build Issue Content
49
+
50
+ Issue content rules:
51
+ - **Title**: use the task title
52
+ - **Body values**: come from `task.md` only
53
+ - **Template role**: Issue templates provide structure, field labels, and default labels only
54
+ - **Issue Type**: prefer the template `type:` value; otherwise use a fallback mapping from task.md `type`
55
+ - **When no usable template exists**: fall back to the simple format
56
+
57
+ #### 3a. Detect Issue Templates
58
+
59
+ Check the project templates and ignore `config.yml`:
60
+
61
+ ```bash
62
+ rg --files .github/ISSUE_TEMPLATE -g '*.yml' -g '!config.yml'
63
+ ```
64
+
65
+ If template files exist, read the top-level `name:` field from each template and build a candidate list. Use the task title and description to choose the most semantically appropriate template from that list.
66
+
67
+ Example candidate list:
68
+ - `bug_report.yml` - a bug-focused template
69
+ - `question.yml` - a question or support template
70
+ - `feature_request.yml` - a feature-focused template
71
+ - `documentation.yml` - a documentation-focused template
72
+ - `other.yml` - a general fallback template
73
+
74
+ If there is no clearly matching template, choose the closest one.
75
+
76
+ These filenames are illustrative only; use the actual templates present in the target project.
77
+
78
+ If there is no template, no suitable match, or YAML parsing fails, go directly to the **3c fallback path**.
79
+
80
+ #### 3b. Build the Body from the Matched Template
81
+
82
+ Read the following top-level fields from the matched YAML template:
83
+ - `name`
84
+ - `type:`
85
+ - `labels:`
86
+ - `body:`
87
+
88
+ Template-path rules:
89
+ - if the template defines `type:`, record it as `{issue-type}`
90
+ - treat each value in `labels:` as a candidate label
91
+ - iterate over the `body:` list
92
+ - for `type: textarea` and `type: input` fields:
93
+ - use `attributes.label` as the markdown section heading
94
+ - fill the section content with information mapped from `task.md`
95
+ - for `type: markdown`: skip it; do not copy helper text from the template directly into the Issue body
96
+ - for `type: dropdown` and `type: checkboxes`: skip them
97
+ - if `task.md` does not have suitable content, write `N/A`
98
+
99
+ Suggested field mapping:
100
+ - fields containing `summary`, `title` -> task title
101
+ - fields containing `description`, `problem`, `what happened`, `issue-description`, `current-content` -> task description
102
+ - fields containing `solution`, `requirements`, `steps`, `suggested-content`, `impact`, `context`, `alternatives`, `expected` -> requirement list rendered as a checklist or bullet list
103
+ - other `textarea` / `input` fields -> prefer the task description, otherwise use `N/A`
104
+
105
+ For each candidate label from the template path, check existence first:
106
+
107
+ ```bash
108
+ gh label list --search "{label}" --limit 20 --json name --jq '.[].name'
109
+ ```
110
+
111
+ Keep only exact label matches for Issue creation.
112
+
113
+ #### 3c. Default Body Format (Fallback)
114
+
115
+ Recommended body structure:
116
+
117
+ ```markdown
118
+ ## Description
119
+
120
+ {task-description}
121
+
122
+ ## Requirements
123
+
124
+ - [ ] {requirement-1}
125
+ - [ ] {requirement-2}
126
+ ```
127
+
128
+ Label mapping:
129
+
130
+ | task.md type | GitHub label |
131
+ |---|---|
132
+ | `bug`, `bugfix` | `type: bug` |
133
+ | `feature` | `type: feature` |
134
+ | `enhancement` | `type: enhancement` |
135
+ | `docs`, `documentation` | `type: documentation` |
136
+ | `dependency-upgrade` | `type: dependency-upgrade` |
137
+ | `task`, `chore`, `refactor`, `refactoring` | `type: task` |
138
+ | anything else | skip |
139
+
140
+ Issue Type fallback mapping:
141
+
142
+ | task.md type | GitHub Issue Type |
143
+ |---|---|
144
+ | `bug`, `bugfix` | `Bug` |
145
+ | `feature`, `enhancement` | `Feature` |
146
+ | `task`, `documentation`, `dependency-upgrade`, `chore`, `docs`, `refactor`, `refactoring`, and all other values | `Task` |
147
+
148
+ If the fallback path maps a label, check whether it exists first:
149
+
150
+ ```bash
151
+ gh label list --search "{type-label}" --limit 20 --json name --jq '.[].name'
152
+ ```
153
+
154
+ Only keep the label when an exact matching label exists; otherwise skip it to avoid Issue creation failure.
155
+
156
+ ### 4. Create Issue
157
+
158
+ Execute:
159
+
160
+ ```bash
161
+ gh issue create --title "{title}" --body "{body}" --label "{label-1}" --label "{label-2}" --milestone "{milestone}"
162
+ ```
163
+
164
+ If the previous step kept no valid labels, omit all `--label` arguments.
165
+ If task.md has no `milestone` field or it is empty, default to `General Backlog` as the milestone (newly created Issues are unassigned and should go into the general backlog). If `General Backlog` does not exist either, omit the `--milestone` argument.
166
+
167
+ Do not rely on `gh issue create --template`; this skill should parse `.github/ISSUE_TEMPLATE/*.yml` directly and produce the final `--body`.
168
+
169
+ Record the returned Issue URL and extract the Issue number from the trailing path segment:
170
+
171
+ ```bash
172
+ issue_url="$(gh issue create ...)"
173
+ issue_number="${issue_url##*/}"
174
+ ```
175
+
176
+ If `{issue-type}` has been determined, set the Issue Type after creation on a best-effort basis:
177
+
178
+ Get repository information first because the later `in:` label step can reuse it:
179
+
180
+ ```bash
181
+ repo="$(gh repo view --json nameWithOwner --jq '.nameWithOwner')"
182
+ owner="${repo%%/*}"
183
+ ```
184
+
185
+ Query the organization's available Issue Types:
186
+
187
+ ```bash
188
+ gh api "orgs/$owner/issue-types" --jq '.[].name'
189
+ ```
190
+
191
+ If the query succeeds and `{issue-type}` appears in the returned list, set it:
192
+
193
+ ```bash
194
+ gh api "repos/$repo/issues/{issue-number}" -X PATCH -f type="{issue-type}" --silent
195
+ ```
196
+
197
+ Verify the result:
198
+
199
+ ```bash
200
+ gh api "repos/$repo/issues/{issue-number}" --jq '.type.name // empty'
201
+ ```
202
+
203
+ If the verification result matches `{issue-type}`, record `Issue Type: {issue-type}`; otherwise record `Issue Type: failed to set`.
204
+
205
+ #### Add `in:` labels
206
+
207
+ Get all repository labels with the `in:` prefix:
208
+
209
+ ```bash
210
+ gh label list --search "in:" --limit 50 --json name --jq '.[].name'
211
+ ```
212
+
213
+ If no `in:` labels exist, skip this step.
214
+
215
+ If `in:` labels exist, use the task context (title, description, and affected file list) to judge which labels are relevant. For each relevant label, run:
216
+
217
+ ```bash
218
+ gh issue edit {issue-number} --add-label "in: {module}"
219
+ ```
220
+
221
+ Record all successfully added `in:` labels. If none are relevant, record `in: labels: skipped (no relevant labels)`.
222
+
223
+ Tolerance requirements:
224
+ - if `orgs/$owner/issue-types` returns `404`, the repo owner is not an organization, or Issue Types are not enabled, skip this without failing the create flow
225
+ - if `{issue-type}` is not in the available list, skip it
226
+ - if adding an `in:` label fails, skip it and record the failure without blocking Issue creation
227
+ - if the milestone name is invalid or unavailable, warn and skip it instead of aborting the whole Issue creation flow
228
+
229
+ ### 5. Update Task Status
230
+
231
+ Get the current time:
232
+
233
+ ```bash
234
+ date "+%Y-%m-%d %H:%M:%S"
235
+ ```
236
+
237
+ Update `.agent-workspace/active/{task-id}/task.md`:
238
+ - Add or update `issue_number`: `{issue-number}`
239
+ - `updated_at`: {current time}
240
+ - **Append** to `## Activity Log` (do NOT overwrite previous entries):
241
+ ```
242
+ - {yyyy-MM-dd HH:mm:ss} — **Create Issue** by {agent} — Issue #{issue-number} created
243
+ ```
244
+
245
+ ### 6. Inform User
246
+
247
+ > **IMPORTANT**: All TUI command formats listed below must be output in full. Do not show only the format for the current AI agent.
248
+
249
+ Output format:
250
+ ```
251
+ Issue created for task {task-id}.
252
+
253
+ Issue details:
254
+ - Number: #{issue-number}
255
+ - URL: {issue-url}
256
+ - Labels: {applied-labels or skipped}
257
+ - in: Labels: {applied-in-labels or skipped}
258
+ - Issue Type: {issue-type | failed to set | skipped}
259
+ - Milestone: {milestone or skipped}
260
+
261
+ Output:
262
+ - `issue_number` written back to task.md
263
+
264
+ Next step - sync task progress to the Issue:
265
+ - Claude Code / OpenCode: /sync-issue {task-id}
266
+ - Gemini CLI: /{{project}}:sync-issue {task-id}
267
+ - Codex CLI: $sync-issue {task-id}
268
+ ```
269
+
270
+ ## Completion Checklist
271
+
272
+ - [ ] Created the GitHub Issue
273
+ - [ ] Detected project `ISSUE_TEMPLATE` files
274
+ - [ ] Used template structure when available, otherwise used the fallback format
275
+ - [ ] Built the Issue title and body from `task.md` only
276
+ - [ ] Handled `type:` / Issue Type and `milestone` when available
277
+ - [ ] Processed `in:` labels using LLM relevance judgment
278
+ - [ ] Recorded `issue_number` in task.md
279
+ - [ ] Updated `updated_at` in task.md
280
+ - [ ] Appended an Activity Log entry to task.md
281
+ - [ ] Informed the user of the next step (must include all TUI command formats)
282
+ - [ ] **Did not read analysis/design/implementation artifacts to build the Issue**
283
+
284
+ ## STOP
285
+
286
+ After completing the checklist, **stop immediately**. Do not sync detailed Issue content or continue the workflow.
287
+
288
+ ## Notes
289
+
290
+ 1. **Responsibility boundary**: `create-issue` only creates the base Issue; detailed progress sync belongs to `sync-issue`
291
+ 2. **Avoid duplicates**: confirm with the user if `issue_number` already exists
292
+ 3. **Label tolerance**: if standard labels are not initialized, skipping the label is acceptable and should not block Issue creation
293
+ 4. **Template tolerance**: if a template is missing, unmatched, or its YAML is invalid, fall back to the simple body format instead of failing the whole create flow
294
+ 5. **Issue Type / Milestone tolerance**: if Issue Types are unavailable, the target type is missing, or the milestone is unavailable, skip that part and continue creating the Issue
295
+ 6. **`in:` label tolerance**: if adding an `in:` label fails, skip it without blocking Issue creation
296
+
297
+ ## Error Handling
298
+
299
+ - Task not found: prompt `Task {task-id} not found`
300
+ - `gh` missing or unauthenticated: prompt `GitHub CLI is not available or not authenticated`
301
+ - Empty description: prompt `Task description is empty, please update task.md first`
302
+ - Create failure: prompt `Failed to create GitHub Issue`
@@ -0,0 +1,302 @@
1
+ ---
2
+ name: create-issue
3
+ description: >
4
+ 从任务文件创建 GitHub Issue。
5
+ 当用户要求为任务创建 Issue 时触发。参数:task-id。
6
+ ---
7
+
8
+ # 创建 Issue
9
+
10
+ ## 行为边界 / 关键规则
11
+
12
+ - 本技能的唯一产出是 GitHub Issue,以及 task.md 中 `issue_number` 字段的回写
13
+ - 构建 Issue 标题和正文时,**仅从 task.md 读取**;不要读取 `analysis.md`、`plan.md`、`implementation.md` 或其他产物
14
+ - 如果项目存在 Issue 模板,模板只提供正文结构、字段标题、默认 labels 和候选 Issue Type;所有实际正文内容值仍然只来自 task.md
15
+ - 不要在此技能中同步分析、方案、实现或审查细节;这些由 `sync-issue` 负责
16
+ - 执行本技能后,你**必须**立即更新 task.md 中的任务状态
17
+
18
+ ## 执行步骤
19
+
20
+ ### 1. 验证前置条件
21
+
22
+ 检查必要文件:
23
+ - `.agent-workspace/active/{task-id}/task.md` - 任务文件
24
+
25
+ 检查 GitHub CLI 可用且已认证:
26
+
27
+ ```bash
28
+ gh auth status
29
+ ```
30
+
31
+ 注意:`{task-id}` 格式为 `TASK-{yyyyMMdd-HHmmss}`,例如 `TASK-20260306-143022`
32
+
33
+ 如果任务文件不存在,提示 `Task {task-id} not found`。
34
+
35
+ 如果 `task.md` front matter 中已经存在 `issue_number` 字段,且其值不为空也不为 `N/A`,先询问用户是复用现有 Issue 还是重新创建。
36
+
37
+ ### 2. 提取任务信息
38
+
39
+ 仅从 `task.md` 提取:
40
+ - 任务标题
41
+ - `## 描述` 内容
42
+ - `## 需求` 列表
43
+ - `type` 字段
44
+ - `milestone` 字段(如存在)
45
+
46
+ 如果描述为空,提示用户先完善任务描述。
47
+
48
+ ### 3. 构建 Issue 内容
49
+
50
+ Issue 内容规则:
51
+ - **标题**:使用任务标题
52
+ - **正文内容值**:仅来自 task.md
53
+ - **模板作用**:Issue 模板只提供结构、字段标签和默认 labels
54
+ - **Issue Type**:优先使用模板中的 `type:`;无模板时根据 task.md `type` 做 fallback 映射
55
+ - **无可用模板时**:退回简单格式(fallback / 兜底)
56
+
57
+ #### 3a. 检测 Issue 模板
58
+
59
+ 检查项目中的模板文件,忽略 `config.yml`:
60
+
61
+ ```bash
62
+ rg --files .github/ISSUE_TEMPLATE -g '*.yml' -g '!config.yml'
63
+ ```
64
+
65
+ 如果存在模板文件,读取每个模板的顶层 `name:` 字段,构建候选列表。结合任务标题和描述,从候选列表中选择最匹配的模板。
66
+
67
+ 示例候选列表:
68
+ - `bug_report.yml` — Bug 类模板
69
+ - `question.yml` — 问题咨询类模板
70
+ - `feature_request.yml` — 功能请求类模板
71
+ - `documentation.yml` — 文档问题类模板
72
+ - `other.yml` — 通用兜底模板
73
+
74
+ 如果没有明确匹配的模板,选择最接近的一个。
75
+
76
+ 以上文件名仅为示例,应以目标项目实际存在的模板为准。
77
+
78
+ 如果没有模板、没有匹配到合适模板,或模板 YAML 解析失败,则直接进入 **3c fallback / 兜底路径**。
79
+
80
+ #### 3b. 使用模板构建 Issue 正文
81
+
82
+ 读取匹配模板中的顶层字段:
83
+ - `name`
84
+ - `type:`
85
+ - `labels:`
86
+ - `body:`
87
+
88
+ 模板路径的处理规则:
89
+ - 如果模板定义了 `type:`,记录为 `{issue-type}`
90
+ - `labels:` 中的每个值都视为候选 label
91
+ - 遍历 `body:` 列表
92
+ - 对 `type: textarea` 和 `type: input` 字段:
93
+ - 使用 `attributes.label` 作为 markdown 段落标题
94
+ - 将 task.md 信息映射到该段内容
95
+ - 对 `type: markdown`:跳过,不要把模板说明文本直接复制到正文
96
+ - 对 `type: dropdown` 和 `type: checkboxes`:跳过
97
+ - 如果 task.md 中没有合适内容,写入 `N/A`
98
+
99
+ 字段映射建议:
100
+ - 包含 `summary`、`title` 的字段 -> 使用任务标题
101
+ - 包含 `description`、`problem`、`what happened`、`issue-description`、`current-content` 的字段 -> 使用任务描述
102
+ - 包含 `solution`、`requirements`、`steps`、`suggested-content`、`impact`、`context`、`alternatives`、`expected` 的字段 -> 使用需求列表(可渲染为 checklist 或 bullet list)
103
+ - 其他 `textarea` / `input` 字段 -> 优先使用任务描述,否则使用 `N/A`
104
+
105
+ 对模板路径中的每个候选 label,都先检查是否存在:
106
+
107
+ ```bash
108
+ gh label list --search "{label}" --limit 20 --json name --jq '.[].name'
109
+ ```
110
+
111
+ 只有精确匹配的 label 才保留用于创建 Issue。
112
+
113
+ #### 3c. 默认正文格式(fallback / 兜底)
114
+
115
+ 推荐正文结构:
116
+
117
+ ```markdown
118
+ ## Description
119
+
120
+ {task-description}
121
+
122
+ ## Requirements
123
+
124
+ - [ ] {requirement-1}
125
+ - [ ] {requirement-2}
126
+ ```
127
+
128
+ 标签映射:
129
+
130
+ | task.md type | GitHub label |
131
+ |---|---|
132
+ | `bug`、`bugfix` | `type: bug` |
133
+ | `feature` | `type: feature` |
134
+ | `enhancement` | `type: enhancement` |
135
+ | `docs`、`documentation` | `type: documentation` |
136
+ | `dependency-upgrade` | `type: dependency-upgrade` |
137
+ | `task`、`chore`、`refactor`、`refactoring` | `type: task` |
138
+ | 其他 | 跳过 |
139
+
140
+ Issue Type fallback 映射:
141
+
142
+ | task.md type | GitHub Issue Type |
143
+ |---|---|
144
+ | `bug`、`bugfix` | `Bug` |
145
+ | `feature`、`enhancement` | `Feature` |
146
+ | `task`、`documentation`、`dependency-upgrade`、`chore`、`docs`、`refactor`、`refactoring` 及其他值 | `Task` |
147
+
148
+ 如果 fallback 路径映射到了 label,先检查该 label 是否存在:
149
+
150
+ ```bash
151
+ gh label list --search "{type-label}" --limit 20 --json name --jq '.[].name'
152
+ ```
153
+
154
+ 只有存在精确匹配的 label 时,才在创建 Issue 时保留它;否则跳过 label,避免创建失败。
155
+
156
+ ### 4. 创建 Issue
157
+
158
+ 执行:
159
+
160
+ ```bash
161
+ gh issue create --title "{title}" --body "{body}" --label "{label-1}" --label "{label-2}" --milestone "{milestone}"
162
+ ```
163
+
164
+ 如果前一步没有保留下任何有效 label,则省略所有 `--label` 参数。
165
+ 如果 task.md 中没有 `milestone` 字段或值为空,默认使用 `General Backlog` 作为里程碑(新建 Issue 处于未分配状态,应归入通用积压)。如果 `General Backlog` 也不存在,则省略 `--milestone` 参数。
166
+
167
+ 不要依赖 `gh issue create --template`;本技能应直接解析 `.github/ISSUE_TEMPLATE/*.yml` 并生成最终 `--body`。
168
+
169
+ 记录命令输出的 Issue URL,并从末尾路径提取 Issue 编号:
170
+
171
+ ```bash
172
+ issue_url="$(gh issue create ...)"
173
+ issue_number="${issue_url##*/}"
174
+ ```
175
+
176
+ 如果已经确定了 `{issue-type}`,在创建后以 best-effort 方式设置 Issue Type:
177
+
178
+ 先获取仓库信息,后续 `in:` label 步骤也会复用:
179
+
180
+ ```bash
181
+ repo="$(gh repo view --json nameWithOwner --jq '.nameWithOwner')"
182
+ owner="${repo%%/*}"
183
+ ```
184
+
185
+ 查询组织可用的 Issue Types:
186
+
187
+ ```bash
188
+ gh api "orgs/$owner/issue-types" --jq '.[].name'
189
+ ```
190
+
191
+ 如果查询成功且 `{issue-type}` 在返回列表中,执行设置:
192
+
193
+ ```bash
194
+ gh api "repos/$repo/issues/{issue-number}" -X PATCH -f type="{issue-type}" --silent
195
+ ```
196
+
197
+ 验证设置结果:
198
+
199
+ ```bash
200
+ gh api "repos/$repo/issues/{issue-number}" --jq '.type.name // empty'
201
+ ```
202
+
203
+ 如果验证返回的名称与 `{issue-type}` 一致,记录 `Issue Type: {issue-type}`;否则记录 `Issue Type: failed to set`。
204
+
205
+ #### 添加 `in:` labels
206
+
207
+ 获取仓库中所有 `in:` 前缀的 labels:
208
+
209
+ ```bash
210
+ gh label list --search "in:" --limit 50 --json name --jq '.[].name'
211
+ ```
212
+
213
+ 如果没有 `in:` labels,跳过此步骤。
214
+
215
+ 如果存在 `in:` labels,结合任务上下文(标题、描述、受影响文件列表)判断每个 `in:` label 是否与当前任务相关。对判断为相关的 label,执行:
216
+
217
+ ```bash
218
+ gh issue edit {issue-number} --add-label "in: {module}"
219
+ ```
220
+
221
+ 记录所有成功添加的 `in:` labels。如果没有判断为相关的 label,记录 `in: labels: skipped (no relevant labels)`。
222
+
223
+ 容错要求:
224
+ - 如果 `orgs/$owner/issue-types` 返回 `404`、仓库 owner 不是组织,或仓库未启用 Issue Types,则跳过,不要让创建失败
225
+ - 如果目标 `{issue-type}` 不在可用列表中,则跳过
226
+ - `in:` label 添加失败时,跳过并记录,不阻止 Issue 创建流程
227
+ - Milestone 不存在或名称无效时,也应提示并跳过,而不是中断整个 Issue 创建流程
228
+
229
+ ### 5. 更新任务状态
230
+
231
+ 获取当前时间:
232
+
233
+ ```bash
234
+ date "+%Y-%m-%d %H:%M:%S"
235
+ ```
236
+
237
+ 更新 `.agent-workspace/active/{task-id}/task.md`:
238
+ - 添加或更新 `issue_number`:`{issue-number}`
239
+ - `updated_at`:{当前时间}
240
+ - **追加**到 `## Activity Log`(不要覆盖之前的记录):
241
+ ```
242
+ - {yyyy-MM-dd HH:mm:ss} — **Create Issue** by {agent} — Issue #{issue-number} created
243
+ ```
244
+
245
+ ### 6. 告知用户
246
+
247
+ > **重要**:以下「下一步」中列出的所有 TUI 命令格式必须完整输出,不要只展示当前 AI 代理对应的格式。
248
+
249
+ 输出格式:
250
+ ```
251
+ 任务 {task-id} 的 Issue 已创建。
252
+
253
+ Issue 信息:
254
+ - 编号:#{issue-number}
255
+ - URL:{issue-url}
256
+ - Labels:{applied-labels 或 skipped}
257
+ - in: Labels:{applied-in-labels 或 skipped}
258
+ - Issue Type:{issue-type | failed to set | skipped}
259
+ - Milestone:{milestone 或 skipped}
260
+
261
+ 产出:
262
+ - task.md 已回写 `issue_number`
263
+
264
+ 下一步 - 同步任务进度到 Issue:
265
+ - Claude Code / OpenCode:/sync-issue {task-id}
266
+ - Gemini CLI:/{{project}}:sync-issue {task-id}
267
+ - Codex CLI:$sync-issue {task-id}
268
+ ```
269
+
270
+ ## 完成检查清单
271
+
272
+ - [ ] 创建了 GitHub Issue
273
+ - [ ] 检测了项目 `ISSUE_TEMPLATE`
274
+ - [ ] 有模板时按模板结构生成正文;无模板时走 fallback / 兜底格式
275
+ - [ ] Issue 标题和正文仅来自 task.md
276
+ - [ ] 如可用,处理了 `type:` / Issue Type 和 `milestone`
277
+ - [ ] 处理了 `in:` labels(LLM 判断关联性)
278
+ - [ ] 在 task.md 中记录了 `issue_number`
279
+ - [ ] 更新了 task.md 中的 `updated_at`
280
+ - [ ] 追加了 Activity Log 条目到 task.md
281
+ - [ ] 告知了用户下一步(必须展示所有 TUI 的命令格式,不要筛选)
282
+ - [ ] **没有读取分析/方案/实现产物来构建 Issue**
283
+
284
+ ## 停止
285
+
286
+ 完成检查清单后,**立即停止**。不要继续同步 Issue 内容或执行后续工作流步骤。
287
+
288
+ ## 注意事项
289
+
290
+ 1. **职责边界**:`create-issue` 只负责创建基础 Issue;详细上下文同步由 `sync-issue` 负责
291
+ 2. **避免重复创建**:已有 `issue_number` 时,先与用户确认
292
+ 3. **Label 容错**:标准 label 未初始化时,可以跳过 label,但不要阻止 Issue 创建
293
+ 4. **模板容错**:模板缺失、匹配失败或 YAML 异常时,退回 fallback / 兜底正文,不要让整个创建失败
294
+ 5. **Issue Type / Milestone 容错**:Issue Type 未启用、类型不存在或 milestone 不可用时,跳过该项并继续创建
295
+ 6. **in: Label 容错**:`in:` label 添加失败时跳过,不阻止 Issue 创建
296
+
297
+ ## 错误处理
298
+
299
+ - 任务未找到:提示 `Task {task-id} not found`
300
+ - 未安装或未认证 `gh`:提示 `GitHub CLI is not available or not authenticated`
301
+ - 描述为空:提示 `Task description is empty, please update task.md first`
302
+ - 创建失败:提示 `Failed to create GitHub Issue`