@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.
- package/README.md +237 -5
- package/README.zh-CN.md +213 -5
- package/bin/cli.js +2 -2
- package/lib/init.js +18 -4
- package/lib/sandbox/commands/create.js +467 -240
- package/lib/sandbox/commands/enter.js +59 -26
- package/lib/sandbox/commands/ls.js +37 -6
- package/lib/sandbox/commands/rebuild.js +31 -15
- package/lib/sandbox/commands/refresh.js +119 -0
- package/lib/sandbox/commands/rm.js +59 -11
- package/lib/sandbox/commands/vm.js +56 -6
- package/lib/sandbox/config.js +9 -5
- package/lib/sandbox/constants.js +18 -3
- package/lib/sandbox/credentials.js +520 -0
- package/lib/sandbox/dotfiles.js +189 -0
- package/lib/sandbox/engine.js +135 -157
- package/lib/sandbox/engines/colima.js +79 -0
- package/lib/sandbox/engines/docker-desktop.js +34 -0
- package/lib/sandbox/engines/index.js +27 -0
- package/lib/sandbox/engines/native.js +112 -0
- package/lib/sandbox/engines/orbstack.js +76 -0
- package/lib/sandbox/engines/selinux.js +60 -0
- package/lib/sandbox/engines/wsl2-paths.js +59 -0
- package/lib/sandbox/engines/wsl2.js +72 -0
- package/lib/sandbox/index.js +10 -1
- package/lib/sandbox/runtimes/ai-tools.dockerfile +14 -1
- package/lib/sandbox/runtimes/base.dockerfile +125 -3
- package/lib/sandbox/shell.js +53 -2
- package/lib/sandbox/tools.js +5 -5
- package/package.json +8 -4
- package/templates/.agents/rules/create-issue.en.md +5 -0
- package/templates/.agents/rules/create-issue.github.en.md +176 -0
- package/templates/.agents/rules/create-issue.github.zh-CN.md +176 -0
- package/templates/.agents/rules/create-issue.zh-CN.md +5 -0
- package/templates/.agents/rules/issue-pr-commands.github.en.md +29 -0
- package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +29 -0
- package/templates/.agents/rules/issue-sync.github.en.md +1 -1
- package/templates/.agents/rules/issue-sync.github.zh-CN.md +1 -1
- package/templates/.agents/rules/milestone-inference.github.en.md +2 -2
- package/templates/.agents/rules/milestone-inference.github.zh-CN.md +2 -2
- package/templates/.agents/scripts/{platform-adapters/find-existing-task.github.js → find-existing-task.js} +22 -79
- package/templates/.agents/scripts/platform-adapters/platform-sync.github.js +72 -42
- package/templates/.agents/skills/create-task/SKILL.en.md +69 -11
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +70 -12
- package/templates/.agents/skills/create-task/config/verify.json +6 -1
- package/templates/.agents/skills/implement-task/reference/implementation-rules.en.md +7 -12
- package/templates/.agents/skills/implement-task/reference/implementation-rules.zh-CN.md +7 -12
- package/templates/.agents/skills/import-issue/SKILL.en.md +7 -9
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +7 -9
- package/templates/.agents/skills/refine-task/reference/fix-workflow.en.md +2 -2
- package/templates/.agents/skills/refine-task/reference/fix-workflow.zh-CN.md +2 -2
- package/templates/.agents/skills/test/SKILL.en.md +45 -6
- package/templates/.agents/skills/test/SKILL.zh-CN.md +45 -6
- package/templates/.agents/scripts/platform-adapters/find-existing-task.js +0 -5
- package/templates/.agents/skills/create-issue/SKILL.en.md +0 -118
- package/templates/.agents/skills/create-issue/SKILL.zh-CN.md +0 -118
- package/templates/.agents/skills/create-issue/config/verify.json +0 -30
- package/templates/.agents/skills/create-issue/reference/label-and-type.en.md +0 -71
- package/templates/.agents/skills/create-issue/reference/label-and-type.zh-CN.md +0 -71
- package/templates/.agents/skills/create-issue/reference/template-matching.en.md +0 -17
- package/templates/.agents/skills/create-issue/reference/template-matching.zh-CN.md +0 -17
- package/templates/.claude/commands/create-issue.en.md +0 -8
- package/templates/.claude/commands/create-issue.zh-CN.md +0 -8
- package/templates/.gemini/commands/_project_/create-issue.en.toml +0 -8
- package/templates/.gemini/commands/_project_/create-issue.zh-CN.toml +0 -8
- package/templates/.opencode/commands/create-issue.en.md +0 -11
- 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.
|
|
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": ">=
|
|
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.
|
|
45
|
-
"
|
|
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`
|
|
@@ -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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
24
|
+
## 阶段 1:`create-task`(平台规则创建 Issue 时)
|
|
25
25
|
|
|
26
26
|
目标:在创建 Issue 时先确定粗粒度版本线。
|
|
27
27
|
|