@fitlab-ai/agent-infra 0.5.8 → 0.5.10

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 (67) hide show
  1. package/README.md +237 -5
  2. package/README.zh-CN.md +213 -5
  3. package/bin/cli.js +2 -2
  4. package/lib/init.js +18 -4
  5. package/lib/sandbox/commands/create.js +467 -240
  6. package/lib/sandbox/commands/enter.js +59 -26
  7. package/lib/sandbox/commands/ls.js +37 -6
  8. package/lib/sandbox/commands/rebuild.js +31 -15
  9. package/lib/sandbox/commands/refresh.js +119 -0
  10. package/lib/sandbox/commands/rm.js +59 -11
  11. package/lib/sandbox/commands/vm.js +56 -6
  12. package/lib/sandbox/config.js +9 -5
  13. package/lib/sandbox/constants.js +18 -3
  14. package/lib/sandbox/credentials.js +520 -0
  15. package/lib/sandbox/dotfiles.js +189 -0
  16. package/lib/sandbox/engine.js +135 -157
  17. package/lib/sandbox/engines/colima.js +79 -0
  18. package/lib/sandbox/engines/docker-desktop.js +34 -0
  19. package/lib/sandbox/engines/index.js +27 -0
  20. package/lib/sandbox/engines/native.js +112 -0
  21. package/lib/sandbox/engines/orbstack.js +76 -0
  22. package/lib/sandbox/engines/selinux.js +60 -0
  23. package/lib/sandbox/engines/wsl2-paths.js +59 -0
  24. package/lib/sandbox/engines/wsl2.js +72 -0
  25. package/lib/sandbox/index.js +10 -1
  26. package/lib/sandbox/runtimes/ai-tools.dockerfile +14 -1
  27. package/lib/sandbox/runtimes/base.dockerfile +125 -3
  28. package/lib/sandbox/shell.js +53 -2
  29. package/lib/sandbox/tools.js +5 -5
  30. package/package.json +8 -4
  31. package/templates/.agents/rules/create-issue.en.md +5 -0
  32. package/templates/.agents/rules/create-issue.github.en.md +176 -0
  33. package/templates/.agents/rules/create-issue.github.zh-CN.md +176 -0
  34. package/templates/.agents/rules/create-issue.zh-CN.md +5 -0
  35. package/templates/.agents/rules/issue-pr-commands.github.en.md +29 -0
  36. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +29 -0
  37. package/templates/.agents/rules/issue-sync.github.en.md +1 -1
  38. package/templates/.agents/rules/issue-sync.github.zh-CN.md +1 -1
  39. package/templates/.agents/rules/milestone-inference.github.en.md +2 -2
  40. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +2 -2
  41. package/templates/.agents/scripts/{platform-adapters/find-existing-task.github.js → find-existing-task.js} +22 -79
  42. package/templates/.agents/scripts/platform-adapters/platform-sync.github.js +72 -42
  43. package/templates/.agents/skills/create-task/SKILL.en.md +69 -11
  44. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +70 -12
  45. package/templates/.agents/skills/create-task/config/verify.json +6 -1
  46. package/templates/.agents/skills/implement-task/reference/implementation-rules.en.md +7 -12
  47. package/templates/.agents/skills/implement-task/reference/implementation-rules.zh-CN.md +7 -12
  48. package/templates/.agents/skills/import-issue/SKILL.en.md +7 -9
  49. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +7 -9
  50. package/templates/.agents/skills/refine-task/reference/fix-workflow.en.md +2 -2
  51. package/templates/.agents/skills/refine-task/reference/fix-workflow.zh-CN.md +2 -2
  52. package/templates/.agents/skills/test/SKILL.en.md +45 -6
  53. package/templates/.agents/skills/test/SKILL.zh-CN.md +45 -6
  54. package/templates/.agents/scripts/platform-adapters/find-existing-task.js +0 -5
  55. package/templates/.agents/skills/create-issue/SKILL.en.md +0 -118
  56. package/templates/.agents/skills/create-issue/SKILL.zh-CN.md +0 -118
  57. package/templates/.agents/skills/create-issue/config/verify.json +0 -30
  58. package/templates/.agents/skills/create-issue/reference/label-and-type.en.md +0 -71
  59. package/templates/.agents/skills/create-issue/reference/label-and-type.zh-CN.md +0 -71
  60. package/templates/.agents/skills/create-issue/reference/template-matching.en.md +0 -17
  61. package/templates/.agents/skills/create-issue/reference/template-matching.zh-CN.md +0 -17
  62. package/templates/.claude/commands/create-issue.en.md +0 -8
  63. package/templates/.claude/commands/create-issue.zh-CN.md +0 -8
  64. package/templates/.gemini/commands/_project_/create-issue.en.toml +0 -8
  65. package/templates/.gemini/commands/_project_/create-issue.zh-CN.toml +0 -8
  66. package/templates/.opencode/commands/create-issue.en.md +0 -11
  67. package/templates/.opencode/commands/create-issue.zh-CN.md +0 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fitlab-ai/agent-infra",
3
- "version": "0.5.8",
3
+ "version": "0.5.10",
4
4
  "description": "Bootstrap tool for AI multi-tool collaboration infrastructure — works with Claude Code, Codex, Gemini CLI, and OpenCode",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -27,7 +27,7 @@
27
27
  "templates/"
28
28
  ],
29
29
  "engines": {
30
- "node": ">=18"
30
+ "node": ">=22"
31
31
  },
32
32
  "keywords": [
33
33
  "ai",
@@ -41,13 +41,17 @@
41
41
  "installer"
42
42
  ],
43
43
  "dependencies": {
44
- "@clack/prompts": "1.2.0",
45
- "picocolors": "1.1.1"
44
+ "@clack/prompts": "1.4.0",
45
+ "cross-spawn": "^7.0.6",
46
+ "picocolors": "1.1.1",
47
+ "smol-toml": "^1.6.1"
46
48
  },
47
49
  "scripts": {
48
50
  "build": "node scripts/build-inline.js",
49
51
  "demo:regen": "sh scripts/demo-regen.sh",
50
52
  "prepare": "git config core.hooksPath .git-hooks || true",
53
+ "test:smoke": "node scripts/build-inline.js --check && node --test tests/templates/*.test.js tests/core/airc.test.js tests/core/release.test.js tests/core/metadata-sync-workflow.test.js tests/core/pr-label-workflow.test.js tests/core/status-label-workflow.test.js tests/core/test-tier-coverage.test.js tests/cli/lib.test.js tests/cli/sync-templates.test.js tests/scripts/sync-templates-platform-gating.test.js",
54
+ "test:core": "node scripts/build-inline.js --check && node --test tests/templates/*.test.js tests/core/airc.test.js tests/core/release.test.js tests/core/metadata-sync-workflow.test.js tests/core/pr-label-workflow.test.js tests/core/status-label-workflow.test.js tests/core/test-tier-coverage.test.js tests/cli/lib.test.js tests/cli/sync-templates.test.js tests/scripts/sync-templates-platform-gating.test.js tests/cli/cli.test.js tests/cli/merge.test.js tests/cli/sandbox.test.js tests/core/custom-skills.test.js tests/core/custom-tuis.test.js tests/core/demo-regen.test.js tests/scripts/find-existing-task.test.js tests/scripts/platform-adapter-defaults.test.js",
51
55
  "test": "node scripts/build-inline.js --check && node --test tests/cli/*.test.js tests/templates/*.test.js tests/core/*.test.js tests/scripts/*.test.js",
52
56
  "prepublishOnly": "node scripts/build-inline.js --check && node --test tests/cli/*.test.js tests/templates/*.test.js tests/core/*.test.js tests/scripts/*.test.js"
53
57
  }
@@ -0,0 +1,5 @@
1
+ # Issue Creation
2
+
3
+ This code platform does not provide an Issue creation rule.
4
+
5
+ `create-task` skips the cascade Issue creation step on this platform; the local `task.md` remains a valid artifact. If you later want to bind the task to an Issue, manually write `issue_number` into `task.md` and the subsequent skills (`commit` / `refine-task` / `complete-task`, etc.) will pick up Issue metadata syncing through the existing cascade rules.
@@ -0,0 +1,176 @@
1
+ # Issue Creation
2
+
3
+ After `create-task` writes the local `task.md`, follow this rule to cascade Issue creation. This rule is referenced internally by `create-task` SKILL.md only; do not invoke it standalone.
4
+
5
+ ## Boundary
6
+
7
+ - Issue title and body must come from `task.md` only
8
+ - Do not read `analysis.md`, `plan.md`, `implementation.md`, or any review artifact
9
+ - Persistent outputs are limited to the remote Issue and the `issue_number` written back to `task.md`
10
+ - If Issue creation fails, do not roll back `task.md`; the current task remains valid for the workflow, and the user can later manually fill `issue_number` so other skills' cascade sync takes over
11
+
12
+ ## Steps
13
+
14
+ ### 1. Verify Prerequisites
15
+
16
+ - `.agents/workspace/active/{task-id}/task.md` must exist
17
+ - Read `.agents/rules/issue-pr-commands.md` first and run its authentication and platform detection commands to confirm `gh auth status` and the current repository are usable
18
+ - Read `.agents/rules/issue-sync.md` first and complete `upstream_repo`, `has_triage`, and `has_push` detection; reuse these variables for every later `gh issue` and repo-level `gh api` call
19
+ - If `task.md` already has a non-empty, non-`N/A` `issue_number`, halt the cascade immediately: return "Task already linked to Issue #{n}, skipping creation" to `create-task` and let it decide how to continue
20
+
21
+ ### 2. Extract Task Information
22
+
23
+ Pull the following from `task.md`:
24
+
25
+ - Task title (the first `# ` heading, stripped of `任务:` / `Task:` prefixes)
26
+ - The `## Description` / `## 描述` section
27
+ - The `## Requirements` / `## 需求` section
28
+ - frontmatter fields `type` and (optionally) `milestone`
29
+
30
+ Build the Issue title:
31
+
32
+ | task.md `type` | Conventional Commits type |
33
+ |---|---|
34
+ | `feature` | `feat` |
35
+ | `bugfix`, `bug` | `fix` |
36
+ | `refactor`, `refactoring` | `refactor` |
37
+ | `docs`, `documentation` | `docs` |
38
+ | `chore`, `task`, others | `chore` |
39
+
40
+ Scope inference: read known module names from `.agents/.airc.json`'s `labels.in` field, then semantically match them against the task title and description; omit `scope` when there is no clear hit. Final title: `{cc_type}({scope}): {task_title}` or `{cc_type}: {task_title}` (preserve the task title verbatim — do not translate or rewrite).
41
+
42
+ ### 3. Build the Issue Body
43
+
44
+ Issue Form detection: follow the "Issue Template Detection" section in `.agents/rules/issue-pr-commands.md` to scan `.github/ISSUE_TEMPLATE/*.yml` (excluding `config.yml`).
45
+
46
+ #### Scenario A: A matching template was detected
47
+
48
+ Pick the form whose `name` (or filename) best matches the task type (e.g., a task with `type: bugfix` prefers a form whose name contains `bug`); if no match, fall back to a generic form like `other.yml`; if none, take the first form in the directory.
49
+
50
+ Populate the form by following the field-handling rules in `.agents/rules/issue-pr-commands.md` § "Issue Template Detection":
51
+
52
+ - `textarea` / `input` fields: use `attributes.label` as a markdown heading and pull values from task.md
53
+ - `markdown` fields: skip (these are description blurbs)
54
+ - `dropdown` / `checkboxes` fields: skip
55
+
56
+ Recommended field-to-source mapping:
57
+
58
+ | Template field hint | Source in task.md |
59
+ |---|---|
60
+ | `summary`, `title` | task title |
61
+ | `description`, `problem`, `what happened`, `issue-description`, `current-content` | task description |
62
+ | `solution`, `requirements`, `steps`, `suggested-content`, `impact`, `context`, `alternatives`, `expected` | requirements list (preserve checked / unchecked state as-is) |
63
+ | Other `textarea` / `input` fields | task description, or `N/A` if missing |
64
+
65
+ Whenever task.md does not provide a usable value, write `N/A`.
66
+
67
+ #### Scenario B: No template, or template parsing failed
68
+
69
+ Fall back to the default body:
70
+
71
+ ```markdown
72
+ ## Description
73
+
74
+ {task description, or N/A if missing}
75
+
76
+ ## Requirements
77
+
78
+ - [ ] {requirement-1}
79
+ - [ ] {requirement-2}
80
+ ```
81
+
82
+ If the requirements list is empty, write `N/A` in that section.
83
+
84
+ ### 4. Resolve labels / Issue Type / milestone
85
+
86
+ #### labels (rough pass)
87
+
88
+ - Call `gh api "repos/$upstream_repo/labels?per_page=100" --jq '.[].name'` to fetch the actual labels in the repo (cache as a set)
89
+ - Pick the "expected type label" using the mapping below, keeping only those that exist in the repo set:
90
+
91
+ | task.md `type` | label |
92
+ |---|---|
93
+ | `bug`, `bugfix` | `type: bug` |
94
+ | `feature` | `type: feature` |
95
+ | `enhancement` | `type: enhancement` |
96
+ | `docs`, `documentation` | `type: documentation` |
97
+ | `dependency-upgrade` | `type: dependency-upgrade` |
98
+ | `task`, `chore` | `type: task` |
99
+ | `refactor`, `refactoring` | `type: enhancement` |
100
+ | others | skip |
101
+
102
+ - `in:` labels (rough pass — when in doubt, leave it out): semantically match the task title and description against module names from `labels.in`; explicit mention or strong implication → add `in: {module}`; vague or uncertain → skip. `in:` labels also require the label to actually exist in the repo.
103
+
104
+ If the final label set is empty, omit the `--label` argument.
105
+
106
+ #### Issue Type fallback
107
+
108
+ | task.md `type` | Issue Type |
109
+ |---|---|
110
+ | `bug`, `bugfix` | `Bug` |
111
+ | `feature`, `enhancement` | `Feature` |
112
+ | `task`, `documentation`, `dependency-upgrade`, `chore`, `docs`, `refactor`, `refactoring`, others | `Task` |
113
+
114
+ When applying the Issue Type, follow the "Set Issue Type" command in `.agents/rules/issue-pr-commands.md`; first call `gh api orgs/{owner}/issue-types` to list the org's actually available Types, and only set the inferred value when it is present in that list. Failure to set is non-blocking.
115
+
116
+ #### milestone
117
+
118
+ Infer per `.agents/rules/milestone-inference.md` § "Stage 1: `create-task` (when the platform rule creates the Issue)". When the inference is empty or the repo lacks a matching milestone, omit the milestone.
119
+
120
+ ### 5. Call the GitHub CLI to Create the Issue
121
+
122
+ Run the "Create Issue" command from `.agents/rules/issue-pr-commands.md`:
123
+
124
+ ```bash
125
+ gh issue create -R "$upstream_repo" \
126
+ --title "{title}" \
127
+ --body "{body}" \
128
+ --assignee @me \
129
+ {label-args} \
130
+ {milestone-arg}
131
+ ```
132
+
133
+ - `{label-args}` is expanded from the result of §4 into multiple `--label "..."`; if empty, omit the entire argument
134
+ - `{milestone-arg}` is only expanded to `--milestone "..."` when `has_triage=true` and milestone is non-empty; otherwise omit
135
+ - `--assignee @me` requires no permission probe; on failure, skip silently
136
+
137
+ Permission downgrade follows `.agents/rules/issue-sync.md`: `has_triage=false` skips label / milestone settings; `has_push=false` skips Issue Type setting; the rest continues.
138
+
139
+ After success, parse the Issue number from the output (match only the `https://.../issues/(\d+)` URL form; do not use a loose regex). If parsing fails, halt the cascade and propagate the error back to `create-task`.
140
+
141
+ ### 6. Set Issue Type (Optional)
142
+
143
+ Execute only when `has_push=true` and the Issue Type inferred in §4 is in the org's actually available list:
144
+
145
+ ```bash
146
+ gh api "repos/$upstream_repo/issues/{issue-number}" -X PATCH \
147
+ -f type="{issue-type}" --silent
148
+ ```
149
+
150
+ Failure is non-blocking.
151
+
152
+ ### 7. Write Back task.md
153
+
154
+ Update task.md:
155
+
156
+ - Write `issue_number: {n}` into the frontmatter (replace if it exists; append at the end of the frontmatter otherwise)
157
+ - Update `updated_at` to the current time (command: `date "+%Y-%m-%d %H:%M:%S%:z"`)
158
+
159
+ > Do NOT append an Activity Log entry here. The Issue creation event is already captured by the GitHub Issue itself and by the frontmatter `issue_number` field; the Activity Log only records the single `create-task` skill execution anchor (`Task Created`), written by the caller SKILL step 3.
160
+
161
+ ### 8. Return the Result
162
+
163
+ Hand the following back to the caller `create-task`:
164
+
165
+ - Issue number `{n}`
166
+ - Issue URL (prefer the URL printed by `gh issue create`; fall back to `https://github.com/$upstream_repo/issues/{n}`)
167
+ - The labels / milestone / Issue Type that were actually applied
168
+
169
+ `create-task` uses these to pick the "Scenario A: Issue created" output branch and continue with task comment sync and status label setup.
170
+
171
+ ## Error Handling
172
+
173
+ - Auth failure / command unavailable: return a structured `{code: "AUTH_FAILED", message}` to `create-task`; do not modify task.md
174
+ - Network timeout / DNS failure: `{code: "NETWORK", message}`
175
+ - Template parsing failure, Issue number parsing failure, other anomalies: `{code: "VALIDATION", message}`
176
+ - All failures keep task.md untouched; `create-task` takes the "Scenario C: failure fallback" output branch and prompts the user to retry manually or fill `issue_number` later
@@ -0,0 +1,176 @@
1
+ # Issue 创建
2
+
3
+ 当 `create-task` 完成本地 `task.md` 落盘后,按本规则级联创建 Issue。本规则仅由 `create-task` SKILL.md 内部引用,不应独立调用。
4
+
5
+ ## 行为边界
6
+
7
+ - Issue 标题和正文只能来自 `task.md`
8
+ - 不读取 `analysis.md`、`plan.md`、`implementation.md` 或审查产物
9
+ - 持久产物只有:远端 Issue + `task.md` 中回写的 `issue_number`
10
+ - Issue 创建失败时不回滚 `task.md`;当前 task 仍可继续后续工作流,未来可由用户手动写入 `issue_number`,让其它技能的级联同步接管
11
+
12
+ ## 执行步骤
13
+
14
+ ### 1. 验证前置条件
15
+
16
+ - `.agents/workspace/active/{task-id}/task.md` 必须存在
17
+ - 先读取 `.agents/rules/issue-pr-commands.md`,按其中的认证与平台检测命令验证 `gh auth status` 和当前仓库可用
18
+ - 先读取 `.agents/rules/issue-sync.md`,完成 `upstream_repo`、`has_triage`、`has_push` 检测;后续所有 `gh issue` 与 repo 级 `gh api` 调用都复用这些变量
19
+ - 如果 `task.md` 中 `issue_number` 已存在且既不为空也不为 `N/A`,立即停止级联:返回"任务已绑定 Issue #{n},跳过创建"信息给 `create-task`,由调用方决定如何继续
20
+
21
+ ### 2. 提取任务信息
22
+
23
+ 从 `task.md` 提取以下字段:
24
+
25
+ - 任务标题(首个 `# ` 标题,去掉 `任务:` / `Task:` 前缀)
26
+ - `## Description` / `## 描述` 段落
27
+ - `## Requirements` / `## 需求` 段落
28
+ - frontmatter 中的 `type` 与(可选的)`milestone`
29
+
30
+ 构造 Issue 标题:
31
+
32
+ | task.md `type` | Conventional Commits type |
33
+ |---|---|
34
+ | `feature` | `feat` |
35
+ | `bugfix`, `bug` | `fix` |
36
+ | `refactor`, `refactoring` | `refactor` |
37
+ | `docs`, `documentation` | `docs` |
38
+ | `chore`, `task` 或其它 | `chore` |
39
+
40
+ scope 推断:从 `.agents/.airc.json` 的 `labels.in` 字段读取已知模块名,再与任务标题/描述做语义匹配;没有清晰命中时省略 scope。最终标题:`{cc_type}({scope}): {task_title}` 或 `{cc_type}: {task_title}`(任务标题保留原文,不要翻译或改写)。
41
+
42
+ ### 3. 构建 Issue 正文
43
+
44
+ Issue 模板检测:按 `.agents/rules/issue-pr-commands.md` 的 "Issue 模板检测" 规则扫描 `.github/ISSUE_TEMPLATE/*.yml`(排除 `config.yml`)。
45
+
46
+ #### 场景 A:检测到匹配模板
47
+
48
+ 按模板顶层 `name` 与任务类型挑选最匹配的 form(如任务 `type: bugfix` 优先选名称含 `bug` 的模板);找不到匹配时,回退到通用 form(如 `other.yml`),仍找不到时取目录中第一个 form。
49
+
50
+ 按 `.agents/rules/issue-pr-commands.md` 中 "Issue 模板检测" 章节的字段处理规则填充 form:
51
+
52
+ - `textarea` / `input` 字段:使用 `attributes.label` 作为 markdown 标题,从 task.md 取值
53
+ - `markdown` 字段:跳过(说明文案)
54
+ - `dropdown` / `checkboxes` 字段:跳过
55
+
56
+ 字段值映射(建议):
57
+
58
+ | 模板字段提示 | task.md 来源 |
59
+ |---|---|
60
+ | `summary`, `title` | 任务标题 |
61
+ | `description`, `problem`, `what happened`, `issue-description`, `current-content` | 任务描述 |
62
+ | `solution`, `requirements`, `steps`, `suggested-content`, `impact`, `context`, `alternatives`, `expected` | 需求列表(已勾选与未勾选混合,原样保留) |
63
+ | 其它 `textarea` / `input` 字段 | 任务描述;缺失时填 `N/A` |
64
+
65
+ 任何字段在 task.md 中找不到合适值时,写入 `N/A`。
66
+
67
+ #### 场景 B:无模板或解析失败
68
+
69
+ 回退到默认正文:
70
+
71
+ ```markdown
72
+ ## Description
73
+
74
+ {任务描述;缺失时填 N/A}
75
+
76
+ ## Requirements
77
+
78
+ - [ ] {requirement-1}
79
+ - [ ] {requirement-2}
80
+ ```
81
+
82
+ 需求列表为空时,整段写 `N/A`。
83
+
84
+ ### 4. 解析 labels / Issue Type / milestone
85
+
86
+ #### labels(粗选)
87
+
88
+ - 调用 `gh api "repos/$upstream_repo/labels?per_page=100" --jq '.[].name'` 获取仓库实际存在的 label 列表(缓存为 set)
89
+ - 按以下映射挑出"应有的 type label",仅保留仓库 set 中实际存在的:
90
+
91
+ | task.md `type` | label |
92
+ |---|---|
93
+ | `bug`, `bugfix` | `type: bug` |
94
+ | `feature` | `type: feature` |
95
+ | `enhancement` | `type: enhancement` |
96
+ | `docs`, `documentation` | `type: documentation` |
97
+ | `dependency-upgrade` | `type: dependency-upgrade` |
98
+ | `task`, `chore` | `type: task` |
99
+ | `refactor`, `refactoring` | `type: enhancement` |
100
+ | 其它 | 跳过 |
101
+
102
+ - `in:` label(粗选,宁缺毋滥):根据任务标题与描述对 `labels.in` 中的模块名做语义匹配;明确提及或强烈暗示 → 添加 `in: {module}`;模糊或不确定 → 不添加。`in:` label 同样要求仓库实际存在。
103
+
104
+ 最终 label 集合若为空,省略 `--label` 参数。
105
+
106
+ #### Issue Type fallback
107
+
108
+ | task.md `type` | Issue Type |
109
+ |---|---|
110
+ | `bug`, `bugfix` | `Bug` |
111
+ | `feature`, `enhancement` | `Feature` |
112
+ | `task`, `documentation`, `dependency-upgrade`, `chore`, `docs`, `refactor`, `refactoring` 及其它 | `Task` |
113
+
114
+ 实际设置时按 `.agents/rules/issue-pr-commands.md` 的 "设置 Issue Type" 命令;先调 `gh api orgs/{owner}/issue-types` 列出 org 实际可用的 Type,仅当推断值在列表中时才设置;设置失败不阻断流程。
115
+
116
+ #### milestone
117
+
118
+ 按 `.agents/rules/milestone-inference.md` 的 "阶段 1:`create-task`(平台规则创建 Issue 时)" 规则推断;推断结果为空或仓库无对应 milestone 时省略。
119
+
120
+ ### 5. 调用 GitHub CLI 创建 Issue
121
+
122
+ 按 `.agents/rules/issue-pr-commands.md` 中的 "创建 Issue" 命令执行:
123
+
124
+ ```bash
125
+ gh issue create -R "$upstream_repo" \
126
+ --title "{title}" \
127
+ --body "{body}" \
128
+ --assignee @me \
129
+ {label-args} \
130
+ {milestone-arg}
131
+ ```
132
+
133
+ - `{label-args}` 由 §4 计算结果展开为多个 `--label "..."`;为空则整体省略
134
+ - `{milestone-arg}` 仅当 `has_triage=true` 且 milestone 非空时展开为 `--milestone "..."`;否则整体省略
135
+ - `--assignee @me` 不做权限预判,失败时静默跳过
136
+
137
+ 权限降级规则按 `.agents/rules/issue-sync.md`:`has_triage=false` 时跳过 label / milestone 设置;`has_push=false` 时跳过 Issue Type 设置;其余流程继续。
138
+
139
+ 创建成功后从输出中解析 Issue 编号(仅匹配 `https://.../issues/(\d+)` URL 形式,不要使用宽松正则);解析失败时停止级联并把错误传回 `create-task`。
140
+
141
+ ### 6. 设置 Issue Type(可选)
142
+
143
+ 仅当 `has_push=true` 且 §4 推断的 Issue Type 在 org 实际可用列表中时执行:
144
+
145
+ ```bash
146
+ gh api "repos/$upstream_repo/issues/{issue-number}" -X PATCH \
147
+ -f type="{issue-type}" --silent
148
+ ```
149
+
150
+ 设置失败不阻断流程。
151
+
152
+ ### 7. 回写 task.md
153
+
154
+ 更新 task.md:
155
+
156
+ - 把 `issue_number: {n}` 写入 frontmatter(已存在则替换;不存在则在 frontmatter 末尾追加)
157
+ - 更新 `updated_at` 为当前时间(命令:`date "+%Y-%m-%d %H:%M:%S%:z"`)
158
+
159
+ > 不要在此追加 Activity Log 条目。Issue 创建事件已由 GitHub Issue 自身和 frontmatter `issue_number` 承载;Activity Log 仅记录 `create-task` skill 一次执行的整体锚点(`Task Created`),由调用方 SKILL 步骤 3 写入。
160
+
161
+ ### 8. 返回结果
162
+
163
+ 把以下信息回传给调用方 `create-task`:
164
+
165
+ - Issue 编号 `{n}`
166
+ - Issue URL(首选 `gh issue create` 输出中的 URL;缺失时拼 `https://github.com/$upstream_repo/issues/{n}`)
167
+ - 实际应用的 labels / milestone / Issue Type
168
+
169
+ `create-task` 据此选择"场景 A:已创建 Issue"输出分支并继续执行后续 task 评论同步与 status label 设置。
170
+
171
+ ## 错误处理
172
+
173
+ - 认证失败 / 命令不可用:返回结构化错误 `{code: "AUTH_FAILED", message}` 给 `create-task`,不修改 task.md
174
+ - 网络超时 / DNS 失败:`{code: "NETWORK", message}`
175
+ - 模板解析失败、Issue 编号解析失败、其它异常:`{code: "VALIDATION", message}`
176
+ - 任意失败均不回滚 task.md;`create-task` 走"场景 C 失败兜底"输出,提示用户手动重试或在事后写入 `issue_number`
@@ -0,0 +1,5 @@
1
+ # Issue 创建
2
+
3
+ 当前代码平台未提供 Issue 创建规则。
4
+
5
+ `create-task` 在本平台上会跳过级联创建 Issue 步骤;本地 `task.md` 仍然是有效产物。如果将来需要把任务绑定到一个 Issue,可手动在 `task.md` 中写入 `issue_number`,后续技能(`commit` / `refine-task` / `complete-task` 等)会按既有的级联同步规则自动接管 Issue 元数据更新。
@@ -120,6 +120,35 @@ Read Issue comments or search for existing hidden markers:
120
120
  gh api "repos/$upstream_repo/issues/{issue-number}/comments" --paginate
121
121
  ```
122
122
 
123
+ ## Historical Task Comment Scan
124
+
125
+ `find-existing-task.js` only consumes stdin and does not call `gh` directly. The AI selects the pipeline command for the host OS.
126
+
127
+ POSIX (bash / zsh):
128
+
129
+ ```bash
130
+ set -o pipefail
131
+ gh api "repos/$upstream_repo/issues/{issue-number}/comments" \
132
+ --paginate --jq '.[] | @json' \
133
+ | node .agents/scripts/find-existing-task.js
134
+ ```
135
+
136
+ Windows (PowerShell 7+ / pwsh):
137
+
138
+ ```powershell
139
+ $ErrorActionPreference = 'Stop'
140
+ gh api "repos/$upstream_repo/issues/{issue-number}/comments" `
141
+ --paginate --jq '.[] | @json' |
142
+ node .agents/scripts/find-existing-task.js
143
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
144
+ ```
145
+
146
+ On PowerShell 5.1, explicitly enable UTF-8 stdio first; otherwise the pipe may corrupt multibyte characters:
147
+
148
+ ```powershell
149
+ [Console]::OutputEncoding = $OutputEncoding = [System.Text.UTF8Encoding]::new()
150
+ ```
151
+
123
152
  ## PR Template and Metadata Helpers
124
153
 
125
154
  Read a repository PR template when present:
@@ -120,6 +120,35 @@ gh issue close {issue-number} -R "$upstream_repo" --reason "{reason}"
120
120
  gh api "repos/$upstream_repo/issues/{issue-number}/comments" --paginate
121
121
  ```
122
122
 
123
+ ## 历史任务评论扫描
124
+
125
+ `find-existing-task.js` 仅消费 stdin,不直接调用 `gh`。由 AI 按宿主 OS 选择下面的 pipeline 命令。
126
+
127
+ POSIX(bash / zsh):
128
+
129
+ ```bash
130
+ set -o pipefail
131
+ gh api "repos/$upstream_repo/issues/{issue-number}/comments" \
132
+ --paginate --jq '.[] | @json' \
133
+ | node .agents/scripts/find-existing-task.js
134
+ ```
135
+
136
+ Windows(PowerShell 7+ / pwsh):
137
+
138
+ ```powershell
139
+ $ErrorActionPreference = 'Stop'
140
+ gh api "repos/$upstream_repo/issues/{issue-number}/comments" `
141
+ --paginate --jq '.[] | @json' |
142
+ node .agents/scripts/find-existing-task.js
143
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
144
+ ```
145
+
146
+ 在 PowerShell 5.1 上需先显式启用 UTF-8 stdio,否则 pipe 可能损坏多字节字符:
147
+
148
+ ```powershell
149
+ [Console]::OutputEncoding = $OutputEncoding = [System.Text.UTF8Encoding]::new()
150
+ ```
151
+
123
152
  ## PR 模板与元数据辅助命令
124
153
 
125
154
  存在仓库 PR 模板时读取:
@@ -115,7 +115,7 @@ If `gh` fails, skip and continue. Do not fail the skill.
115
115
 
116
116
  When a skill creates or imports an Issue, automatically add the current executor as assignee:
117
117
 
118
- - `create-issue`: use `--assignee @me` in `gh issue create` and include `-R "$upstream_repo"`
118
+ - When the `create-task` platform rule triggers Issue creation: use `--assignee @me` in `gh issue create` and include `-R "$upstream_repo"`
119
119
  - `import-issue`: run `gh issue edit {issue-number} -R "$upstream_repo" --add-assignee @me 2>/dev/null || true` after import
120
120
 
121
121
  `@me` is resolved by `gh` CLI to the authenticated user. The operation is idempotent. If the command fails, skip it directly and do not provide a fallback path.
@@ -115,7 +115,7 @@ fi
115
115
 
116
116
  当技能创建或导入 Issue 时,自动将当前执行者添加为 assignee:
117
117
 
118
- - `create-issue`:在 `gh issue create` 命令中使用 `--assignee @me` 参数,并附带 `-R "$upstream_repo"`
118
+ - `create-task` 的平台规则触发 Issue 创建时:在 `gh issue create` 命令中使用 `--assignee @me` 参数,并附带 `-R "$upstream_repo"`
119
119
  - `import-issue`:导入后执行 `gh issue edit {issue-number} -R "$upstream_repo" --add-assignee @me 2>/dev/null || true`
120
120
 
121
121
  `@me` 由 `gh` CLI 自动解析为当前认证用户。此操作是幂等的(重复添加不会报错)。如果命令失败(如权限不足),直接跳过,不做任何替代。
@@ -1,6 +1,6 @@
1
1
  # Milestone Inference Rules
2
2
 
3
- Read this file before `create-issue`, `implement-task`, or `create-pr` handles a milestone.
3
+ Read this file before the `create-task` platform rule, `implement-task`, or `create-pr` handles a milestone.
4
4
 
5
5
  ## General Principles
6
6
 
@@ -21,7 +21,7 @@ git branch -r | grep -v 'HEAD' | grep -E 'origin/[0-9]+\.[0-9]+\.x$'
21
21
  - Any output: multi-version branch mode
22
22
  - No output: trunk mode
23
23
 
24
- ## Phase 1: `create-issue`
24
+ ## Phase 1: `create-task` (when the platform rule creates an Issue)
25
25
 
26
26
  Goal: choose a coarse-grained release line when the Issue is created.
27
27
 
@@ -1,6 +1,6 @@
1
1
  # Milestone 推断规则
2
2
 
3
- 在 `create-issue`、`implement-task` 或 `create-pr` 处理 milestone 之前先读取本文件。
3
+ 在 `create-task` 的平台规则、`implement-task` 或 `create-pr` 处理 milestone 之前先读取本文件。
4
4
 
5
5
  ## 通用原则
6
6
 
@@ -21,7 +21,7 @@ git branch -r | grep -v 'HEAD' | grep -E 'origin/[0-9]+\.[0-9]+\.x$'
21
21
  - 有输出:多版本分支模式
22
22
  - 无输出:主干模式
23
23
 
24
- ## 阶段 1:`create-issue`
24
+ ## 阶段 1:`create-task`(平台规则创建 Issue 时)
25
25
 
26
26
  目标:在创建 Issue 时先确定粗粒度版本线。
27
27