@fitlab-ai/agent-infra 0.5.1 → 0.5.3
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 +17 -3
- package/README.zh-CN.md +17 -3
- package/lib/defaults.json +3 -0
- package/lib/init.js +15 -5
- package/lib/merge.js +22 -7
- package/lib/render.js +77 -15
- package/lib/sandbox/commands/enter.js +22 -7
- package/lib/sandbox/commands/rm.js +1 -1
- package/lib/sandbox/runtimes/base.dockerfile +27 -1
- package/lib/update.js +19 -5
- package/package.json +2 -1
- package/templates/.agents/{README.md → README.en.md} +13 -3
- package/templates/.agents/README.zh-CN.md +13 -3
- package/templates/.agents/rules/issue-pr-commands.github.en.md +111 -0
- package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +111 -0
- package/templates/.agents/rules/label-milestone-setup.github.en.md +50 -0
- package/templates/.agents/rules/label-milestone-setup.github.zh-CN.md +50 -0
- package/templates/.agents/rules/release-commands.github.en.md +30 -0
- package/templates/.agents/rules/release-commands.github.zh-CN.md +30 -0
- package/templates/.agents/rules/security-alerts.github.en.md +43 -0
- package/templates/.agents/rules/security-alerts.github.zh-CN.md +43 -0
- package/templates/.agents/scripts/validate-artifact.js +3 -5
- package/templates/.agents/skills/analyze-task/{SKILL.md → SKILL.en.md} +2 -2
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/archive-tasks/scripts/archive-tasks.sh +1 -1
- package/templates/.agents/skills/block-task/{SKILL.md → SKILL.en.md} +2 -2
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/cancel-task/{SKILL.md → SKILL.en.md} +18 -17
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +18 -17
- package/templates/.agents/skills/close-codescan/{SKILL.md → SKILL.en.md} +5 -13
- package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +5 -13
- package/templates/.agents/skills/close-dependabot/{SKILL.md → SKILL.en.md} +7 -15
- package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +7 -15
- package/templates/.agents/skills/commit/{SKILL.md → SKILL.en.md} +1 -1
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/commit/reference/{task-status-update.md → task-status-update.en.md} +2 -2
- package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +2 -2
- package/templates/.agents/skills/complete-task/{SKILL.md → SKILL.en.md} +11 -11
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +11 -11
- package/templates/.agents/skills/create-issue/{SKILL.md → SKILL.en.md} +3 -6
- package/templates/.agents/skills/create-issue/SKILL.zh-CN.md +3 -6
- package/templates/.agents/skills/create-issue/reference/{label-and-type.md → label-and-type.en.md} +4 -16
- package/templates/.agents/skills/create-issue/reference/label-and-type.zh-CN.md +4 -16
- package/templates/.agents/skills/create-pr/{SKILL.md → SKILL.en.md} +4 -5
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +4 -5
- package/templates/.agents/skills/create-pr/reference/{pr-body-template.md → pr-body-template.en.md} +8 -13
- package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +8 -13
- package/templates/.agents/skills/create-release-note/{SKILL.md → SKILL.en.md} +6 -18
- package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +6 -18
- package/templates/.agents/skills/create-task/{SKILL.md → SKILL.en.md} +4 -4
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/implement-task/{SKILL.md → SKILL.en.md} +2 -2
- package/templates/.agents/skills/implement-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/import-codescan/{SKILL.md → SKILL.en.md} +3 -5
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +3 -5
- package/templates/.agents/skills/import-dependabot/{SKILL.md → SKILL.en.md} +3 -5
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +3 -5
- package/templates/.agents/skills/import-issue/{SKILL.md → SKILL.en.md} +6 -14
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +6 -14
- package/templates/.agents/skills/init-labels/{SKILL.md → SKILL.en.md} +9 -13
- package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +9 -13
- package/templates/.agents/skills/init-milestones/{SKILL.md → SKILL.en.md} +5 -6
- package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +5 -6
- package/templates/.agents/skills/plan-task/{SKILL.md → SKILL.en.md} +2 -2
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/refine-task/{SKILL.md → SKILL.en.md} +2 -2
- package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/refine-title/{SKILL.md → SKILL.en.md} +7 -17
- package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +6 -16
- package/templates/.agents/skills/release/{SKILL.md → SKILL.en.md} +2 -1
- package/templates/.agents/skills/release/SKILL.zh-CN.md +2 -1
- package/templates/.agents/skills/restore-task/{SKILL.md → SKILL.en.md} +7 -13
- package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +7 -13
- package/templates/.agents/skills/review-task/{SKILL.md → SKILL.en.md} +2 -2
- package/templates/.agents/skills/review-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +219 -59
- package/templates/.agents/templates/{task.md → task.en.md} +3 -3
- package/templates/.agents/templates/task.zh-CN.md +3 -3
- /package/templates/.agents/{QUICKSTART.md → QUICKSTART.en.md} +0 -0
- /package/templates/.agents/rules/{commit-and-pr.md → commit-and-pr.en.md} +0 -0
- /package/templates/.agents/rules/{issue-sync.md → issue-sync.github.en.md} +0 -0
- /package/templates/.agents/rules/{issue-sync.zh-CN.md → issue-sync.github.zh-CN.md} +0 -0
- /package/templates/.agents/rules/{milestone-inference.md → milestone-inference.github.en.md} +0 -0
- /package/templates/.agents/rules/{milestone-inference.zh-CN.md → milestone-inference.github.zh-CN.md} +0 -0
- /package/templates/.agents/rules/{pr-sync.md → pr-sync.github.en.md} +0 -0
- /package/templates/.agents/rules/{pr-sync.zh-CN.md → pr-sync.github.zh-CN.md} +0 -0
- /package/templates/.agents/rules/{task-management.md → task-management.en.md} +0 -0
- /package/templates/.agents/skills/archive-tasks/{SKILL.md → SKILL.en.md} +0 -0
- /package/templates/.agents/skills/check-task/{SKILL.md → SKILL.en.md} +0 -0
- /package/templates/.agents/skills/commit/reference/{commit-message.md → commit-message.en.md} +0 -0
- /package/templates/.agents/skills/commit/reference/{copyright-check.md → copyright-check.en.md} +0 -0
- /package/templates/.agents/skills/commit/reference/{pr-summary-sync.md → pr-summary-sync.en.md} +0 -0
- /package/templates/.agents/skills/create-issue/reference/{template-matching.md → template-matching.en.md} +0 -0
- /package/templates/.agents/skills/create-pr/reference/{branch-strategy.md → branch-strategy.en.md} +0 -0
- /package/templates/.agents/skills/create-pr/reference/{comment-publish.md → comment-publish.en.md} +0 -0
- /package/templates/.agents/skills/implement-task/reference/{branch-management.md → branch-management.en.md} +0 -0
- /package/templates/.agents/skills/implement-task/reference/{implementation-rules.md → implementation-rules.en.md} +0 -0
- /package/templates/.agents/skills/implement-task/reference/{output-template.md → output-template.en.md} +0 -0
- /package/templates/.agents/skills/implement-task/reference/{report-template.md → report-template.en.md} +0 -0
- /package/templates/.agents/skills/init-labels/scripts/{init-labels.sh → init-labels.github.sh} +0 -0
- /package/templates/.agents/skills/init-milestones/scripts/{init-milestones.sh → init-milestones.github.sh} +0 -0
- /package/templates/.agents/skills/refine-task/reference/{fix-workflow.md → fix-workflow.en.md} +0 -0
- /package/templates/.agents/skills/refine-task/reference/{report-template.md → report-template.en.md} +0 -0
- /package/templates/.agents/skills/release/scripts/{manage-milestones.sh → manage-milestones.github.sh} +0 -0
- /package/templates/.agents/skills/review-task/reference/{output-templates.md → output-templates.en.md} +0 -0
- /package/templates/.agents/skills/review-task/reference/{report-template.md → report-template.en.md} +0 -0
- /package/templates/.agents/skills/review-task/reference/{review-criteria.md → review-criteria.en.md} +0 -0
- /package/templates/.agents/skills/test/{SKILL.md → SKILL.en.md} +0 -0
- /package/templates/.agents/skills/test-integration/{SKILL.md → SKILL.en.md} +0 -0
- /package/templates/.agents/skills/update-agent-infra/{SKILL.md → SKILL.en.md} +0 -0
- /package/templates/.agents/skills/upgrade-dependency/{SKILL.md → SKILL.en.md} +0 -0
- /package/templates/.agents/templates/{handoff.md → handoff.en.md} +0 -0
- /package/templates/.agents/templates/{review-report.md → review-report.en.md} +0 -0
- /package/templates/.agents/workflows/{bug-fix.yaml → bug-fix.en.yaml} +0 -0
- /package/templates/.agents/workflows/{code-review.yaml → code-review.en.yaml} +0 -0
- /package/templates/.agents/workflows/{feature-development.yaml → feature-development.en.yaml} +0 -0
- /package/templates/.agents/workflows/{refactoring.yaml → refactoring.en.yaml} +0 -0
- /package/templates/.agents/workspace/{README.md → README.en.md} +0 -0
- /package/templates/.claude/commands/{analyze-task.md → analyze-task.en.md} +0 -0
- /package/templates/.claude/commands/{archive-tasks.md → archive-tasks.en.md} +0 -0
- /package/templates/.claude/commands/{block-task.md → block-task.en.md} +0 -0
- /package/templates/.claude/commands/{cancel-task.md → cancel-task.en.md} +0 -0
- /package/templates/.claude/commands/{check-task.md → check-task.en.md} +0 -0
- /package/templates/.claude/commands/{close-codescan.md → close-codescan.en.md} +0 -0
- /package/templates/.claude/commands/{close-dependabot.md → close-dependabot.en.md} +0 -0
- /package/templates/.claude/commands/{commit.md → commit.en.md} +0 -0
- /package/templates/.claude/commands/{complete-task.md → complete-task.en.md} +0 -0
- /package/templates/.claude/commands/{create-issue.md → create-issue.en.md} +0 -0
- /package/templates/.claude/commands/{create-pr.md → create-pr.en.md} +0 -0
- /package/templates/.claude/commands/{create-release-note.md → create-release-note.en.md} +0 -0
- /package/templates/.claude/commands/{create-task.md → create-task.en.md} +0 -0
- /package/templates/.claude/commands/{implement-task.md → implement-task.en.md} +0 -0
- /package/templates/.claude/commands/{import-codescan.md → import-codescan.en.md} +0 -0
- /package/templates/.claude/commands/{import-dependabot.md → import-dependabot.en.md} +0 -0
- /package/templates/.claude/commands/{import-issue.md → import-issue.en.md} +0 -0
- /package/templates/.claude/commands/{init-labels.md → init-labels.en.md} +0 -0
- /package/templates/.claude/commands/{init-milestones.md → init-milestones.en.md} +0 -0
- /package/templates/.claude/commands/{plan-task.md → plan-task.en.md} +0 -0
- /package/templates/.claude/commands/{refine-task.md → refine-task.en.md} +0 -0
- /package/templates/.claude/commands/{refine-title.md → refine-title.en.md} +0 -0
- /package/templates/.claude/commands/{release.md → release.en.md} +0 -0
- /package/templates/.claude/commands/{restore-task.md → restore-task.en.md} +0 -0
- /package/templates/.claude/commands/{review-task.md → review-task.en.md} +0 -0
- /package/templates/.claude/commands/{test-integration.md → test-integration.en.md} +0 -0
- /package/templates/.claude/commands/{test.md → test.en.md} +0 -0
- /package/templates/.claude/commands/{update-agent-infra.md → update-agent-infra.en.md} +0 -0
- /package/templates/.claude/commands/{upgrade-dependency.md → upgrade-dependency.en.md} +0 -0
- /package/templates/.gemini/commands/_project_/{analyze-task.toml → analyze-task.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{archive-tasks.toml → archive-tasks.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{block-task.toml → block-task.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{cancel-task.toml → cancel-task.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{check-task.toml → check-task.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{close-codescan.toml → close-codescan.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{close-dependabot.toml → close-dependabot.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{commit.toml → commit.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{complete-task.toml → complete-task.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{create-issue.toml → create-issue.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{create-pr.toml → create-pr.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{create-release-note.toml → create-release-note.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{create-task.toml → create-task.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{implement-task.toml → implement-task.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{import-codescan.toml → import-codescan.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{import-dependabot.toml → import-dependabot.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{import-issue.toml → import-issue.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{init-labels.toml → init-labels.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{init-milestones.toml → init-milestones.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{plan-task.toml → plan-task.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{refine-task.toml → refine-task.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{refine-title.toml → refine-title.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{release.toml → release.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{restore-task.toml → restore-task.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{review-task.toml → review-task.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{test-integration.toml → test-integration.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{test.toml → test.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{update-agent-infra.toml → update-agent-infra.en.toml} +0 -0
- /package/templates/.gemini/commands/_project_/{upgrade-dependency.toml → upgrade-dependency.en.toml} +0 -0
- /package/templates/.opencode/commands/{analyze-task.md → analyze-task.en.md} +0 -0
- /package/templates/.opencode/commands/{archive-tasks.md → archive-tasks.en.md} +0 -0
- /package/templates/.opencode/commands/{block-task.md → block-task.en.md} +0 -0
- /package/templates/.opencode/commands/{cancel-task.md → cancel-task.en.md} +0 -0
- /package/templates/.opencode/commands/{check-task.md → check-task.en.md} +0 -0
- /package/templates/.opencode/commands/{close-codescan.md → close-codescan.en.md} +0 -0
- /package/templates/.opencode/commands/{close-dependabot.md → close-dependabot.en.md} +0 -0
- /package/templates/.opencode/commands/{commit.md → commit.en.md} +0 -0
- /package/templates/.opencode/commands/{complete-task.md → complete-task.en.md} +0 -0
- /package/templates/.opencode/commands/{create-issue.md → create-issue.en.md} +0 -0
- /package/templates/.opencode/commands/{create-pr.md → create-pr.en.md} +0 -0
- /package/templates/.opencode/commands/{create-release-note.md → create-release-note.en.md} +0 -0
- /package/templates/.opencode/commands/{create-task.md → create-task.en.md} +0 -0
- /package/templates/.opencode/commands/{implement-task.md → implement-task.en.md} +0 -0
- /package/templates/.opencode/commands/{import-codescan.md → import-codescan.en.md} +0 -0
- /package/templates/.opencode/commands/{import-dependabot.md → import-dependabot.en.md} +0 -0
- /package/templates/.opencode/commands/{import-issue.md → import-issue.en.md} +0 -0
- /package/templates/.opencode/commands/{init-labels.md → init-labels.en.md} +0 -0
- /package/templates/.opencode/commands/{init-milestones.md → init-milestones.en.md} +0 -0
- /package/templates/.opencode/commands/{plan-task.md → plan-task.en.md} +0 -0
- /package/templates/.opencode/commands/{refine-task.md → refine-task.en.md} +0 -0
- /package/templates/.opencode/commands/{refine-title.md → refine-title.en.md} +0 -0
- /package/templates/.opencode/commands/{release.md → release.en.md} +0 -0
- /package/templates/.opencode/commands/{restore-task.md → restore-task.en.md} +0 -0
- /package/templates/.opencode/commands/{review-task.md → review-task.en.md} +0 -0
- /package/templates/.opencode/commands/{test-integration.md → test-integration.en.md} +0 -0
- /package/templates/.opencode/commands/{test.md → test.en.md} +0 -0
- /package/templates/.opencode/commands/{update-agent-infra.md → update-agent-infra.en.md} +0 -0
- /package/templates/.opencode/commands/{upgrade-dependency.md → upgrade-dependency.en.md} +0 -0
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<h1 align="center">Agent Infra</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
|
|
8
|
+
Collaboration infrastructure for AI coding agents — skills, workflows, and sandboxes for Claude Code, Codex, Gemini CLI, and OpenCode.
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
@@ -29,12 +29,26 @@
|
|
|
29
29
|
|
|
30
30
|
Teams increasingly mix Claude Code, Codex, Gemini CLI, OpenCode, and other AI TUIs in the same repository, but each tool tends to introduce its own commands, prompts, and local conventions. Without a shared layer, the result is fragmented workflows, duplicated setup, and task history that is difficult to audit.
|
|
31
31
|
|
|
32
|
-
agent-infra standardizes that
|
|
32
|
+
agent-infra standardizes that shared infrastructure. It gives every supported AI TUI the same task lifecycle, the same skill vocabulary, the same project governance files, isolated development sandboxes, and the same upgrade path, so teams can switch tools without rebuilding process from scratch.
|
|
33
33
|
|
|
34
34
|
<a id="see-it-in-action"></a>
|
|
35
35
|
|
|
36
36
|
## See it in Action
|
|
37
37
|
|
|
38
|
+
### Install & Initialize
|
|
39
|
+
|
|
40
|
+
<p align="center">
|
|
41
|
+
<img src="./assets/demo-init.gif" alt="CLI install and initialize demo" width="100%" style="max-width: 720px;">
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
Once initialized, open the project in your AI TUI and install the latest skills:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
/update-agent-infra
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
> AI reads `.agents/.airc.json`, auto-locates the installed template root, and syncs the latest skill manifests, managed files, and registry deterministically via `sync-templates.js`.
|
|
51
|
+
|
|
38
52
|
**Scenario**: Issue #42 reports *"Login API returns 500 when email contains a plus sign"*. Here is the full fix lifecycle — AI does the heavy lifting, you stay in control:
|
|
39
53
|
|
|
40
54
|
```bash
|
|
@@ -396,7 +410,7 @@ The generated `.agents/.airc.json` file is the central contract between the boot
|
|
|
396
410
|
"project": "my-project",
|
|
397
411
|
"org": "my-org",
|
|
398
412
|
"language": "en",
|
|
399
|
-
"templateVersion": "v0.5.
|
|
413
|
+
"templateVersion": "v0.5.3",
|
|
400
414
|
"files": {
|
|
401
415
|
"managed": [
|
|
402
416
|
".agents/workspace/README.md",
|
package/README.zh-CN.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<h1 align="center">Agent Infra</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
AI
|
|
8
|
+
AI 编程代理的协作基础设施 —— 为 Claude Code、Codex、Gemini CLI、OpenCode 提供 skills、工作流和沙箱。
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
@@ -29,12 +29,26 @@
|
|
|
29
29
|
|
|
30
30
|
越来越多的团队会在同一个仓库里混用 Claude Code、Codex、Gemini CLI、OpenCode 等 AI TUI,但每个工具往往都会带来自己的命令体系、提示词习惯和本地约定。缺少共享层时,结果通常是工作流割裂、初始化重复、任务历史难以追踪。
|
|
31
31
|
|
|
32
|
-
agent-infra
|
|
32
|
+
agent-infra 的目标就是把这层共享基础设施标准化。它为所有支持的 AI TUI 提供统一的任务生命周期、统一的 skill 词汇、统一的项目治理文件、隔离的开发沙箱以及统一的升级路径,让团队切换工具时不必重新发明流程。
|
|
33
33
|
|
|
34
34
|
<a id="see-it-in-action"></a>
|
|
35
35
|
|
|
36
36
|
## 实战演示
|
|
37
37
|
|
|
38
|
+
### 安装与初始化
|
|
39
|
+
|
|
40
|
+
<p align="center">
|
|
41
|
+
<img src="./assets/demo-init.gif" alt="CLI 安装初始化演示" width="100%" style="max-width: 720px;">
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
完成初始化后,在你的 AI TUI 中打开项目并安装最新 skills:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
/update-agent-infra
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
> AI 读取 `.agents/.airc.json`,自动定位已安装的模板根目录,并通过 `sync-templates.js` 确定性地同步最新的 skill 清单、managed 文件和注册表。
|
|
51
|
+
|
|
38
52
|
**场景**:Issue #42 报告 *"登录接口在邮箱包含加号时返回 500"*。以下是完整的修复流程 —— AI 执行主要工作,你掌控方向:
|
|
39
53
|
|
|
40
54
|
```bash
|
|
@@ -396,7 +410,7 @@ import-issue #42 从 GitHub Issue 导入任务
|
|
|
396
410
|
"project": "my-project",
|
|
397
411
|
"org": "my-org",
|
|
398
412
|
"language": "en",
|
|
399
|
-
"templateVersion": "v0.5.
|
|
413
|
+
"templateVersion": "v0.5.3",
|
|
400
414
|
"files": {
|
|
401
415
|
"managed": [
|
|
402
416
|
".agents/workspace/README.md",
|
package/lib/defaults.json
CHANGED
package/lib/init.js
CHANGED
|
@@ -92,14 +92,22 @@ async function cmdInit() {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
let language = await prompt('Language (en / zh)', 'zh');
|
|
95
|
-
closePrompt();
|
|
96
95
|
if (language === 'zh') language = 'zh-CN';
|
|
97
96
|
if (language !== 'en' && language !== 'zh-CN') {
|
|
97
|
+
closePrompt();
|
|
98
98
|
err(`Language must be 'en' or 'zh'. Got: ${language}`);
|
|
99
99
|
process.exitCode = 1;
|
|
100
100
|
return;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
const platformType = (await prompt('Platform type', 'github')).trim() || 'github';
|
|
104
|
+
closePrompt();
|
|
105
|
+
if (!/^[a-z0-9][a-z0-9-]*$/.test(platformType)) {
|
|
106
|
+
err(`Platform type must match /^[a-z0-9][a-z0-9-]*$/. Got: ${platformType}`);
|
|
107
|
+
process.exitCode = 1;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
103
111
|
const project = projectName;
|
|
104
112
|
const replacements = { project, org: orgName };
|
|
105
113
|
|
|
@@ -118,9 +126,9 @@ async function cmdInit() {
|
|
|
118
126
|
geminiSrc = 'update-agent-infra.zh-CN.toml';
|
|
119
127
|
opencodeSrc = 'update-agent-infra.zh-CN.md';
|
|
120
128
|
} else {
|
|
121
|
-
claudeSrc = 'update-agent-infra.md';
|
|
122
|
-
geminiSrc = 'update-agent-infra.toml';
|
|
123
|
-
opencodeSrc = 'update-agent-infra.md';
|
|
129
|
+
claudeSrc = 'update-agent-infra.en.md';
|
|
130
|
+
geminiSrc = 'update-agent-infra.en.toml';
|
|
131
|
+
opencodeSrc = 'update-agent-infra.en.md';
|
|
124
132
|
}
|
|
125
133
|
|
|
126
134
|
// install skill
|
|
@@ -128,7 +136,8 @@ async function cmdInit() {
|
|
|
128
136
|
path.join(templateDir, '.agents', 'skills', 'update-agent-infra'),
|
|
129
137
|
path.join('.agents', 'skills', 'update-agent-infra'),
|
|
130
138
|
replacements,
|
|
131
|
-
language
|
|
139
|
+
language,
|
|
140
|
+
platformType
|
|
132
141
|
);
|
|
133
142
|
ok('Installed .agents/skills/update-agent-infra/');
|
|
134
143
|
|
|
@@ -161,6 +170,7 @@ async function cmdInit() {
|
|
|
161
170
|
project: projectName,
|
|
162
171
|
org: orgName,
|
|
163
172
|
language,
|
|
173
|
+
platform: { type: platformType },
|
|
164
174
|
templateVersion: VERSION,
|
|
165
175
|
sandbox: structuredClone(defaults.sandbox),
|
|
166
176
|
labels: structuredClone(defaults.labels),
|
package/lib/merge.js
CHANGED
|
@@ -404,15 +404,22 @@ function removeManifestFiles(rootDir) {
|
|
|
404
404
|
}
|
|
405
405
|
|
|
406
406
|
function formatTimestamp(date) {
|
|
407
|
+
const pad = (value) => String(value).padStart(2, '0');
|
|
408
|
+
const offsetMinutes = -date.getTimezoneOffset();
|
|
409
|
+
const sign = offsetMinutes >= 0 ? '+' : '-';
|
|
410
|
+
const absoluteOffsetMinutes = Math.abs(offsetMinutes);
|
|
411
|
+
const offsetHours = Math.floor(absoluteOffsetMinutes / 60);
|
|
412
|
+
const offsetRemainderMinutes = absoluteOffsetMinutes % 60;
|
|
413
|
+
|
|
407
414
|
return [
|
|
408
415
|
date.getFullYear(),
|
|
409
|
-
|
|
410
|
-
|
|
416
|
+
pad(date.getMonth() + 1),
|
|
417
|
+
pad(date.getDate())
|
|
411
418
|
].join('-') + ' ' + [
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
].join(':')
|
|
419
|
+
pad(date.getHours()),
|
|
420
|
+
pad(date.getMinutes()),
|
|
421
|
+
pad(date.getSeconds())
|
|
422
|
+
].join(':') + `${sign}${pad(offsetHours)}:${pad(offsetRemainderMinutes)}`;
|
|
416
423
|
}
|
|
417
424
|
|
|
418
425
|
function formatBackupTimestamp(date) {
|
|
@@ -485,7 +492,15 @@ function getTaskTimestamp(taskDir) {
|
|
|
485
492
|
}
|
|
486
493
|
|
|
487
494
|
function compareTimestamps(left, right) {
|
|
488
|
-
|
|
495
|
+
const normalizeTimestamp = (timestamp) => (timestamp.includes('T') ? timestamp : timestamp.replace(' ', 'T'));
|
|
496
|
+
const leftMs = Date.parse(normalizeTimestamp(left.value));
|
|
497
|
+
const rightMs = Date.parse(normalizeTimestamp(right.value));
|
|
498
|
+
|
|
499
|
+
if (Number.isNaN(leftMs) || Number.isNaN(rightMs)) {
|
|
500
|
+
return left.value.localeCompare(right.value);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
return leftMs - rightMs;
|
|
489
504
|
}
|
|
490
505
|
|
|
491
506
|
function scanWorkspaceSection(rootDir, sectionName) {
|
package/lib/render.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
|
+
// Add a new identifier here only after shipping matching .{platform}. template variants.
|
|
5
|
+
const KNOWN_PLATFORMS = new Set(['github']);
|
|
6
|
+
const KNOWN_LANGUAGES = new Set(['en', 'zh-CN']);
|
|
7
|
+
|
|
4
8
|
function renderFile(src, dst, replacements) {
|
|
5
9
|
if (!fs.existsSync(src)) {
|
|
6
10
|
throw new Error(`Template file not found: ${src}`);
|
|
@@ -50,37 +54,95 @@ function containsPlaceholders(src) {
|
|
|
50
54
|
return content.includes('{{project}}') || content.includes('{{org}}');
|
|
51
55
|
}
|
|
52
56
|
|
|
53
|
-
function
|
|
54
|
-
|
|
57
|
+
function variantExt(relativePath) {
|
|
58
|
+
return path.extname(relativePath);
|
|
59
|
+
}
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
function variantBase(relativePath) {
|
|
62
|
+
const ext = variantExt(relativePath);
|
|
63
|
+
return relativePath.slice(0, -ext.length);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function withVariant(relativePath, variant) {
|
|
67
|
+
const ext = variantExt(relativePath);
|
|
68
|
+
const base = variantBase(relativePath);
|
|
69
|
+
return `${base}.${variant}${ext}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function stripVariant(relativePath, variant) {
|
|
73
|
+
return relativePath.replace(new RegExp(`\\.${variant.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\.`), '.');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function isPlatformVariant(relativePath, platform) {
|
|
77
|
+
const platforms = new Set([...KNOWN_PLATFORMS, platform]);
|
|
78
|
+
for (const candidate of platforms) {
|
|
79
|
+
if (relativePath.includes(`.${candidate}.`)) {
|
|
80
|
+
return true;
|
|
60
81
|
}
|
|
61
|
-
selected.set(relativePath, src);
|
|
62
82
|
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function isLangVariant(relativePath) {
|
|
87
|
+
for (const lang of KNOWN_LANGUAGES) {
|
|
88
|
+
if (relativePath.includes(`.${lang}.`)) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function langSelect(relativePaths, language) {
|
|
96
|
+
const selected = new Map();
|
|
63
97
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
98
|
+
for (const relativePath of relativePaths) {
|
|
99
|
+
if (relativePath.includes(`.${language}.`)) {
|
|
100
|
+
selected.set(stripVariant(relativePath, language), relativePath);
|
|
101
|
+
} else if (!isLangVariant(relativePath)) {
|
|
102
|
+
if (!selected.has(relativePath)) {
|
|
103
|
+
selected.set(relativePath, relativePath);
|
|
69
104
|
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return selected;
|
|
109
|
+
}
|
|
70
110
|
|
|
71
|
-
|
|
111
|
+
function platformSelect(entries, platform) {
|
|
112
|
+
const selected = new Map();
|
|
113
|
+
|
|
114
|
+
for (const [relativePath, src] of entries) {
|
|
115
|
+
if (!relativePath.includes(`.${platform}.`)) {
|
|
116
|
+
continue;
|
|
72
117
|
}
|
|
118
|
+
selected.set(stripVariant(relativePath, platform), src);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
for (const [relativePath, src] of entries) {
|
|
122
|
+
if (selected.has(relativePath)) {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (isPlatformVariant(relativePath, platform)) {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
selected.set(relativePath, src);
|
|
73
129
|
}
|
|
74
130
|
|
|
75
131
|
return selected;
|
|
76
132
|
}
|
|
77
133
|
|
|
78
|
-
function
|
|
134
|
+
function selectLocalizedFiles(srcDir, language, platform = 'github') {
|
|
135
|
+
const relativePaths = walkFiles(srcDir).map((src) => path.relative(srcDir, src));
|
|
136
|
+
return platformSelect(langSelect(relativePaths, language), platform);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function copySkillDir(srcDir, dstDir, replacements, language, platform = 'github') {
|
|
79
140
|
if (!fs.existsSync(srcDir)) {
|
|
80
141
|
throw new Error(`Template directory not found: ${srcDir}`);
|
|
81
142
|
}
|
|
82
143
|
|
|
83
|
-
for (const [relativePath,
|
|
144
|
+
for (const [relativePath, selectedRelativePath] of selectLocalizedFiles(srcDir, language, platform)) {
|
|
145
|
+
const src = path.join(srcDir, selectedRelativePath);
|
|
84
146
|
const dst = path.join(dstDir, relativePath);
|
|
85
147
|
if (containsPlaceholders(src)) {
|
|
86
148
|
renderFile(src, dst, replacements);
|
|
@@ -4,12 +4,28 @@ import { runInteractive, runSafe } from '../shell.js';
|
|
|
4
4
|
import { resolveTaskBranch } from '../task-resolver.js';
|
|
5
5
|
|
|
6
6
|
const USAGE = `Usage: ai sandbox exec <branch> [cmd...]`;
|
|
7
|
-
export const
|
|
8
|
-
|
|
7
|
+
export const TMUX_ENTRY_SCRIPT = `
|
|
8
|
+
SESSION=work
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
if ! command -v tmux >/dev/null 2>&1; then
|
|
11
|
+
exec bash
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
if ! tmux has-session -t "$SESSION" 2>/dev/null; then
|
|
15
|
+
exec tmux new-session -s "$SESSION"
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
tmux list-sessions -F '#{session_name} #{session_attached}' 2>/dev/null | \\
|
|
19
|
+
while read -r name attached; do
|
|
20
|
+
[ "$name" = "$SESSION" ] && continue
|
|
21
|
+
case "$name" in
|
|
22
|
+
''|*[!0-9]*) continue ;;
|
|
23
|
+
esac
|
|
24
|
+
[ "$attached" = "0" ] && tmux kill-session -t "$name" 2>/dev/null || true
|
|
25
|
+
done
|
|
26
|
+
|
|
27
|
+
exec tmux new-session -t "$SESSION"
|
|
28
|
+
`.trim();
|
|
13
29
|
|
|
14
30
|
// Terminal-detection variables that interactive TUIs (e.g. claude-code)
|
|
15
31
|
// inspect to enable progressive enhancements such as the kitty keyboard
|
|
@@ -56,8 +72,7 @@ export function enter(args) {
|
|
|
56
72
|
|
|
57
73
|
const envFlags = terminalEnvFlags();
|
|
58
74
|
if (cmd.length === 0) {
|
|
59
|
-
|
|
60
|
-
return runInteractive('docker', ['exec', '-it', ...envFlags, container, 'bash']);
|
|
75
|
+
return runInteractive('docker', ['exec', '-it', ...envFlags, container, 'bash', '-c', TMUX_ENTRY_SCRIPT]);
|
|
61
76
|
}
|
|
62
77
|
|
|
63
78
|
return runInteractive('docker', ['exec', '-it', ...envFlags, container, ...cmd]);
|
|
@@ -87,7 +87,7 @@ async function rmOne(config, tools, branch) {
|
|
|
87
87
|
|
|
88
88
|
const shouldDeleteBranch = await p.confirm({
|
|
89
89
|
message: `Also delete local branch '${effectiveBranch}'?`,
|
|
90
|
-
initialValue:
|
|
90
|
+
initialValue: true
|
|
91
91
|
});
|
|
92
92
|
|
|
93
93
|
if (!p.isCancel(shouldDeleteBranch) && shouldDeleteBranch) {
|
|
@@ -11,8 +11,10 @@ RUN (groupadd -g ${HOST_GID} devuser || true) && \
|
|
|
11
11
|
useradd -u ${HOST_UID} -g ${HOST_GID} -m -s /bin/bash devuser
|
|
12
12
|
|
|
13
13
|
RUN apt-get update && apt-get install -y \
|
|
14
|
-
curl wget git vim
|
|
14
|
+
curl wget git vim file \
|
|
15
15
|
build-essential ca-certificates gnupg lsb-release \
|
|
16
|
+
libevent-core-2.1-7 libncursesw6 libtinfo6 \
|
|
17
|
+
pkg-config bison libevent-dev libncurses-dev \
|
|
16
18
|
locales \
|
|
17
19
|
&& locale-gen en_US.UTF-8 \
|
|
18
20
|
&& (curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
|
|
@@ -20,8 +22,32 @@ RUN apt-get update && apt-get install -y \
|
|
|
20
22
|
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
|
|
21
23
|
> /etc/apt/sources.list.d/github-cli.list \
|
|
22
24
|
&& apt-get update && apt-get install -y gh \
|
|
25
|
+
&& TMUX_VERSION=3.6a \
|
|
26
|
+
&& wget -qO /tmp/tmux.tar.gz \
|
|
27
|
+
"https://github.com/tmux/tmux/releases/download/${TMUX_VERSION}/tmux-${TMUX_VERSION}.tar.gz" \
|
|
28
|
+
&& tar xzf /tmp/tmux.tar.gz -C /tmp \
|
|
29
|
+
&& cd /tmp/tmux-${TMUX_VERSION} \
|
|
30
|
+
&& ./configure --prefix=/usr/local \
|
|
31
|
+
&& make -j"$(nproc)" \
|
|
32
|
+
&& make install \
|
|
33
|
+
&& cd / \
|
|
34
|
+
&& rm -rf /tmp/tmux.tar.gz /tmp/tmux-${TMUX_VERSION} \
|
|
35
|
+
&& apt-get purge -y pkg-config bison libevent-dev libncurses-dev \
|
|
36
|
+
&& apt-get autoremove -y \
|
|
37
|
+
&& apt-get clean \
|
|
23
38
|
&& rm -rf /var/lib/apt/lists/*
|
|
24
39
|
|
|
40
|
+
# Enable extended keys in CSI u format so Shift+Enter and other modified
|
|
41
|
+
# keys are forwarded through tmux. Preserve terminal-detection variables
|
|
42
|
+
# injected at `docker exec` time when new tmux sessions are created.
|
|
43
|
+
RUN printf '%s\n' \
|
|
44
|
+
'set -g extended-keys always' \
|
|
45
|
+
'set -g extended-keys-format csi-u' \
|
|
46
|
+
"set -as terminal-features 'xterm*:extkeys'" \
|
|
47
|
+
"set -ga update-environment 'TERM_PROGRAM TERM_PROGRAM_VERSION LC_TERMINAL LC_TERMINAL_VERSION'" \
|
|
48
|
+
'set -g mouse on' \
|
|
49
|
+
> /etc/tmux.conf
|
|
50
|
+
|
|
25
51
|
ENV LANG=en_US.UTF-8
|
|
26
52
|
ENV LC_ALL=en_US.UTF-8
|
|
27
53
|
ENV TERM=xterm-256color
|
package/lib/update.js
CHANGED
|
@@ -81,6 +81,7 @@ async function cmdUpdate() {
|
|
|
81
81
|
// read project config
|
|
82
82
|
const config = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'));
|
|
83
83
|
const { project, org, language } = config;
|
|
84
|
+
const platformType = config.platform?.type || defaults.platform.type;
|
|
84
85
|
const replacements = { project, org };
|
|
85
86
|
|
|
86
87
|
info(`Updating seed files for: ${project}`);
|
|
@@ -93,9 +94,9 @@ async function cmdUpdate() {
|
|
|
93
94
|
geminiSrc = 'update-agent-infra.zh-CN.toml';
|
|
94
95
|
opencodeSrc = 'update-agent-infra.zh-CN.md';
|
|
95
96
|
} else {
|
|
96
|
-
claudeSrc = 'update-agent-infra.md';
|
|
97
|
-
geminiSrc = 'update-agent-infra.toml';
|
|
98
|
-
opencodeSrc = 'update-agent-infra.md';
|
|
97
|
+
claudeSrc = 'update-agent-infra.en.md';
|
|
98
|
+
geminiSrc = 'update-agent-infra.en.toml';
|
|
99
|
+
opencodeSrc = 'update-agent-infra.en.md';
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
// update skill
|
|
@@ -103,7 +104,8 @@ async function cmdUpdate() {
|
|
|
103
104
|
path.join(templateDir, '.agents', 'skills', 'update-agent-infra'),
|
|
104
105
|
path.join('.agents', 'skills', 'update-agent-infra'),
|
|
105
106
|
replacements,
|
|
106
|
-
language
|
|
107
|
+
language,
|
|
108
|
+
platformType
|
|
107
109
|
);
|
|
108
110
|
ok('Updated .agents/skills/update-agent-infra/');
|
|
109
111
|
try {
|
|
@@ -139,10 +141,16 @@ async function cmdUpdate() {
|
|
|
139
141
|
// sync file registry
|
|
140
142
|
const { added, changed } = syncFileRegistry(config);
|
|
141
143
|
const hasNewEntries = added.managed.length > 0 || added.merged.length > 0;
|
|
144
|
+
const platformAdded = !config.platform;
|
|
142
145
|
const sandboxAdded = !config.sandbox;
|
|
143
146
|
const labelsAdded = !config.labels;
|
|
144
147
|
let configChanged = changed;
|
|
145
148
|
|
|
149
|
+
if (platformAdded) {
|
|
150
|
+
config.platform = structuredClone(defaults.platform);
|
|
151
|
+
configChanged = true;
|
|
152
|
+
}
|
|
153
|
+
|
|
146
154
|
if (sandboxAdded) {
|
|
147
155
|
config.sandbox = structuredClone(defaults.sandbox);
|
|
148
156
|
configChanged = true;
|
|
@@ -163,7 +171,10 @@ async function cmdUpdate() {
|
|
|
163
171
|
for (const entry of added.merged) {
|
|
164
172
|
ok(` merged: ${entry}`);
|
|
165
173
|
}
|
|
166
|
-
} else if (sandboxAdded || labelsAdded) {
|
|
174
|
+
} else if (platformAdded || sandboxAdded || labelsAdded) {
|
|
175
|
+
if (platformAdded) {
|
|
176
|
+
info(`Default platform config added to ${CONFIG_PATH}.`);
|
|
177
|
+
}
|
|
167
178
|
if (sandboxAdded) {
|
|
168
179
|
info(`Default sandbox config added to ${CONFIG_PATH}.`);
|
|
169
180
|
}
|
|
@@ -179,6 +190,9 @@ async function cmdUpdate() {
|
|
|
179
190
|
if (hasNewEntries && labelsAdded) {
|
|
180
191
|
info(`Default labels.in config added to ${CONFIG_PATH}.`);
|
|
181
192
|
}
|
|
193
|
+
if (hasNewEntries && platformAdded) {
|
|
194
|
+
info(`Default platform config added to ${CONFIG_PATH}.`);
|
|
195
|
+
}
|
|
182
196
|
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
183
197
|
ok(`Updated ${CONFIG_PATH}`);
|
|
184
198
|
}
|
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.3",
|
|
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",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "node scripts/build-inline.js",
|
|
49
|
+
"demo:regen": "vhs assets/demo-init.tape",
|
|
49
50
|
"prepare": "git config core.hooksPath .github/hooks || true",
|
|
50
51
|
"test": "node scripts/build-inline.js --check && node --test tests/cli/*.test.js tests/templates/*.test.js tests/core/*.test.js",
|
|
51
52
|
"prepublishOnly": "node scripts/build-inline.js --check && node --test tests/cli/*.test.js tests/templates/*.test.js tests/core/*.test.js"
|
|
@@ -100,15 +100,25 @@ Each AI tool has different strengths. Use them accordingly:
|
|
|
100
100
|
|
|
101
101
|
## Label Conventions
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
This project uses the following collaboration label prefixes, each with a defined scope:
|
|
104
104
|
|
|
105
105
|
| Label prefix | Issue | PR | Notes |
|
|
106
106
|
|---|---|---|---|
|
|
107
|
-
| `type:` | — | Yes | Issues use the native
|
|
107
|
+
| `type:` | — | Yes | Issues use the platform's native type/category field when available; PRs use `type:` labels for changelog generation and categorization |
|
|
108
108
|
| `status:` | Yes | — | PRs already have their own state flow (Open / Draft / Merged / Closed); Issues use `status:` labels for project tracking states |
|
|
109
109
|
| `in:` | Yes | Yes | Both Issues and PRs can be filtered by module |
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
The default GitHub setup initializes these labels with the `/init-labels` command.
|
|
112
|
+
|
|
113
|
+
## Private Platform Extensions
|
|
114
|
+
|
|
115
|
+
To adapt agent-infra to a private code-hosting platform:
|
|
116
|
+
|
|
117
|
+
1. Set `.agents/.airc.json` `platform.type` to a stable identifier such as `my-platform`.
|
|
118
|
+
2. Copy the generated rule files in `.agents/rules/` and adapt them to your platform's CLI or API while keeping the runtime filenames unchanged.
|
|
119
|
+
3. Add the customized rule files to `.agents/.airc.json` `files.ejected` so future `agent-infra update` runs do not overwrite them.
|
|
120
|
+
4. If you maintain a fork of the template source, add matching `.{platform}.` template variants before adding that platform identifier to the sync logic.
|
|
121
|
+
5. Validate the customized workflow on a test task before rolling it out broadly.
|
|
112
122
|
|
|
113
123
|
## Skill Authoring Conventions
|
|
114
124
|
|
|
@@ -100,15 +100,25 @@
|
|
|
100
100
|
|
|
101
101
|
## Label 规范
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
本项目的协作 labels 按以下前缀分类,各前缀有明确的适用范围:
|
|
104
104
|
|
|
105
105
|
| Label 前缀 | Issue | PR | 说明 |
|
|
106
106
|
|---|---|---|---|
|
|
107
|
-
| `type:` | — | Yes | Issue
|
|
107
|
+
| `type:` | — | Yes | Issue 优先使用平台原生的类型/分类字段;PR 无原生类型字段时,通过 `type:` label 驱动 changelog 和分类 |
|
|
108
108
|
| `status:` | Yes | — | PR 有自身状态流转(Open / Draft / Merged / Closed);Issue 使用 `status:` label 标记等待反馈、已确认等项目管理状态 |
|
|
109
109
|
| `in:` | Yes | Yes | Issue 和 PR 均可按模块筛选 |
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
默认 GitHub 配置下,可使用 `/init-labels` 命令一次性创建标准 labels。
|
|
112
|
+
|
|
113
|
+
## 私有平台扩展
|
|
114
|
+
|
|
115
|
+
如需将 agent-infra 接入私有代码托管平台:
|
|
116
|
+
|
|
117
|
+
1. 在 `.agents/.airc.json` 中把 `platform.type` 设为稳定标识,例如 `my-platform`。
|
|
118
|
+
2. 以 `.agents/rules/` 下已生成的规则文件为起点,改写为你的平台 CLI 或 API 调用,同时保持运行时文件名不变。
|
|
119
|
+
3. 将这些自定义规则文件加入 `.agents/.airc.json` 的 `files.ejected`,避免后续执行 `agent-infra update` 时被覆盖。
|
|
120
|
+
4. 如果你维护的是模板源码分支或私有 fork,需要先补齐对应的 `.{platform}.` 模板变体,再把该平台标识加入模板同步逻辑。
|
|
121
|
+
5. 在正式推广前,先用一个测试任务完整验证工作流和 gate 校验。
|
|
112
122
|
|
|
113
123
|
## Skill 编写规范
|
|
114
124
|
|