@fitlab-ai/agent-infra 0.6.2 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -3
- package/README.zh-CN.md +10 -3
- package/bin/cli.ts +6 -1
- package/dist/bin/cli.js +6 -1
- package/dist/lib/sandbox/clipboard/bridge.js +218 -0
- package/dist/lib/sandbox/clipboard/darwin.js +66 -0
- package/dist/lib/sandbox/clipboard/index.js +9 -0
- package/dist/lib/sandbox/clipboard/keys.js +58 -0
- package/dist/lib/sandbox/clipboard/node-pty.js +13 -0
- package/dist/lib/sandbox/clipboard/paths.js +59 -0
- package/dist/lib/sandbox/commands/create.js +15 -2
- package/dist/lib/sandbox/commands/enter.js +14 -3
- package/dist/lib/sandbox/commands/ls.js +19 -4
- package/dist/lib/sandbox/commands/prune.js +176 -0
- package/dist/lib/sandbox/commands/rm.js +27 -33
- package/dist/lib/sandbox/config.js +1 -0
- package/dist/lib/sandbox/constants.js +6 -0
- package/dist/lib/sandbox/host-timezone.js +33 -0
- package/dist/lib/sandbox/index.js +7 -1
- package/dist/lib/sandbox/managed-fs.js +25 -0
- package/dist/lib/sandbox/runtimes/base.dockerfile +21 -16
- package/dist/lib/sandbox/tools.js +1 -1
- package/dist/lib/version.js +9 -2
- package/lib/sandbox/clipboard/bridge.ts +286 -0
- package/lib/sandbox/clipboard/darwin.ts +91 -0
- package/lib/sandbox/clipboard/index.ts +13 -0
- package/lib/sandbox/clipboard/keys.ts +78 -0
- package/lib/sandbox/clipboard/node-pty.d.ts +19 -0
- package/lib/sandbox/clipboard/node-pty.ts +34 -0
- package/lib/sandbox/clipboard/paths.ts +71 -0
- package/lib/sandbox/commands/create.ts +19 -2
- package/lib/sandbox/commands/enter.ts +15 -3
- package/lib/sandbox/commands/ls.ts +28 -4
- package/lib/sandbox/commands/prune.ts +211 -0
- package/lib/sandbox/commands/rm.ts +30 -32
- package/lib/sandbox/config.ts +2 -0
- package/lib/sandbox/constants.ts +9 -0
- package/lib/sandbox/host-timezone.ts +42 -0
- package/lib/sandbox/index.ts +7 -1
- package/lib/sandbox/managed-fs.ts +27 -0
- package/lib/sandbox/runtimes/base.dockerfile +21 -16
- package/lib/sandbox/tools.ts +1 -1
- package/lib/version.ts +11 -4
- package/package.json +10 -6
- package/templates/.agents/README.en.md +19 -0
- package/templates/.agents/README.zh-CN.md +19 -0
- package/templates/.agents/rules/create-issue.github.en.md +19 -1
- package/templates/.agents/rules/create-issue.github.zh-CN.md +19 -1
- package/templates/.agents/rules/milestone-inference.github.en.md +12 -0
- package/templates/.agents/rules/milestone-inference.github.zh-CN.md +12 -0
- package/templates/.agents/rules/testing-discipline.en.md +44 -0
- package/templates/.agents/rules/testing-discipline.zh-CN.md +44 -0
- package/templates/.agents/skills/analyze-task/SKILL.en.md +26 -0
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +26 -0
- package/templates/.agents/skills/analyze-task/config/verify.en.json +51 -0
- package/templates/.agents/skills/analyze-task/config/{verify.json → verify.zh-CN.json} +6 -2
- package/templates/.agents/skills/complete-task/SKILL.en.md +15 -0
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +15 -0
- package/templates/.agents/skills/complete-task/config/{verify.json → verify.en.json} +10 -0
- package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +48 -0
- package/templates/.agents/skills/create-task/SKILL.en.md +2 -0
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +2 -0
- package/templates/.agents/skills/create-task/config/verify.json +1 -0
- package/templates/.agents/skills/implement-task/SKILL.en.md +14 -0
- package/templates/.agents/skills/implement-task/SKILL.zh-CN.md +14 -0
- package/templates/.agents/skills/implement-task/config/verify.en.json +51 -0
- package/templates/.agents/skills/implement-task/config/{verify.json → verify.zh-CN.json} +7 -2
- package/templates/.agents/skills/implement-task/reference/report-template.en.md +15 -0
- package/templates/.agents/skills/implement-task/reference/report-template.zh-CN.md +15 -0
- package/templates/.agents/skills/import-issue/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/plan-task/SKILL.en.md +22 -0
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +22 -0
- package/templates/.agents/skills/plan-task/config/verify.en.json +52 -0
- package/templates/.agents/skills/plan-task/config/{verify.json → verify.zh-CN.json} +6 -2
- package/templates/.agents/skills/post-release/SKILL.en.md +1 -0
- package/templates/.agents/skills/post-release/SKILL.zh-CN.md +1 -0
- package/templates/.agents/skills/refine-task/SKILL.en.md +14 -0
- package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +14 -0
- package/templates/.agents/skills/refine-task/config/verify.en.json +47 -0
- package/templates/.agents/skills/refine-task/config/{verify.json → verify.zh-CN.json} +7 -2
- package/templates/.agents/skills/refine-task/reference/report-template.en.md +15 -0
- package/templates/.agents/skills/refine-task/reference/report-template.zh-CN.md +15 -0
- package/templates/.agents/skills/review-task/SKILL.en.md +14 -0
- package/templates/.agents/skills/review-task/SKILL.zh-CN.md +14 -0
- package/templates/.agents/skills/review-task/config/verify.en.json +50 -0
- package/templates/.agents/skills/review-task/config/{verify.json → verify.zh-CN.json} +5 -2
- package/templates/.agents/skills/review-task/reference/report-template.en.md +15 -0
- package/templates/.agents/skills/review-task/reference/report-template.zh-CN.md +15 -0
- package/dist/package.json +0 -5
package/lib/version.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
)
|
|
3
|
+
const packageJsonUrl = [
|
|
4
|
+
new URL('../package.json', import.meta.url),
|
|
5
|
+
new URL('../../package.json', import.meta.url),
|
|
6
|
+
].find((url) => existsSync(url));
|
|
7
|
+
|
|
8
|
+
if (!packageJsonUrl) {
|
|
9
|
+
throw new Error('Unable to locate package.json for agent-infra version');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const { version } = JSON.parse(readFileSync(packageJsonUrl, 'utf8'));
|
|
6
13
|
const VERSION = `v${version}`;
|
|
7
14
|
|
|
8
15
|
export { VERSION };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fitlab-ai/agent-infra",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
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",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"installer"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@clack/prompts": "1.
|
|
46
|
+
"@clack/prompts": "1.5.1",
|
|
47
47
|
"cross-spawn": "^7.0.6",
|
|
48
48
|
"picocolors": "1.1.1",
|
|
49
49
|
"semver": "^7.8.1",
|
|
@@ -54,15 +54,19 @@
|
|
|
54
54
|
"demo:regen": "sh scripts/demo-regen.sh",
|
|
55
55
|
"prepare": "git config core.hooksPath .git-hooks || true",
|
|
56
56
|
"typecheck": "tsc -p tsconfig.test.json --noEmit && tsc -p tsconfig.jschecks.json --noEmit",
|
|
57
|
-
"test:smoke": "npm run build && node --experimental-strip-types --no-warnings --test tests/
|
|
58
|
-
"test:core": "npm run build && node --experimental-strip-types --no-warnings --test tests/
|
|
59
|
-
"test": "npm run build && node --experimental-strip-types --no-warnings --test tests
|
|
60
|
-
"
|
|
57
|
+
"test:smoke": "npm run build && node --experimental-strip-types --no-warnings --test \"tests/unit/**/*.test.ts\"",
|
|
58
|
+
"test:core": "npm run build && node --experimental-strip-types --no-warnings --test \"tests/unit/**/*.test.ts\" \"tests/integration/**/*.test.ts\"",
|
|
59
|
+
"test": "npm run build && node --experimental-strip-types --no-warnings --test \"tests/**/*.test.ts\"",
|
|
60
|
+
"test:coverage": "npm run build && node --experimental-strip-types --no-warnings --test --experimental-test-coverage \"--test-coverage-exclude=tests/**\" --test-reporter=spec --test-reporter-destination=stdout --test-reporter=lcov --test-reporter-destination=coverage.lcov \"tests/**/*.test.ts\"",
|
|
61
|
+
"prepublishOnly": "npm run build && node --experimental-strip-types --no-warnings --test \"tests/**/*.test.ts\""
|
|
61
62
|
},
|
|
62
63
|
"devDependencies": {
|
|
63
64
|
"@types/cross-spawn": "^6.0.6",
|
|
64
65
|
"@types/node": "^25.9.1",
|
|
65
66
|
"@types/semver": "^7.7.1",
|
|
66
67
|
"typescript": "~6.0"
|
|
68
|
+
},
|
|
69
|
+
"optionalDependencies": {
|
|
70
|
+
"@lydell/node-pty": "^1.2.0-beta.12"
|
|
67
71
|
}
|
|
68
72
|
}
|
|
@@ -193,6 +193,23 @@ Each source should mirror the `.agents/skills/` layout and include `SKILL.md` at
|
|
|
193
193
|
- Built-in skills are not overridable by custom sources; if a source skill name conflicts with a built-in skill, the source copy is skipped
|
|
194
194
|
- Use `files.ejected` if the project must take ownership of a built-in skill or command
|
|
195
195
|
|
|
196
|
+
## File Ownership and Sync Strategy
|
|
197
|
+
|
|
198
|
+
The `files` field in `.agents/.airc.json` groups project files into three categories:
|
|
199
|
+
|
|
200
|
+
| Category | When the template has the file | When the template does not have the file | Cleanup behavior |
|
|
201
|
+
|----------|--------------------------------|------------------------------------------|------------------|
|
|
202
|
+
| `managed` | Write from the template and overwrite | Treat as removed from the template | Delete the local project copy |
|
|
203
|
+
| `merged` | Merge semantically by AI or humans | Do not write from the template | Keep the local project copy |
|
|
204
|
+
| `ejected` | May be created from the template first; skip overwrite once it exists | Do not write from the template | Keep the local project copy |
|
|
205
|
+
|
|
206
|
+
`ejected` has two common uses:
|
|
207
|
+
|
|
208
|
+
1. **Taking over a built-in file**: the project needs full control over a rule, command, or config file that originally came from the template.
|
|
209
|
+
2. **Declaring a project-only file**: the project owns a file under a managed directory wildcard, but the template does not contain that file; list it in `files.ejected` so sync does not treat it as a removed template file.
|
|
210
|
+
|
|
211
|
+
`ejected` entries support literal paths or globs, using the same matching rules as `merged`.
|
|
212
|
+
|
|
196
213
|
## Custom TUI Configuration
|
|
197
214
|
|
|
198
215
|
Use the top-level `.agents/.airc.json` `customTUIs` array when your team uses an AI TUI that is not one of the built-in command targets. This config lets agent-infra show the correct next-step commands and generate command files for project custom skills by learning from an existing command in the custom TUI directory.
|
|
@@ -257,6 +274,7 @@ When writing or updating `.agents/skills/*/SKILL.md` files and their templates,
|
|
|
257
274
|
|
|
258
275
|
- Keep SKILL.md as concise as possible; move detailed rules, long templates, and large script blocks into a sibling `reference/` or `scripts/` directory.
|
|
259
276
|
- Store declarative configuration in a sibling `config/` directory, for example `config/verify.json`.
|
|
277
|
+
When `required_sections` or `required_patterns` contain language-specific text, provide `config/verify.en.json` and `config/verify.zh-CN.json`; sync strips the selected language variant back to `config/verify.json`.
|
|
260
278
|
- Use explicit navigation in the skeleton, such as: `Read reference/xxx.md before executing this step.`
|
|
261
279
|
- Keep scripts in `scripts/` and execute them instead of inlining long bash blocks.
|
|
262
280
|
|
|
@@ -269,6 +287,7 @@ node .agents/scripts/validate-artifact.js gate <skill-name> <task-dir> [artifact
|
|
|
269
287
|
```
|
|
270
288
|
|
|
271
289
|
- Each skill declares its own checks in `config/verify.json`; keep the file focused on what that skill must validate
|
|
290
|
+
- For language-specific artifact headings or anchors, keep only `required_sections` and language-specific `required_patterns` different between `config/verify.en.json` and `config/verify.zh-CN.json`
|
|
272
291
|
- If a skill also prints next-step guidance, run the gate first and only show those instructions after the gate passes
|
|
273
292
|
- For user-facing final validation, prefer `--format text` so the reply contains a readable summary instead of raw JSON
|
|
274
293
|
- Shared validation logic belongs in `.agents/scripts/validate-artifact.js`; do not move detailed rules back into SKILL.md
|
|
@@ -193,6 +193,23 @@ args: "<task-id>" # 可选
|
|
|
193
193
|
- 自定义 source 不能覆盖内置 skill;如果与内置 skill 同名,会跳过该 source skill
|
|
194
194
|
- 如果项目必须接管某个内置 skill 或命令,请使用 `files.ejected`
|
|
195
195
|
|
|
196
|
+
## 文件归属与同步策略
|
|
197
|
+
|
|
198
|
+
`.agents/.airc.json` 的 `files` 字段把项目文件分为三类:
|
|
199
|
+
|
|
200
|
+
| 类别 | 模板中存在时 | 模板中不存在时 | 清理行为 |
|
|
201
|
+
|------|--------------|----------------|----------|
|
|
202
|
+
| `managed` | 从模板写入并覆盖 | 视为模板已下线 | 删除项目本地副本 |
|
|
203
|
+
| `merged` | 由 AI 或人工语义合并 | 不从模板写入 | 保留项目本地副本 |
|
|
204
|
+
| `ejected` | 首次可从模板创建,已存在时跳过覆盖 | 不从模板写入 | 保留项目本地副本 |
|
|
205
|
+
|
|
206
|
+
`ejected` 有两种常见用法:
|
|
207
|
+
|
|
208
|
+
1. **接管内置文件**:项目需要完全控制原本来自模板的规则、命令或配置文件,避免后续同步覆盖本地内容。
|
|
209
|
+
2. **声明项目独占文件**:项目自己的文件落在 managed 目录通配下,但模板中没有同名文件;把它列入 `files.ejected`,避免同步时被当作模板已下线文件删除。
|
|
210
|
+
|
|
211
|
+
`ejected` 条目支持字面路径或 glob,匹配规则与 `merged` 相同。
|
|
212
|
+
|
|
196
213
|
## 自定义 TUI 配置
|
|
197
214
|
|
|
198
215
|
当团队使用的 AI TUI 不属于内置命令目标时,可以在 `.agents/.airc.json` 顶层配置 `customTUIs` 数组。该配置用于让 agent-infra 输出正确的下一步命令,并通过学习自定义 TUI 目录中的既有命令文件,为项目自定义 skill 生成同格式命令。
|
|
@@ -257,6 +274,7 @@ args: "<task-id>" # 可选
|
|
|
257
274
|
|
|
258
275
|
- SKILL.md 正文尽可能精简,把详细规则、长模板和大段脚本拆分到同级 `reference/` 或 `scripts/` 目录。
|
|
259
276
|
- 声明式配置统一放在同级 `config/` 目录,例如 `config/verify.json`。
|
|
277
|
+
当 `required_sections` 或 `required_patterns` 包含语言相关文案时,提供 `config/verify.en.json` 和 `config/verify.zh-CN.json`;sync 会把选中的语言变体剥离为 `config/verify.json`。
|
|
260
278
|
- 骨架中使用明确导航,例如:`执行此步骤前,先读取 reference/xxx.md。`
|
|
261
279
|
- 长脚本继续放在 `scripts/` 目录,优先执行脚本而不是内联大段 bash。
|
|
262
280
|
|
|
@@ -269,6 +287,7 @@ node .agents/scripts/validate-artifact.js gate <skill-name> <task-dir> [artifact
|
|
|
269
287
|
```
|
|
270
288
|
|
|
271
289
|
- 每个 skill 在自己的 `config/verify.json` 中声明需要检查的事项
|
|
290
|
+
- 对语言相关的产物标题或锚点,`config/verify.en.json` 和 `config/verify.zh-CN.json` 之间只应让 `required_sections` 与语言相关的 `required_patterns` 不同
|
|
272
291
|
- 如果 skill 还会展示“下一步”提示,必须先通过完成校验,再输出这些指引
|
|
273
292
|
- 面向用户展示最终校验结果时,优先使用 `--format text` 输出可读摘要,而不是原始 JSON
|
|
274
293
|
- 共享逻辑集中在 `.agents/scripts/validate-artifact.js`,不要把详细校验规则重新塞回 SKILL.md
|
|
@@ -115,7 +115,25 @@ When applying the Issue Type, follow the "Set Issue Type" command in `.agents/ru
|
|
|
115
115
|
|
|
116
116
|
#### milestone
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
**Mandatory; do not skip.** This section expands `.agents/rules/milestone-inference.md` Phase 1 in place and keeps the same semantics; do not treat it as optional inference.
|
|
119
|
+
|
|
120
|
+
Select the milestone using these numbered steps, with priority strictly aligned to Phase 1:
|
|
121
|
+
|
|
122
|
+
1. If `has_triage=false`: omit `--milestone` immediately and skip this section.
|
|
123
|
+
2. List all open milestones in the repository:
|
|
124
|
+
```bash
|
|
125
|
+
gh api "repos/$upstream_repo/milestones?state=open&per_page=100" \
|
|
126
|
+
--jq '.[].title'
|
|
127
|
+
```
|
|
128
|
+
3. If task.md frontmatter explicitly provides a `milestone` field and that value appears in the step 2 list: use that value directly as `{milestone-arg}` and skip steps 4 / 5.
|
|
129
|
+
4. Filter the step 2 result with `^[0-9]+\.[0-9]+\.x$`.
|
|
130
|
+
- Non-empty: sort by major and minor numerically, then choose the smallest release line as `{milestone-arg}`.
|
|
131
|
+
5. If step 4 has no candidates: fall back to `General Backlog`.
|
|
132
|
+
- `General Backlog` exists in the step 2 result: use that milestone.
|
|
133
|
+
- `General Backlog` does not exist: omit `--milestone` only in this case.
|
|
134
|
+
6. If the step 2 `gh api` call fails (network / authentication error): handle it as "no candidates" and continue to step 5.
|
|
135
|
+
|
|
136
|
+
When a milestone is selected, pass the release line (or `General Backlog` or the explicit task.md value) as `{milestone-arg}` to the `gh issue create` command in step 5; keep the expansion rule at the end of §5 unchanged.
|
|
119
137
|
|
|
120
138
|
### 5. Call the GitHub CLI to Create the Issue
|
|
121
139
|
|
|
@@ -115,7 +115,25 @@ Issue 模板检测:按 `.agents/rules/issue-pr-commands.md` 的 "Issue 模板
|
|
|
115
115
|
|
|
116
116
|
#### milestone
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
**必须执行,不得跳过**。本节是 `.agents/rules/milestone-inference.md` 阶段 1 的就地展开,语义与之对齐;不要把它当成"可选推断"。
|
|
119
|
+
|
|
120
|
+
按以下编号步骤选取 milestone(优先级与阶段 1 严格一致):
|
|
121
|
+
|
|
122
|
+
1. 如果 `has_triage=false`:直接省略 `--milestone`,跳过本节。
|
|
123
|
+
2. 列出仓库 open 状态的全部 milestone:
|
|
124
|
+
```bash
|
|
125
|
+
gh api "repos/$upstream_repo/milestones?state=open&per_page=100" \
|
|
126
|
+
--jq '.[].title'
|
|
127
|
+
```
|
|
128
|
+
3. 如果 `task.md` frontmatter 显式给出 `milestone` 字段,且该值出现在步骤 2 列表中:直接使用该值作为 `{milestone-arg}`,跳过步骤 4 / 5。
|
|
129
|
+
4. 用正则 `^[0-9]+\.[0-9]+\.x$` 过滤步骤 2 结果。
|
|
130
|
+
- 非空:按 major、minor 数值升序排序,取最小的版本线作为 `{milestone-arg}`。
|
|
131
|
+
5. 步骤 4 候选为空:尝试回退到 `General Backlog`。
|
|
132
|
+
- 步骤 2 结果中存在 `General Backlog`:使用该 milestone。
|
|
133
|
+
- 不存在 `General Backlog`:仅在此情况下省略 `--milestone`。
|
|
134
|
+
6. 步骤 2 的 `gh api` 调用失败(网络 / 认证错误):按"无候选"处理,落到步骤 5。
|
|
135
|
+
|
|
136
|
+
设置成功时把版本线(或 `General Backlog` 或 task.md 显式值)作为 `{milestone-arg}` 带入步骤 5 的 `gh issue create` 命令;§5 末尾的展开规则保持不变。
|
|
119
137
|
|
|
120
138
|
### 5. 调用 GitHub CLI 创建 Issue
|
|
121
139
|
|
|
@@ -44,6 +44,18 @@ Only match titles in `X.Y.x` format and choose the smallest major/minor pair num
|
|
|
44
44
|
|
|
45
45
|
Direct milestone writes are triage-gated. When the caller detected `has_triage=false`, omit `--milestone` and continue.
|
|
46
46
|
|
|
47
|
+
### Backfill when called from `import-issue`
|
|
48
|
+
|
|
49
|
+
When `import-issue` imports an existing Issue whose current milestone is empty, infer a release line using the priority above, including the `General Backlog` fallback. When a non-empty release line is found, write it back to the remote Issue:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
if [ "$has_triage" = "true" ]; then
|
|
53
|
+
gh issue edit {issue-number} -R "$upstream_repo" --milestone "{version}" 2>/dev/null || true
|
|
54
|
+
fi
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
If `has_triage=false`, inference returns empty, or `gh issue edit` fails, skip and continue without blocking the `import-issue` workflow.
|
|
58
|
+
|
|
47
59
|
## Phase 2: `implement-task`
|
|
48
60
|
|
|
49
61
|
Goal: narrow the Issue milestone from a release line to a concrete version when implementation starts.
|
|
@@ -44,6 +44,18 @@ gh api "repos/$upstream_repo/milestones?state=open&per_page=100" \
|
|
|
44
44
|
|
|
45
45
|
Milestone 设置属于 `has_triage` 权限范围;如果调用方检测到 `has_triage=false`,则省略 `--milestone` 并继续。
|
|
46
46
|
|
|
47
|
+
### `import-issue` 调用时的兜底
|
|
48
|
+
|
|
49
|
+
`import-issue` 导入既有 Issue 时,若 Issue 当前 milestone 为空,按上述优先级推断版本线(含 `General Backlog` 回退)。命中非空版本线后,回写到远端 Issue:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
if [ "$has_triage" = "true" ]; then
|
|
53
|
+
gh issue edit {issue-number} -R "$upstream_repo" --milestone "{version}" 2>/dev/null || true
|
|
54
|
+
fi
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
如果 `has_triage=false`、推断结果为空、或 `gh issue edit` 失败,跳过并继续,不阻断 `import-issue` 工作流。
|
|
58
|
+
|
|
47
59
|
## 阶段 2:`implement-task`
|
|
48
60
|
|
|
49
61
|
目标:开始开发时,把 Issue milestone 从版本线收窄到具体版本。
|
|
@@ -38,3 +38,47 @@ This mirrors "Goal-Driven Execution" in AGENTS.md: define a verifiable success c
|
|
|
38
38
|
- **Over-mocking**: Stub only real boundaries such as network, filesystem, time, or randomness; do not mock the logic of the unit under test, or the test only proves that the mock followed the script.
|
|
39
39
|
- **Testing implementation details**: Prefer assertions on public APIs, artifacts, state changes, or error results; avoid assertions on private functions, internal call order, or temporary data structures.
|
|
40
40
|
- **Insufficient assertions**: Assertions must pin down concrete expected values; do not replace checks on key fields, counts, and boundaries with "does not throw" or "result exists".
|
|
41
|
+
|
|
42
|
+
## Coverage positioning (informational layer)
|
|
43
|
+
|
|
44
|
+
> CI emits coverage via `node --test --experimental-test-coverage` as a hint about "which files are weakly tested". It is **not a merge gate**.
|
|
45
|
+
|
|
46
|
+
### Local run
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm run test:coverage
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The tail of stdout prints per-file line / branch / function coverage and the uncovered line numbers.
|
|
53
|
+
|
|
54
|
+
### CI display
|
|
55
|
+
|
|
56
|
+
`.github/workflows/unit-tests.yml` writes the coverage block into the GitHub Actions step summary on the ubuntu-latest shard (visible on the PR Checks page). Windows / macOS shards do not duplicate this output.
|
|
57
|
+
|
|
58
|
+
The Codecov badge at the top of the README is generated by Codecov after `.github/workflows/unit-tests.yml` uploads `coverage.lcov` from the ubuntu-latest shard.
|
|
59
|
+
|
|
60
|
+
### Boundaries
|
|
61
|
+
|
|
62
|
+
- **No percentage thresholds**: Threshold flags such as `--test-coverage-lines/branches/functions` are forbidden. Goodhart's law reminds us that once coverage becomes a metric, developers write "coverage-friendly but behavior-weak" tests.
|
|
63
|
+
- **Third-party services for the badge only**: Codecov hosts the README coverage badge, but the root `codecov.yml` explicitly disables its project/patch status checks and PR comments — Codecov only displays a number here and does not participate in merge decisions. Do not integrate other services such as coveralls.
|
|
64
|
+
- **No tier split**: Coverage is currently emitted only for the full `test` tier; smoke / core tier coverage has no independent value.
|
|
65
|
+
- **Does not block PRs**: The CI step uses `continue-on-error: true`, so a failed coverage collection does not affect merges.
|
|
66
|
+
|
|
67
|
+
### Where New Tests Go
|
|
68
|
+
|
|
69
|
+
The test directory determines which npm script runs a test file:
|
|
70
|
+
|
|
71
|
+
- `tests/unit/<module>/`: fast structural or pure-function tests; does not spawn the real CLI process or depend on external tools, suitable for `test:smoke`.
|
|
72
|
+
- `tests/integration/<module>/`: combines multiple modules, runs CLI subprocesses, touches temporary filesystems, or verifies template sync flows while staying stable and reasonably fast, suitable for `test:core`.
|
|
73
|
+
- `tests/e2e/<module>/`: slower contract, platform-sync, packaged-output, cross-process, or end-to-end workflow tests, run only by full `npm test`.
|
|
74
|
+
|
|
75
|
+
Modules remain as second-level directories such as `cli`, `core`, `scripts`, and `templates`. Shared helpers and fixtures stay in `tests/helpers/`, `tests/helpers.ts`, and `tests/fixtures/`; do not place them under a tier.
|
|
76
|
+
|
|
77
|
+
### Relation to "test tier coverage"
|
|
78
|
+
|
|
79
|
+
Distinguish two concepts:
|
|
80
|
+
|
|
81
|
+
- **Test tier coverage** (`tests/unit/core/test-tier-coverage.test.ts` checks test directory placement and npm script tier mapping): governs "which test files belong to which tier" and is orthogonal to source-line coverage.
|
|
82
|
+
- **Source-line coverage** (this section): governs "which lines of production source are exercised by tests".
|
|
83
|
+
|
|
84
|
+
The two serve different purposes and should not substitute for each other.
|
|
@@ -38,3 +38,47 @@ assert.match(content, /^name: implement-task$/m); // 正向断言已足够
|
|
|
38
38
|
- **mock 过度**:只在网络、文件系统、时间、随机数等真实边界打桩;不要 mock 被测对象自身逻辑,否则测试只验证 mock 是否按预设运行。
|
|
39
39
|
- **测试实现细节**:优先断言公开接口、产物、状态变化或错误结果;避免断言私有函数、内部调用顺序、临时数据结构。
|
|
40
40
|
- **断言不充分**:断言必须锁定具体期望值;不要用"只要不抛异常""结果存在即可"替代对关键字段、数量和边界的验证。
|
|
41
|
+
|
|
42
|
+
## 覆盖率定位(信息层)
|
|
43
|
+
|
|
44
|
+
> CI 中通过 `node --test --experimental-test-coverage` 输出覆盖率,仅作为"哪些文件被测试薄弱"的提示,**不作为 merge gate**。
|
|
45
|
+
|
|
46
|
+
### 本地运行
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm run test:coverage
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
stdout 末尾会打印按文件粒度的行 / 分支 / 函数覆盖率以及未覆盖行号。
|
|
53
|
+
|
|
54
|
+
### CI 展示
|
|
55
|
+
|
|
56
|
+
`.github/workflows/unit-tests.yml` 在 ubuntu-latest 分片上把覆盖率块写入 GitHub Actions 的 step summary(PR Checks 页可见)。Windows / macOS 分片不重复输出。
|
|
57
|
+
|
|
58
|
+
README 顶部的 Codecov 徽章由 `.github/workflows/unit-tests.yml` 在 ubuntu-latest 分片上传 `coverage.lcov` 后由 Codecov 生成。
|
|
59
|
+
|
|
60
|
+
### 边界
|
|
61
|
+
|
|
62
|
+
- **不设置百分比阈值**:`--test-coverage-lines/branches/functions` 等阈值参数禁止加入;Goodhart's law 提醒我们一旦把覆盖率作为指标,开发者会写"覆盖率友好但行为弱"的测试。
|
|
63
|
+
- **第三方服务仅用于徽章**:已接入 Codecov 托管 README 覆盖率徽章,但通过根 `codecov.yml` 显式关闭其 project/patch status check 与 PR 评论——Codecov 在本项目只展示数字,不参与 merge 决策。不接入 coveralls 等其他服务。
|
|
64
|
+
- **不区分 tier**:当前只对 full `test` tier 输出覆盖率;smoke / core tier 的覆盖率没有独立价值。
|
|
65
|
+
- **不阻塞 PR**:CI 步骤 `continue-on-error: true`,即便覆盖率采集失败也不影响 merge。
|
|
66
|
+
|
|
67
|
+
### 新测试该放哪一层
|
|
68
|
+
|
|
69
|
+
测试文件放入哪一层决定它会被哪些 npm script 自动执行:
|
|
70
|
+
|
|
71
|
+
- `tests/unit/<module>/`:快速、结构性或纯函数类测试;不启动真实 CLI 子进程,不依赖外部工具,适合 `test:smoke`。
|
|
72
|
+
- `tests/integration/<module>/`:会组合多个模块、运行 CLI 子进程、触达临时文件系统或验证模板同步流程,但仍应保持稳定和相对快速,适合 `test:core`。
|
|
73
|
+
- `tests/e2e/<module>/`:较慢的契约、平台同步、打包产物、跨进程或端到端流程测试,只在完整 `npm test` 中运行。
|
|
74
|
+
|
|
75
|
+
模块继续作为第二级目录(如 `cli`、`core`、`scripts`、`templates`)。共享 helper 和 fixtures 保持在 `tests/helpers/`、`tests/helpers.ts`、`tests/fixtures/`,不要放入任一 tier。
|
|
76
|
+
|
|
77
|
+
### 与"测试 tier 覆盖"的关系
|
|
78
|
+
|
|
79
|
+
注意区分两个概念:
|
|
80
|
+
|
|
81
|
+
- **测试 tier 覆盖**(`tests/unit/core/test-tier-coverage.test.ts` 校验测试文件目录归属与 npm script tier 映射):管的是"哪些测试文件被纳入哪一 tier",与代码行覆盖率正交。
|
|
82
|
+
- **代码行覆盖率**(本节):管的是"业务源码哪些行被测试触达"。
|
|
83
|
+
|
|
84
|
+
两者目的不同,不要相互替代。
|
|
@@ -13,6 +13,20 @@ description: "Analyze a task and produce a requirements document"
|
|
|
13
13
|
|
|
14
14
|
Version stamp rule: when creating or updating `task.md` frontmatter, read `.agents/rules/version-stamp.md` first and write or refresh `agent_infra_version`.
|
|
15
15
|
|
|
16
|
+
## Step 0: State Check (pre-execution hard gate)
|
|
17
|
+
|
|
18
|
+
After loading workflow / skill / rules instructions, and before any task-state judgment or user-visible conclusion, run the state check first. Reading instruction files does not count as an external-state action or conclusion.
|
|
19
|
+
|
|
20
|
+
Run these commands and paste the raw output into both the user-facing reply and this round's `## State Check` section:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
git status -s
|
|
24
|
+
ls -la .agents/workspace/active/{task-id}/
|
|
25
|
+
tail .agents/workspace/active/{task-id}/task.md
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Before the state check is complete, do not make external-state assertions such as "the code is unchanged", "tests passed", or "there are no other references", including in reasoning. This gate is only a structural floor; evidence pairing and authenticity still require the report template and review discipline.
|
|
29
|
+
|
|
16
30
|
## Steps
|
|
17
31
|
|
|
18
32
|
### 1. Verify Prerequisites
|
|
@@ -72,6 +86,10 @@ Create `.agents/workspace/active/{task-id}/{analysis-artifact}`.
|
|
|
72
86
|
- **Analysis round**: Round {analysis-round}
|
|
73
87
|
- **Artifact file**: `{analysis-artifact}`
|
|
74
88
|
|
|
89
|
+
## State Check
|
|
90
|
+
|
|
91
|
+
> Paste the raw Step 0 state-check command output; each command starts with `$ `.
|
|
92
|
+
|
|
75
93
|
## Requirement Source
|
|
76
94
|
|
|
77
95
|
**Source type**: {User description / Issue / Code Scanning / Dependabot / Other}
|
|
@@ -118,6 +136,14 @@ Update `.agents/workspace/active/{task-id}/task.md`:
|
|
|
118
136
|
- Record the analysis artifact for this round: `{analysis-artifact}` (Round `{analysis-round}`)
|
|
119
137
|
- If the task template contains a `## Analysis` section, update it to link to `{analysis-artifact}`
|
|
120
138
|
- Mark requirement-analysis as complete in workflow progress and include the actual round when the task template supports it
|
|
139
|
+
- Before appending the workflow Activity Log entry, re-estimate `priority` based on the analysis findings (business impact, risks, dependencies, blockers). If the re-estimated value differs from the current value in `task.md`:
|
|
140
|
+
- Overwrite the `priority` field in frontmatter with the new value
|
|
141
|
+
- Prepend an Activity Log entry recording the transition (placed before the `Requirement Analysis (Round N)` entry):
|
|
142
|
+
```
|
|
143
|
+
- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Analysis Re-estimate** by {agent} — priority {old} → {new} (rationale: {short basis grounded in this analysis})
|
|
144
|
+
```
|
|
145
|
+
Both entries may share the same timestamp; ordering is conveyed by list position only.
|
|
146
|
+
If the re-estimated value matches the current value, skip the Re-estimate entry. The Flow A sync that follows reads the possibly updated frontmatter and propagates the new value to the Issue automatically.
|
|
121
147
|
- **Append** to `## Activity Log` (do NOT overwrite previous entries):
|
|
122
148
|
```
|
|
123
149
|
- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Requirement Analysis (Round {N})** by {agent} — Analysis completed → {analysis-artifact}
|
|
@@ -13,6 +13,20 @@ description: "分析任务并输出需求分析文档"
|
|
|
13
13
|
|
|
14
14
|
版本戳规则:创建或更新 `task.md` frontmatter 时,先读取 `.agents/rules/version-stamp.md`,并写入或刷新 `agent_infra_version`。
|
|
15
15
|
|
|
16
|
+
## 第 0 步:状态核对(执行前硬约束)
|
|
17
|
+
|
|
18
|
+
在加载 workflow / skill / rules 指令之后、做任何任务状态判断或用户可见结论之前,必须先执行状态核对。指令类文件读取不算对外动作或结论。
|
|
19
|
+
|
|
20
|
+
运行以下命令,并把原文粘贴到回复正文和本轮产物的 `## 状态核对` 段:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
git status -s
|
|
24
|
+
ls -la .agents/workspace/active/{task-id}/
|
|
25
|
+
tail .agents/workspace/active/{task-id}/task.md
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
状态核对完成前,禁止任何关于外部状态的断言(例如“代码没变”“测试已通过”“没有其他引用”),包括思考阶段。本门禁只提供结构下限;逐条证据配对和真实性仍需按报告模板与审查要求核对。
|
|
29
|
+
|
|
16
30
|
## 执行步骤
|
|
17
31
|
|
|
18
32
|
### 1. 验证前置条件
|
|
@@ -72,6 +86,10 @@ description: "分析任务并输出需求分析文档"
|
|
|
72
86
|
- **分析轮次**:Round {analysis-round}
|
|
73
87
|
- **产物文件**:`{analysis-artifact}`
|
|
74
88
|
|
|
89
|
+
## 状态核对
|
|
90
|
+
|
|
91
|
+
> 粘贴第 0 步状态核对命令原文;每条命令以 `$ ` 开头。
|
|
92
|
+
|
|
75
93
|
## 需求来源
|
|
76
94
|
|
|
77
95
|
**来源类型**:{用户描述 / Issue / Code Scanning / Dependabot / 其他}
|
|
@@ -118,6 +136,14 @@ date "+%Y-%m-%d %H:%M:%S%:z"
|
|
|
118
136
|
- 记录本轮分析产物:`{analysis-artifact}`(Round `{analysis-round}`)
|
|
119
137
|
- 如任务模板包含 `## 分析` 段落,更新为指向 `{analysis-artifact}` 的链接
|
|
120
138
|
- 在工作流进度中标记 requirement-analysis 为已完成,并注明实际轮次(如果任务模板支持)
|
|
139
|
+
- 在追加工作流 Activity Log 条目之前,基于分析结果(业务影响、风险、依赖、阻塞条件)重估 `priority`。若重估值与 `task.md` 当前值不一致:
|
|
140
|
+
- 用新值覆盖 frontmatter 的 `priority` 字段
|
|
141
|
+
- 在 `Requirement Analysis (Round N)` 条目之前追加一条转移记录:
|
|
142
|
+
```
|
|
143
|
+
- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Analysis Re-estimate** by {agent} — priority {old} → {new} (rationale: {基于本轮分析的简短依据})
|
|
144
|
+
```
|
|
145
|
+
两条条目可共用同一时间戳,顺序仅通过列表位置表达。
|
|
146
|
+
若重估值与当前值一致,跳过 Re-estimate 条目。后续 Flow A 同步会读取可能更新过的 frontmatter,并自动把新值同步到 Issue。
|
|
121
147
|
- **追加**到 `## Activity Log`(不要覆盖之前的记录):
|
|
122
148
|
```
|
|
123
149
|
- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Requirement Analysis (Round {N})** by {agent} — Analysis completed → {analysis-artifact}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill": "analyze-task",
|
|
3
|
+
"checks": {
|
|
4
|
+
"task-meta": {
|
|
5
|
+
"required_fields": [
|
|
6
|
+
"id",
|
|
7
|
+
"type",
|
|
8
|
+
"workflow",
|
|
9
|
+
"status",
|
|
10
|
+
"created_at",
|
|
11
|
+
"updated_at",
|
|
12
|
+
"agent_infra_version",
|
|
13
|
+
"current_step",
|
|
14
|
+
"assigned_to"
|
|
15
|
+
],
|
|
16
|
+
"expected_step": "requirement-analysis"
|
|
17
|
+
},
|
|
18
|
+
"artifact": {
|
|
19
|
+
"file_pattern": "analysis.md|analysis-r{N}.md",
|
|
20
|
+
"required_sections": [
|
|
21
|
+
"Requirement Source",
|
|
22
|
+
"Requirement Understanding",
|
|
23
|
+
"Related Files",
|
|
24
|
+
"Impact Assessment",
|
|
25
|
+
"Technical Risks",
|
|
26
|
+
"Effort and Complexity Assessment",
|
|
27
|
+
"State Check"
|
|
28
|
+
],
|
|
29
|
+
"freshness_minutes": 30,
|
|
30
|
+
"required_patterns": [
|
|
31
|
+
"^\\$ "
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
"activity-log": {
|
|
35
|
+
"expected_action_pattern": "Requirement Analysis \\(Round \\d+\\)",
|
|
36
|
+
"freshness_minutes": 30
|
|
37
|
+
},
|
|
38
|
+
"platform-sync": {
|
|
39
|
+
"when": "issue_number_exists",
|
|
40
|
+
"expected_status_label": "status: pending-design-work",
|
|
41
|
+
"expected_comment_marker": "<!-- sync-issue:{task-id}:{artifact-stem} -->",
|
|
42
|
+
"verify_comment_content": true,
|
|
43
|
+
"verify_task_comment_content": true,
|
|
44
|
+
"verify_issue_type": true,
|
|
45
|
+
"verify_issue_fields": false,
|
|
46
|
+
"verify_milestone": true,
|
|
47
|
+
"expected_status_label_key": "pendingDesignWork",
|
|
48
|
+
"expected_comment_marker_key": "artifact"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -23,9 +23,13 @@
|
|
|
23
23
|
"相关文件",
|
|
24
24
|
"影响评估",
|
|
25
25
|
"技术风险",
|
|
26
|
-
"工作量和复杂度评估"
|
|
26
|
+
"工作量和复杂度评估",
|
|
27
|
+
"状态核对"
|
|
27
28
|
],
|
|
28
|
-
"freshness_minutes": 30
|
|
29
|
+
"freshness_minutes": 30,
|
|
30
|
+
"required_patterns": [
|
|
31
|
+
"^\\$ "
|
|
32
|
+
]
|
|
29
33
|
},
|
|
30
34
|
"activity-log": {
|
|
31
35
|
"expected_action_pattern": "Requirement Analysis \\(Round \\d+\\)",
|
|
@@ -12,6 +12,20 @@ description: "Mark a task as completed and archive it"
|
|
|
12
12
|
|
|
13
13
|
Version stamp rule: when creating or updating `task.md` frontmatter, read `.agents/rules/version-stamp.md` first and write or refresh `agent_infra_version`.
|
|
14
14
|
|
|
15
|
+
## Step 0: State Check (pre-execution hard gate)
|
|
16
|
+
|
|
17
|
+
After loading workflow / skill / rules instructions, and before any task-state judgment or user-visible conclusion, run the state check first. Reading instruction files does not count as an external-state action or conclusion.
|
|
18
|
+
|
|
19
|
+
Run these commands and paste the raw output into both the user-facing reply and this round's `## State Check` section:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
git status -s
|
|
23
|
+
ls -la .agents/workspace/active/{task-id}/
|
|
24
|
+
tail .agents/workspace/active/{task-id}/task.md
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Before the state check is complete, do not make external-state assertions such as "the code is unchanged", "tests passed", or "there are no other references", including in reasoning. This gate is only a structural floor; evidence pairing and authenticity still require the report template and review discipline.
|
|
28
|
+
|
|
15
29
|
## Steps
|
|
16
30
|
|
|
17
31
|
### 1. Verify Task Exists
|
|
@@ -64,6 +78,7 @@ Update `.agents/workspace/active/{task-id}/task.md`:
|
|
|
64
78
|
- `completed_at`: {current timestamp}
|
|
65
79
|
- `updated_at`: {current timestamp}
|
|
66
80
|
- `agent_infra_version`: value from `.agents/rules/version-stamp.md`
|
|
81
|
+
- Add or update the `## State Check` section with the raw Step 0 audit command output, including `$ ` prompt lines, before `## Activity Log`
|
|
67
82
|
- Mark all workflow steps as complete
|
|
68
83
|
- Verify and check off all items in `## Completion Checklist` (change `- [ ]` to `- [x]`)
|
|
69
84
|
- **Append** to `## Activity Log` (do NOT overwrite previous entries):
|
|
@@ -12,6 +12,20 @@ description: "标记任务完成并归档"
|
|
|
12
12
|
|
|
13
13
|
版本戳规则:创建或更新 `task.md` frontmatter 时,先读取 `.agents/rules/version-stamp.md`,并写入或刷新 `agent_infra_version`。
|
|
14
14
|
|
|
15
|
+
## 第 0 步:状态核对(执行前硬约束)
|
|
16
|
+
|
|
17
|
+
在加载 workflow / skill / rules 指令之后、做任何任务状态判断或用户可见结论之前,必须先执行状态核对。指令类文件读取不算对外动作或结论。
|
|
18
|
+
|
|
19
|
+
运行以下命令,并把原文粘贴到回复正文和本轮产物的 `## 状态核对` 段:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
git status -s
|
|
23
|
+
ls -la .agents/workspace/active/{task-id}/
|
|
24
|
+
tail .agents/workspace/active/{task-id}/task.md
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
状态核对完成前,禁止任何关于外部状态的断言(例如“代码没变”“测试已通过”“没有其他引用”),包括思考阶段。本门禁只提供结构下限;逐条证据配对和真实性仍需按报告模板与审查要求核对。
|
|
28
|
+
|
|
15
29
|
## 执行步骤
|
|
16
30
|
|
|
17
31
|
### 1. 验证任务存在
|
|
@@ -64,6 +78,7 @@ date "+%Y-%m-%d %H:%M:%S%:z"
|
|
|
64
78
|
- `completed_at`:{当前时间戳}
|
|
65
79
|
- `updated_at`:{当前时间戳}
|
|
66
80
|
- `agent_infra_version`:按 `.agents/rules/version-stamp.md` 取值
|
|
81
|
+
- 新增或更新 `## 状态核对` 段,粘贴第 0 步审计命令原文(含 `$ ` 前缀行),放在 `## 活动日志` 之前
|
|
67
82
|
- 标记所有工作流步骤为已完成
|
|
68
83
|
- 逐项验证并勾选 `## 完成检查清单` 中的所有条目(将 `- [ ]` 改为 `- [x]`)
|
|
69
84
|
- **追加**到 `## Activity Log`(不要覆盖之前的记录):
|
|
@@ -33,6 +33,16 @@
|
|
|
33
33
|
"verify_issue_fields": false,
|
|
34
34
|
"verify_milestone": true,
|
|
35
35
|
"expected_comment_marker_key": "summary"
|
|
36
|
+
},
|
|
37
|
+
"artifact": {
|
|
38
|
+
"file_pattern": "task.md",
|
|
39
|
+
"required_sections": [
|
|
40
|
+
"State Check"
|
|
41
|
+
],
|
|
42
|
+
"required_patterns": [
|
|
43
|
+
"^\\$ "
|
|
44
|
+
],
|
|
45
|
+
"freshness_minutes": 30
|
|
36
46
|
}
|
|
37
47
|
}
|
|
38
48
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill": "complete-task",
|
|
3
|
+
"checks": {
|
|
4
|
+
"task-meta": {
|
|
5
|
+
"required_fields": [
|
|
6
|
+
"id",
|
|
7
|
+
"type",
|
|
8
|
+
"workflow",
|
|
9
|
+
"status",
|
|
10
|
+
"created_at",
|
|
11
|
+
"updated_at",
|
|
12
|
+
"agent_infra_version",
|
|
13
|
+
"current_step",
|
|
14
|
+
"assigned_to",
|
|
15
|
+
"completed_at"
|
|
16
|
+
],
|
|
17
|
+
"expected_status": "completed",
|
|
18
|
+
"require_completed_at": true
|
|
19
|
+
},
|
|
20
|
+
"activity-log": {
|
|
21
|
+
"expected_action_pattern": "Completed",
|
|
22
|
+
"freshness_minutes": 30
|
|
23
|
+
},
|
|
24
|
+
"completion-checklist": {
|
|
25
|
+
"require_all_checked": true
|
|
26
|
+
},
|
|
27
|
+
"platform-sync": {
|
|
28
|
+
"when": "issue_number_exists",
|
|
29
|
+
"expected_comment_marker": "<!-- sync-issue:{task-id}:summary -->",
|
|
30
|
+
"verify_task_comment_content": true,
|
|
31
|
+
"sync_checked_requirements": true,
|
|
32
|
+
"verify_issue_type": true,
|
|
33
|
+
"verify_issue_fields": false,
|
|
34
|
+
"verify_milestone": true,
|
|
35
|
+
"expected_comment_marker_key": "summary"
|
|
36
|
+
},
|
|
37
|
+
"artifact": {
|
|
38
|
+
"file_pattern": "task.md",
|
|
39
|
+
"required_sections": [
|
|
40
|
+
"状态核对"
|
|
41
|
+
],
|
|
42
|
+
"required_patterns": [
|
|
43
|
+
"^\\$ "
|
|
44
|
+
],
|
|
45
|
+
"freshness_minutes": 30
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -116,6 +116,8 @@ The rule's content is determined by the configured code platform:
|
|
|
116
116
|
- A platform that supports Issue creation: contains the full flow for auth detection, template detection, label/type/milestone inference, the create-Issue call, and writing back to `task.md`
|
|
117
117
|
- Custom or empty platforms (no platform-specific variant provided): the rule body is a no-op notice, and this step is skipped entirely
|
|
118
118
|
|
|
119
|
+
> **Hard constraint**: the milestone sub-step in `.agents/rules/create-issue.md` §4 is mandatory; missing it fails the step 5 gate (`verify_milestone: true`) and aborts create-task.
|
|
120
|
+
|
|
119
121
|
Handle the result:
|
|
120
122
|
- Rule successfully created the Issue: `issue_number` has been written back to task.md per the rule; continue by reading `.agents/rules/issue-sync.md`, completing upstream repository and permission detection, then sync the task comment and set `status: waiting-for-triage` by rule
|
|
121
123
|
- Rule failed (auth / network / template parse / etc.): do not roll back task.md; do NOT append an extra Activity Log entry; follow "Scenario C: Issue creation failed" output to surface `error_code` and `error_message` to the user so they can decide whether to retry manually or write `issue_number` later
|