@fitlab-ai/agent-infra 0.6.0 → 0.6.1
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 +12 -12
- package/README.zh-CN.md +12 -12
- package/bin/cli.ts +5 -1
- package/dist/bin/cli.js +6 -1
- package/dist/lib/defaults.json +4 -3
- package/dist/lib/sandbox/config.js +1 -1
- package/dist/package.json +1 -1
- package/lib/defaults.json +4 -3
- package/lib/sandbox/config.ts +1 -1
- package/package.json +3 -3
- package/templates/.agents/README.en.md +8 -8
- package/templates/.agents/README.zh-CN.md +8 -8
- package/templates/{.claude → .agents}/hooks/check-version-format.sh +3 -3
- package/templates/.agents/rules/create-issue.github.en.md +6 -0
- package/templates/.agents/rules/create-issue.github.zh-CN.md +6 -0
- package/templates/.agents/rules/issue-fields.github.en.md +155 -0
- package/templates/.agents/rules/issue-fields.github.zh-CN.md +155 -0
- package/templates/.agents/rules/issue-pr-commands.github.en.md +1 -0
- package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +1 -0
- package/templates/.agents/rules/issue-sync.github.en.md +2 -1
- package/templates/.agents/rules/issue-sync.github.zh-CN.md +2 -1
- package/templates/.agents/rules/task-management.en.md +17 -9
- package/templates/.agents/rules/task-management.zh-CN.md +17 -9
- package/templates/.agents/rules/testing-discipline.en.md +40 -0
- package/templates/.agents/rules/testing-discipline.zh-CN.md +40 -0
- package/templates/.agents/rules/version-stamp.en.md +29 -0
- package/templates/.agents/rules/version-stamp.zh-CN.md +29 -0
- package/templates/.agents/scripts/platform-adapters/platform-sync.github.js +143 -6
- package/templates/.agents/scripts/validate-artifact.js +32 -5
- package/templates/.agents/skills/analyze-task/SKILL.en.md +3 -0
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +3 -0
- package/templates/.agents/skills/analyze-task/config/verify.json +2 -0
- package/templates/.agents/skills/block-task/SKILL.en.md +3 -0
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +3 -0
- package/templates/.agents/skills/block-task/config/verify.json +1 -0
- package/templates/.agents/skills/cancel-task/SKILL.en.md +3 -0
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +3 -0
- package/templates/.agents/skills/cancel-task/config/verify.json +1 -0
- package/templates/.agents/skills/commit/SKILL.en.md +10 -0
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +10 -0
- package/templates/.agents/skills/commit/config/verify.json +1 -0
- package/templates/.agents/skills/commit/reference/task-status-update.en.md +5 -0
- package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +5 -0
- package/templates/.agents/skills/complete-task/SKILL.en.md +4 -0
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +4 -0
- package/templates/.agents/skills/complete-task/config/verify.json +2 -0
- package/templates/.agents/skills/create-pr/SKILL.en.md +5 -1
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +5 -1
- package/templates/.agents/skills/create-pr/config/verify.json +1 -0
- package/templates/.agents/skills/create-task/SKILL.en.md +9 -0
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +9 -0
- package/templates/.agents/skills/create-task/config/verify.json +1 -0
- package/templates/.agents/skills/implement-task/SKILL.en.md +16 -1
- package/templates/.agents/skills/implement-task/SKILL.zh-CN.md +16 -1
- package/templates/.agents/skills/implement-task/config/verify.json +2 -0
- package/templates/.agents/skills/import-codescan/config/verify.json +1 -0
- package/templates/.agents/skills/import-dependabot/config/verify.json +1 -0
- package/templates/.agents/skills/import-issue/SKILL.en.md +10 -0
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +10 -0
- package/templates/.agents/skills/import-issue/config/verify.json +1 -0
- package/templates/.agents/skills/plan-task/SKILL.en.md +3 -0
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +3 -0
- package/templates/.agents/skills/plan-task/config/verify.json +2 -0
- package/templates/.agents/skills/refine-task/SKILL.en.md +15 -1
- package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +15 -1
- package/templates/.agents/skills/refine-task/config/verify.json +2 -0
- package/templates/.agents/skills/refine-task/reference/fix-workflow.en.md +9 -0
- package/templates/.agents/skills/refine-task/reference/fix-workflow.zh-CN.md +9 -0
- package/templates/.agents/skills/refine-task/reference/report-template.en.md +11 -0
- package/templates/.agents/skills/refine-task/reference/report-template.zh-CN.md +11 -0
- package/templates/.agents/skills/restore-task/SKILL.en.md +3 -0
- package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +3 -0
- package/templates/.agents/skills/restore-task/config/verify.json +1 -0
- package/templates/.agents/skills/review-task/SKILL.en.md +16 -1
- package/templates/.agents/skills/review-task/SKILL.zh-CN.md +16 -1
- package/templates/.agents/skills/review-task/config/verify.json +3 -0
- package/templates/.agents/skills/review-task/reference/output-templates.en.md +20 -5
- package/templates/.agents/skills/review-task/reference/output-templates.zh-CN.md +20 -5
- package/templates/.agents/skills/review-task/reference/report-template.en.md +13 -0
- package/templates/.agents/skills/review-task/reference/report-template.zh-CN.md +13 -0
- package/templates/.agents/skills/review-task/reference/review-criteria.en.md +18 -0
- package/templates/.agents/skills/review-task/reference/review-criteria.zh-CN.md +18 -0
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +4 -3
- package/templates/.agents/templates/task.en.md +5 -0
- package/templates/.agents/templates/task.zh-CN.md +5 -0
- package/templates/.claude/settings.json +1 -1
- package/templates/.codex/hooks.json +17 -0
package/README.md
CHANGED
|
@@ -666,15 +666,15 @@ Use the top-level `.agents/.airc.json` `customTUIs` array when your team uses an
|
|
|
666
666
|
|
|
667
667
|
| Field | Required | Meaning |
|
|
668
668
|
|-------|----------|---------|
|
|
669
|
-
| `name` | Yes | Display name shown in reports and next-step guidance, for example
|
|
670
|
-
| `dir` | Yes | Command directory relative to the project root, for example
|
|
669
|
+
| `name` | Yes | Display name shown in reports and next-step guidance, for example `<your-tui-name>`. |
|
|
670
|
+
| `dir` | Yes | Command directory relative to the project root, for example `.<your-tui>/commands`. The path must stay inside the project root. |
|
|
671
671
|
| `invoke` | Yes | User-facing command template used in next-step guidance. |
|
|
672
672
|
|
|
673
673
|
Supported `invoke` placeholders:
|
|
674
674
|
|
|
675
675
|
| Placeholder | Replaced with | Example |
|
|
676
676
|
|-------------|---------------|---------|
|
|
677
|
-
| `${skillName}` | The skill command name, such as `review-task` or `commit`. |
|
|
677
|
+
| `${skillName}` | The skill command name, such as `review-task` or `commit`. | `<your-cli> ${skillName}` -> `<your-cli> review-task` |
|
|
678
678
|
| `${projectName}` | The `.airc.json` `project` value. Use this for namespaced commands. | `/${projectName}:${skillName}` -> `/agent-infra:review-task` |
|
|
679
679
|
|
|
680
680
|
Non-namespaced custom TUI:
|
|
@@ -683,9 +683,9 @@ Non-namespaced custom TUI:
|
|
|
683
683
|
{
|
|
684
684
|
"customTUIs": [
|
|
685
685
|
{
|
|
686
|
-
"name": "
|
|
687
|
-
"dir": "
|
|
688
|
-
"invoke": "
|
|
686
|
+
"name": "<your-tui-name>",
|
|
687
|
+
"dir": ".<your-tui>/commands",
|
|
688
|
+
"invoke": "<your-cli> ${skillName}"
|
|
689
689
|
}
|
|
690
690
|
]
|
|
691
691
|
}
|
|
@@ -698,8 +698,8 @@ Namespaced custom TUI:
|
|
|
698
698
|
"project": "agent-infra",
|
|
699
699
|
"customTUIs": [
|
|
700
700
|
{
|
|
701
|
-
"name": "
|
|
702
|
-
"dir": "
|
|
701
|
+
"name": "<your-tui-name>",
|
|
702
|
+
"dir": ".<your-tui>/commands",
|
|
703
703
|
"invoke": "/${projectName}:${skillName}"
|
|
704
704
|
}
|
|
705
705
|
]
|
|
@@ -777,7 +777,7 @@ The generated `.agents/.airc.json` file is the central contract between the boot
|
|
|
777
777
|
"project": "my-project",
|
|
778
778
|
"org": "my-org",
|
|
779
779
|
"language": "en",
|
|
780
|
-
"templateVersion": "v0.6.
|
|
780
|
+
"templateVersion": "v0.6.1",
|
|
781
781
|
"templates": {
|
|
782
782
|
"sources": [
|
|
783
783
|
{ "type": "local", "path": "~/private-templates" }
|
|
@@ -790,9 +790,9 @@ The generated `.agents/.airc.json` file is the central contract between the boot
|
|
|
790
790
|
},
|
|
791
791
|
"customTUIs": [
|
|
792
792
|
{
|
|
793
|
-
"name": "
|
|
794
|
-
"dir": "
|
|
795
|
-
"invoke": "
|
|
793
|
+
"name": "<your-tui-name>",
|
|
794
|
+
"dir": ".<your-tui>/commands",
|
|
795
|
+
"invoke": "<your-cli> ${skillName}"
|
|
796
796
|
}
|
|
797
797
|
],
|
|
798
798
|
"files": {
|
package/README.zh-CN.md
CHANGED
|
@@ -642,15 +642,15 @@ args: "<task-id>" # 可选
|
|
|
642
642
|
|
|
643
643
|
| 字段 | 必填 | 含义 |
|
|
644
644
|
|------|------|------|
|
|
645
|
-
| `name` | 是 | 报告和下一步提示中展示的工具名称,例如
|
|
646
|
-
| `dir` | 是 | 相对项目根目录的命令目录,例如
|
|
645
|
+
| `name` | 是 | 报告和下一步提示中展示的工具名称,例如 `<your-tui-name>`。 |
|
|
646
|
+
| `dir` | 是 | 相对项目根目录的命令目录,例如 `.<your-tui>/commands`。路径必须位于项目根目录内。 |
|
|
647
647
|
| `invoke` | 是 | 面向用户展示的命令模板,用于生成下一步提示。 |
|
|
648
648
|
|
|
649
649
|
`invoke` 支持的占位符:
|
|
650
650
|
|
|
651
651
|
| 占位符 | 替换为 | 示例 |
|
|
652
652
|
|--------|--------|------|
|
|
653
|
-
| `${skillName}` | skill 命令名,例如 `review-task` 或 `commit`。 |
|
|
653
|
+
| `${skillName}` | skill 命令名,例如 `review-task` 或 `commit`。 | `<your-cli> ${skillName}` -> `<your-cli> review-task` |
|
|
654
654
|
| `${projectName}` | `.airc.json` 中的 `project` 值,适用于带命名空间的命令。 | `/${projectName}:${skillName}` -> `/agent-infra:review-task` |
|
|
655
655
|
|
|
656
656
|
不带命名空间的自定义 TUI:
|
|
@@ -659,9 +659,9 @@ args: "<task-id>" # 可选
|
|
|
659
659
|
{
|
|
660
660
|
"customTUIs": [
|
|
661
661
|
{
|
|
662
|
-
"name": "
|
|
663
|
-
"dir": "
|
|
664
|
-
"invoke": "
|
|
662
|
+
"name": "<your-tui-name>",
|
|
663
|
+
"dir": ".<your-tui>/commands",
|
|
664
|
+
"invoke": "<your-cli> ${skillName}"
|
|
665
665
|
}
|
|
666
666
|
]
|
|
667
667
|
}
|
|
@@ -674,8 +674,8 @@ args: "<task-id>" # 可选
|
|
|
674
674
|
"project": "agent-infra",
|
|
675
675
|
"customTUIs": [
|
|
676
676
|
{
|
|
677
|
-
"name": "
|
|
678
|
-
"dir": "
|
|
677
|
+
"name": "<your-tui-name>",
|
|
678
|
+
"dir": ".<your-tui>/commands",
|
|
679
679
|
"invoke": "/${projectName}:${skillName}"
|
|
680
680
|
}
|
|
681
681
|
]
|
|
@@ -753,7 +753,7 @@ import-issue #42 从 GitHub Issue 导入任务
|
|
|
753
753
|
"project": "my-project",
|
|
754
754
|
"org": "my-org",
|
|
755
755
|
"language": "en",
|
|
756
|
-
"templateVersion": "v0.6.
|
|
756
|
+
"templateVersion": "v0.6.1",
|
|
757
757
|
"templates": {
|
|
758
758
|
"sources": [
|
|
759
759
|
{ "type": "local", "path": "~/private-templates" }
|
|
@@ -766,9 +766,9 @@ import-issue #42 从 GitHub Issue 导入任务
|
|
|
766
766
|
},
|
|
767
767
|
"customTUIs": [
|
|
768
768
|
{
|
|
769
|
-
"name": "
|
|
770
|
-
"dir": "
|
|
771
|
-
"invoke": "
|
|
769
|
+
"name": "<your-tui-name>",
|
|
770
|
+
"dir": ".<your-tui>/commands",
|
|
771
|
+
"invoke": "<your-cli> ${skillName}"
|
|
772
772
|
}
|
|
773
773
|
],
|
|
774
774
|
"files": {
|
package/bin/cli.ts
CHANGED
|
@@ -97,7 +97,11 @@ switch (command) {
|
|
|
97
97
|
break;
|
|
98
98
|
}
|
|
99
99
|
case 'version': {
|
|
100
|
-
|
|
100
|
+
if (process.argv[3] === '--raw') {
|
|
101
|
+
console.log(VERSION);
|
|
102
|
+
} else {
|
|
103
|
+
console.log(`agent-infra ${VERSION}`);
|
|
104
|
+
}
|
|
101
105
|
break;
|
|
102
106
|
}
|
|
103
107
|
case 'help':
|
package/dist/bin/cli.js
CHANGED
|
@@ -100,7 +100,12 @@ switch (command) {
|
|
|
100
100
|
break;
|
|
101
101
|
}
|
|
102
102
|
case 'version': {
|
|
103
|
-
|
|
103
|
+
if (process.argv[3] === '--raw') {
|
|
104
|
+
console.log(VERSION);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
console.log(`agent-infra ${VERSION}`);
|
|
108
|
+
}
|
|
104
109
|
break;
|
|
105
110
|
}
|
|
106
111
|
case 'help':
|
package/dist/lib/defaults.json
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"tools": [
|
|
11
11
|
"claude-code",
|
|
12
12
|
"codex",
|
|
13
|
-
"
|
|
14
|
-
"
|
|
13
|
+
"gemini-cli",
|
|
14
|
+
"opencode"
|
|
15
15
|
],
|
|
16
16
|
"dockerfile": null,
|
|
17
17
|
"vm": {
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"managed": [
|
|
28
28
|
".agents/QUICKSTART.md",
|
|
29
29
|
".agents/README.md",
|
|
30
|
+
".agents/hooks/",
|
|
30
31
|
".agents/rules/",
|
|
31
32
|
".agents/scripts/",
|
|
32
33
|
".agents/skills/",
|
|
@@ -34,7 +35,7 @@
|
|
|
34
35
|
".agents/workflows/",
|
|
35
36
|
".agents/workspace/README.md",
|
|
36
37
|
".claude/commands/",
|
|
37
|
-
".
|
|
38
|
+
".codex/hooks.json",
|
|
38
39
|
".gemini/commands/",
|
|
39
40
|
".git-hooks/check-version-format.sh",
|
|
40
41
|
".github/scripts/",
|
|
@@ -7,7 +7,7 @@ import { hostJoin } from "./engines/wsl2-paths.js";
|
|
|
7
7
|
const DEFAULTS = Object.freeze({
|
|
8
8
|
engine: null,
|
|
9
9
|
runtimes: ['node20'],
|
|
10
|
-
tools: ['claude-code', 'codex', '
|
|
10
|
+
tools: ['claude-code', 'codex', 'gemini-cli', 'opencode'],
|
|
11
11
|
dockerfile: null,
|
|
12
12
|
vm: {
|
|
13
13
|
cpu: null,
|
package/dist/package.json
CHANGED
package/lib/defaults.json
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"tools": [
|
|
11
11
|
"claude-code",
|
|
12
12
|
"codex",
|
|
13
|
-
"
|
|
14
|
-
"
|
|
13
|
+
"gemini-cli",
|
|
14
|
+
"opencode"
|
|
15
15
|
],
|
|
16
16
|
"dockerfile": null,
|
|
17
17
|
"vm": {
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"managed": [
|
|
28
28
|
".agents/QUICKSTART.md",
|
|
29
29
|
".agents/README.md",
|
|
30
|
+
".agents/hooks/",
|
|
30
31
|
".agents/rules/",
|
|
31
32
|
".agents/scripts/",
|
|
32
33
|
".agents/skills/",
|
|
@@ -34,7 +35,7 @@
|
|
|
34
35
|
".agents/workflows/",
|
|
35
36
|
".agents/workspace/README.md",
|
|
36
37
|
".claude/commands/",
|
|
37
|
-
".
|
|
38
|
+
".codex/hooks.json",
|
|
38
39
|
".gemini/commands/",
|
|
39
40
|
".git-hooks/check-version-format.sh",
|
|
40
41
|
".github/scripts/",
|
package/lib/sandbox/config.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { hostJoin } from './engines/wsl2-paths.ts';
|
|
|
8
8
|
const DEFAULTS = Object.freeze({
|
|
9
9
|
engine: null,
|
|
10
10
|
runtimes: ['node20'],
|
|
11
|
-
tools: ['claude-code', 'codex', '
|
|
11
|
+
tools: ['claude-code', 'codex', 'gemini-cli', 'opencode'],
|
|
12
12
|
dockerfile: null,
|
|
13
13
|
vm: {
|
|
14
14
|
cpu: null,
|
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.1",
|
|
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",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/cross-spawn": "^6.0.6",
|
|
63
|
-
"@types/node": "^
|
|
64
|
-
"typescript": "~
|
|
63
|
+
"@types/node": "^25.9.1",
|
|
64
|
+
"typescript": "~6.0"
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -199,15 +199,15 @@ Use the top-level `.agents/.airc.json` `customTUIs` array when your team uses an
|
|
|
199
199
|
|
|
200
200
|
| Field | Required | Meaning |
|
|
201
201
|
|-------|----------|---------|
|
|
202
|
-
| `name` | Yes | Display name shown in reports and next-step guidance, for example
|
|
203
|
-
| `dir` | Yes | Command directory relative to the project root, for example
|
|
202
|
+
| `name` | Yes | Display name shown in reports and next-step guidance, for example `<your-tui-name>`. |
|
|
203
|
+
| `dir` | Yes | Command directory relative to the project root, for example `.<your-tui>/commands`. The path must stay inside the project root. |
|
|
204
204
|
| `invoke` | Yes | User-facing command template used in next-step guidance. |
|
|
205
205
|
|
|
206
206
|
Supported `invoke` placeholders:
|
|
207
207
|
|
|
208
208
|
| Placeholder | Replaced with | Example |
|
|
209
209
|
|-------------|---------------|---------|
|
|
210
|
-
| `${skillName}` | The skill command name, such as `review-task` or `commit`. |
|
|
210
|
+
| `${skillName}` | The skill command name, such as `review-task` or `commit`. | `<your-cli> ${skillName}` -> `<your-cli> review-task` |
|
|
211
211
|
| `${projectName}` | The `.airc.json` `project` value. Use this for namespaced commands. | `/${projectName}:${skillName}` -> `/agent-infra:review-task` |
|
|
212
212
|
|
|
213
213
|
Non-namespaced custom TUI:
|
|
@@ -216,9 +216,9 @@ Non-namespaced custom TUI:
|
|
|
216
216
|
{
|
|
217
217
|
"customTUIs": [
|
|
218
218
|
{
|
|
219
|
-
"name": "
|
|
220
|
-
"dir": "
|
|
221
|
-
"invoke": "
|
|
219
|
+
"name": "<your-tui-name>",
|
|
220
|
+
"dir": ".<your-tui>/commands",
|
|
221
|
+
"invoke": "<your-cli> ${skillName}"
|
|
222
222
|
}
|
|
223
223
|
]
|
|
224
224
|
}
|
|
@@ -231,8 +231,8 @@ Namespaced custom TUI:
|
|
|
231
231
|
"project": "agent-infra",
|
|
232
232
|
"customTUIs": [
|
|
233
233
|
{
|
|
234
|
-
"name": "
|
|
235
|
-
"dir": "
|
|
234
|
+
"name": "<your-tui-name>",
|
|
235
|
+
"dir": ".<your-tui>/commands",
|
|
236
236
|
"invoke": "/${projectName}:${skillName}"
|
|
237
237
|
}
|
|
238
238
|
]
|
|
@@ -199,15 +199,15 @@ args: "<task-id>" # 可选
|
|
|
199
199
|
|
|
200
200
|
| 字段 | 必填 | 含义 |
|
|
201
201
|
|------|------|------|
|
|
202
|
-
| `name` | 是 | 报告和下一步提示中展示的工具名称,例如
|
|
203
|
-
| `dir` | 是 | 相对项目根目录的命令目录,例如
|
|
202
|
+
| `name` | 是 | 报告和下一步提示中展示的工具名称,例如 `<your-tui-name>`。 |
|
|
203
|
+
| `dir` | 是 | 相对项目根目录的命令目录,例如 `.<your-tui>/commands`。路径必须位于项目根目录内。 |
|
|
204
204
|
| `invoke` | 是 | 面向用户展示的命令模板,用于生成下一步提示。 |
|
|
205
205
|
|
|
206
206
|
`invoke` 支持的占位符:
|
|
207
207
|
|
|
208
208
|
| 占位符 | 替换为 | 示例 |
|
|
209
209
|
|--------|--------|------|
|
|
210
|
-
| `${skillName}` | skill 命令名,例如 `review-task` 或 `commit`。 |
|
|
210
|
+
| `${skillName}` | skill 命令名,例如 `review-task` 或 `commit`。 | `<your-cli> ${skillName}` -> `<your-cli> review-task` |
|
|
211
211
|
| `${projectName}` | `.airc.json` 中的 `project` 值,适用于带命名空间的命令。 | `/${projectName}:${skillName}` -> `/agent-infra:review-task` |
|
|
212
212
|
|
|
213
213
|
不带命名空间的自定义 TUI:
|
|
@@ -216,9 +216,9 @@ args: "<task-id>" # 可选
|
|
|
216
216
|
{
|
|
217
217
|
"customTUIs": [
|
|
218
218
|
{
|
|
219
|
-
"name": "
|
|
220
|
-
"dir": "
|
|
221
|
-
"invoke": "
|
|
219
|
+
"name": "<your-tui-name>",
|
|
220
|
+
"dir": ".<your-tui>/commands",
|
|
221
|
+
"invoke": "<your-cli> ${skillName}"
|
|
222
222
|
}
|
|
223
223
|
]
|
|
224
224
|
}
|
|
@@ -231,8 +231,8 @@ args: "<task-id>" # 可选
|
|
|
231
231
|
"project": "agent-infra",
|
|
232
232
|
"customTUIs": [
|
|
233
233
|
{
|
|
234
|
-
"name": "
|
|
235
|
-
"dir": "
|
|
234
|
+
"name": "<your-tui-name>",
|
|
235
|
+
"dir": ".<your-tui>/commands",
|
|
236
236
|
"invoke": "/${projectName}:${skillName}"
|
|
237
237
|
}
|
|
238
238
|
]
|
|
@@ -10,7 +10,7 @@ hook_command=$(
|
|
|
10
10
|
try {
|
|
11
11
|
const payload = JSON.parse(Buffer.concat(chunks).toString());
|
|
12
12
|
process.stdout.write(payload.tool_input && payload.tool_input.command || "");
|
|
13
|
-
} catch
|
|
13
|
+
} catch {
|
|
14
14
|
process.stdout.write("");
|
|
15
15
|
}
|
|
16
16
|
});
|
|
@@ -30,14 +30,14 @@ repo_root=$(
|
|
|
30
30
|
)
|
|
31
31
|
|
|
32
32
|
if sh "$repo_root/.git-hooks/check-version-format.sh"; then
|
|
33
|
-
echo "
|
|
33
|
+
echo "AI hook: version check passed."
|
|
34
34
|
exit 0
|
|
35
35
|
else
|
|
36
36
|
status=$?
|
|
37
37
|
fi
|
|
38
38
|
|
|
39
39
|
if [ "$status" -eq 1 ]; then
|
|
40
|
-
echo "
|
|
40
|
+
echo "AI hook: blocking git commit (version format error)." >&2
|
|
41
41
|
exit 2
|
|
42
42
|
fi
|
|
43
43
|
|
|
@@ -149,6 +149,12 @@ gh api "repos/$upstream_repo/issues/{issue-number}" -X PATCH \
|
|
|
149
149
|
|
|
150
150
|
Failure is non-blocking.
|
|
151
151
|
|
|
152
|
+
### 6.5 Set Issue Fields (Optional)
|
|
153
|
+
|
|
154
|
+
If `has_push=true`, read `.agents/rules/issue-fields.md` and follow Flow A to write any applicable non-empty `priority`, `effort`, `start_date`, and `target_date` values from `task.md`.
|
|
155
|
+
|
|
156
|
+
Field write failures are non-blocking.
|
|
157
|
+
|
|
152
158
|
### 7. Write Back task.md
|
|
153
159
|
|
|
154
160
|
Update task.md:
|
|
@@ -149,6 +149,12 @@ gh api "repos/$upstream_repo/issues/{issue-number}" -X PATCH \
|
|
|
149
149
|
|
|
150
150
|
设置失败不阻断流程。
|
|
151
151
|
|
|
152
|
+
### 6.5 设置 Issue 字段(可选)
|
|
153
|
+
|
|
154
|
+
如果 `has_push=true`,读取 `.agents/rules/issue-fields.md`,按流程 A 写入 `task.md` 中适用且非空的 `priority`、`effort`、`start_date` 和 `target_date`。
|
|
155
|
+
|
|
156
|
+
字段写入失败不阻断流程。
|
|
157
|
+
|
|
152
158
|
### 7. 回写 task.md
|
|
153
159
|
|
|
154
160
|
更新 task.md:
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Issue Fields
|
|
2
|
+
|
|
3
|
+
Read this file before writing or verifying Issue Type pinned custom fields.
|
|
4
|
+
|
|
5
|
+
## Boundary
|
|
6
|
+
|
|
7
|
+
- Use this rule only after `upstream_repo`, `has_push`, and the Issue number are known.
|
|
8
|
+
- If `has_push=false`, skip direct field writes and continue.
|
|
9
|
+
- Fetch the organization's current Issue Type schema before each write; do not hard-code the field set.
|
|
10
|
+
- Missing, empty, or unresolvable values are skipped. Field writes are best-effort and must not block the workflow.
|
|
11
|
+
|
|
12
|
+
## Supported Task Frontmatter
|
|
13
|
+
|
|
14
|
+
All fields are optional:
|
|
15
|
+
|
|
16
|
+
| task.md field | Issue field | Value format |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `priority` | `Priority` | `Urgent`, `High`, `Medium`, or `Low` |
|
|
19
|
+
| `effort` | `Effort` | `High`, `Medium`, or `Low` |
|
|
20
|
+
| `start_date` | `Start date` | `YYYY-MM-DD` |
|
|
21
|
+
| `target_date` | `Target date` | `YYYY-MM-DD` |
|
|
22
|
+
|
|
23
|
+
Localized option input may be normalized before writing:
|
|
24
|
+
|
|
25
|
+
| Input | Stored option |
|
|
26
|
+
|---|---|
|
|
27
|
+
| `紧急` | `Urgent` |
|
|
28
|
+
| `高` | `High` |
|
|
29
|
+
| `中` | `Medium` |
|
|
30
|
+
| `低` | `Low` |
|
|
31
|
+
|
|
32
|
+
AI agents may infer `priority` and `effort` from the title and description when creating or refining tasks, but must keep date fields empty unless the user or source Issue provides explicit dates. Human edits in `task.md` take precedence.
|
|
33
|
+
|
|
34
|
+
## GraphQL Reference
|
|
35
|
+
|
|
36
|
+
Read Issue Type pinned fields:
|
|
37
|
+
|
|
38
|
+
```graphql
|
|
39
|
+
query($owner:String!){
|
|
40
|
+
organization(login:$owner){ issueTypes(first:20){ nodes{
|
|
41
|
+
id name
|
|
42
|
+
pinnedFields{
|
|
43
|
+
__typename
|
|
44
|
+
... on IssueFieldSingleSelect{ id name options{ id name } }
|
|
45
|
+
... on IssueFieldDate{ id name }
|
|
46
|
+
... on IssueFieldText{ id name }
|
|
47
|
+
... on IssueFieldNumber{ id name }
|
|
48
|
+
}
|
|
49
|
+
} } }
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Read one Issue's current type and field values:
|
|
54
|
+
|
|
55
|
+
```graphql
|
|
56
|
+
query($owner:String!,$name:String!,$number:Int!){
|
|
57
|
+
repository(owner:$owner,name:$name){ issue(number:$number){
|
|
58
|
+
id
|
|
59
|
+
issueType{ name pinnedFields{
|
|
60
|
+
__typename
|
|
61
|
+
... on IssueFieldSingleSelect{ id name options{ id name } }
|
|
62
|
+
... on IssueFieldDate{ id name }
|
|
63
|
+
... on IssueFieldText{ id name }
|
|
64
|
+
... on IssueFieldNumber{ id name }
|
|
65
|
+
} }
|
|
66
|
+
issueFieldValues(first:50){ nodes{
|
|
67
|
+
__typename
|
|
68
|
+
... on IssueFieldSingleSelectValue{ name optionId field{ ... on IssueFieldSingleSelect{ name } } }
|
|
69
|
+
... on IssueFieldDateValue{ value field{ ... on IssueFieldDate{ name } } }
|
|
70
|
+
... on IssueFieldTextValue{ value field{ ... on IssueFieldText{ name } } }
|
|
71
|
+
... on IssueFieldNumberValue{ value field{ ... on IssueFieldNumber{ name } } }
|
|
72
|
+
} }
|
|
73
|
+
} }
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Write or clear fields and update Issue Type:
|
|
78
|
+
|
|
79
|
+
```graphql
|
|
80
|
+
mutation($issueId:ID!,$issueFields:[IssueFieldCreateOrUpdateInput!]!){
|
|
81
|
+
setIssueFieldValue(input:{issueId:$issueId,issueFields:$issueFields}){ issue{ id } }
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
mutation($issueId:ID!,$issueTypeId:ID){
|
|
85
|
+
updateIssueIssueType(input:{issueId:$issueId,issueTypeId:$issueTypeId}){ issue{ id } }
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`IssueFieldCreateOrUpdateInput` supports `fieldId`, `singleSelectOptionId`, `dateValue`, `textValue`, `numberValue`, and `delete`.
|
|
90
|
+
|
|
91
|
+
Minimal command shells:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
gh api graphql \
|
|
95
|
+
-f query='query($owner:String!){organization(login:$owner){issueTypes(first:20){nodes{id name pinnedFields{__typename ... on IssueFieldSingleSelect{id name options{id name}} ... on IssueFieldDate{id name} ... on IssueFieldText{id name} ... on IssueFieldNumber{id name}}}}}}' \
|
|
96
|
+
-F owner="{owner}"
|
|
97
|
+
|
|
98
|
+
gh api graphql \
|
|
99
|
+
-f query='query($owner:String!,$name:String!,$number:Int!){repository(owner:$owner,name:$name){issue(number:$number){id issueType{name pinnedFields{__typename ... on IssueFieldSingleSelect{id name options{id name}} ... on IssueFieldDate{id name} ... on IssueFieldText{id name} ... on IssueFieldNumber{id name}}} issueFieldValues(first:50){nodes{__typename ... on IssueFieldSingleSelectValue{name optionId field{... on IssueFieldSingleSelect{name}}} ... on IssueFieldDateValue{value field{... on IssueFieldDate{name}}} ... on IssueFieldTextValue{value field{... on IssueFieldText{name}}} ... on IssueFieldNumberValue{value field{... on IssueFieldNumber{name}}}}}}}}' \
|
|
100
|
+
-F owner="{owner}" -F name="{repo}" -F number="{issue-number}"
|
|
101
|
+
|
|
102
|
+
gh api graphql --input - <<'JSON'
|
|
103
|
+
{
|
|
104
|
+
"query": "mutation($issueId:ID!,$issueFields:[IssueFieldCreateOrUpdateInput!]!){setIssueFieldValue(input:{issueId:$issueId,issueFields:$issueFields}){issue{id}}}",
|
|
105
|
+
"variables": {
|
|
106
|
+
"issueId": "{issue-id}",
|
|
107
|
+
"issueFields": [
|
|
108
|
+
{ "fieldId": "{field-id}", "singleSelectOptionId": "{option-id}" },
|
|
109
|
+
{ "fieldId": "{date-field-id}", "dateValue": "YYYY-MM-DD" },
|
|
110
|
+
{ "fieldId": "{old-field-id}", "delete": true }
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
JSON
|
|
115
|
+
|
|
116
|
+
gh api graphql --input - <<'JSON'
|
|
117
|
+
{
|
|
118
|
+
"query": "mutation($issueId:ID!,$issueTypeId:ID){updateIssueIssueType(input:{issueId:$issueId,issueTypeId:$issueTypeId}){issue{id}}}",
|
|
119
|
+
"variables": {
|
|
120
|
+
"issueId": "{issue-id}",
|
|
121
|
+
"issueTypeId": "{issue-type-id}"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
JSON
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Values not listed in the localization table are treated as literal option names, which is intended for canonical English input.
|
|
128
|
+
|
|
129
|
+
## Flow A: Write Fields After Issue Creation
|
|
130
|
+
|
|
131
|
+
1. Stop if `has_push` is not `true`.
|
|
132
|
+
2. Resolve `{owner}` from `$upstream_repo` and query `organization.issueTypes`.
|
|
133
|
+
3. Select the target Issue Type's `pinnedFields`.
|
|
134
|
+
4. Read non-empty `priority`, `effort`, `start_date`, and `target_date` values from `task.md`.
|
|
135
|
+
5. For each value:
|
|
136
|
+
- Skip it when the target type does not pin a same-name field.
|
|
137
|
+
- For single-select fields, normalize localized input and match the option by name.
|
|
138
|
+
- For date fields, write only `YYYY-MM-DD` values.
|
|
139
|
+
6. Submit one `setIssueFieldValue` mutation with all resolved inputs. If no input remains, skip.
|
|
140
|
+
|
|
141
|
+
## Flow B: Set Type And Migrate Fields
|
|
142
|
+
|
|
143
|
+
Use this flow whenever an existing Issue Type is changed.
|
|
144
|
+
|
|
145
|
+
1. Stop if `has_push` is not `true`.
|
|
146
|
+
2. Read the Issue id, current Issue Type, pinned fields, and current field values.
|
|
147
|
+
3. Query the organization Issue Type list and resolve the target Issue Type id.
|
|
148
|
+
4. Run `updateIssueIssueType` with the target Issue Type id.
|
|
149
|
+
5. Resolve the target type's pinned fields.
|
|
150
|
+
6. For each old field value:
|
|
151
|
+
- If the target type has a same-name field, write the value again. For single-select values, resolve the target option id by option name.
|
|
152
|
+
- If the target type does not have a same-name field, send `{ fieldId, delete: true }` for the old field.
|
|
153
|
+
7. Submit one `setIssueFieldValue` mutation with all migration inputs. Empty migrations are skipped.
|
|
154
|
+
|
|
155
|
+
Both flows are idempotent. Rewriting an unchanged value or deleting an already empty field is acceptable.
|