@fitlab-ai/agent-infra 0.5.7 → 0.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/lib/defaults.json +4 -2
  4. package/lib/init.js +18 -1
  5. package/lib/sandbox/engine.js +19 -0
  6. package/lib/sandbox/shell.js +36 -2
  7. package/lib/update.js +14 -3
  8. package/package.json +4 -4
  9. package/templates/.agents/QUICKSTART.en.md +2 -2
  10. package/templates/.agents/QUICKSTART.zh-CN.md +2 -2
  11. package/templates/.agents/README.en.md +1 -1
  12. package/templates/.agents/README.zh-CN.md +1 -1
  13. package/templates/.agents/rules/issue-pr-commands.github.en.md +60 -0
  14. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +60 -0
  15. package/templates/.agents/rules/issue-sync.en.md +14 -0
  16. package/templates/.agents/rules/issue-sync.github.en.md +14 -0
  17. package/templates/.agents/rules/issue-sync.github.zh-CN.md +14 -0
  18. package/templates/.agents/rules/issue-sync.zh-CN.md +14 -0
  19. package/templates/.agents/rules/label-milestone-setup.github.en.md +10 -0
  20. package/templates/.agents/rules/label-milestone-setup.github.zh-CN.md +10 -0
  21. package/templates/.agents/rules/release-commands.github.en.md +16 -0
  22. package/templates/.agents/rules/release-commands.github.zh-CN.md +16 -0
  23. package/templates/.agents/scripts/platform-adapters/find-existing-task.github.js +272 -0
  24. package/templates/.agents/scripts/platform-adapters/find-existing-task.js +5 -0
  25. package/templates/.agents/scripts/platform-adapters/platform-sync.github.js +88 -8
  26. package/templates/.agents/scripts/platform-adapters/platform-sync.js +7 -0
  27. package/templates/.agents/skills/analyze-task/SKILL.en.md +3 -3
  28. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +3 -3
  29. package/templates/.agents/skills/analyze-task/config/verify.json +3 -1
  30. package/templates/.agents/skills/block-task/config/verify.json +2 -1
  31. package/templates/.agents/skills/cancel-task/SKILL.en.md +2 -2
  32. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +2 -2
  33. package/templates/.agents/skills/cancel-task/config/verify.json +2 -1
  34. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  35. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  36. package/templates/.agents/skills/commit/SKILL.en.md +1 -1
  37. package/templates/.agents/skills/commit/SKILL.zh-CN.md +1 -1
  38. package/templates/.agents/skills/commit/config/verify.json +2 -1
  39. package/templates/.agents/skills/complete-task/SKILL.en.md +1 -1
  40. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +1 -1
  41. package/templates/.agents/skills/complete-task/config/verify.json +2 -1
  42. package/templates/.agents/skills/create-issue/SKILL.en.md +8 -8
  43. package/templates/.agents/skills/create-issue/SKILL.zh-CN.md +8 -8
  44. package/templates/.agents/skills/create-issue/config/verify.json +2 -1
  45. package/templates/.agents/skills/create-issue/reference/label-and-type.en.md +3 -3
  46. package/templates/.agents/skills/create-issue/reference/label-and-type.zh-CN.md +3 -3
  47. package/templates/.agents/skills/create-issue/reference/template-matching.en.md +6 -34
  48. package/templates/.agents/skills/create-issue/reference/template-matching.zh-CN.md +8 -36
  49. package/templates/.agents/skills/create-pr/SKILL.en.md +2 -2
  50. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +2 -2
  51. package/templates/.agents/skills/create-pr/config/verify.json +2 -1
  52. package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +7 -17
  53. package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +27 -37
  54. package/templates/.agents/skills/create-release-note/SKILL.en.md +9 -9
  55. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +9 -9
  56. package/templates/.agents/skills/create-task/SKILL.en.md +3 -3
  57. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +3 -3
  58. package/templates/.agents/skills/implement-task/SKILL.en.md +1 -1
  59. package/templates/.agents/skills/implement-task/SKILL.zh-CN.md +1 -1
  60. package/templates/.agents/skills/implement-task/config/verify.json +3 -1
  61. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  62. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  63. package/templates/.agents/skills/import-issue/SKILL.en.md +39 -9
  64. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +39 -9
  65. package/templates/.agents/skills/init-labels/SKILL.en.md +9 -9
  66. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +9 -9
  67. package/templates/.agents/skills/init-milestones/SKILL.en.md +7 -7
  68. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +7 -7
  69. package/templates/.agents/skills/plan-task/SKILL.en.md +1 -1
  70. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +1 -1
  71. package/templates/.agents/skills/plan-task/config/verify.json +3 -1
  72. package/templates/.agents/skills/refine-task/SKILL.en.md +1 -1
  73. package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +1 -1
  74. package/templates/.agents/skills/refine-task/config/verify.json +3 -1
  75. package/templates/.agents/skills/restore-task/SKILL.en.md +13 -64
  76. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +13 -64
  77. package/templates/.agents/skills/review-task/SKILL.en.md +1 -1
  78. package/templates/.agents/skills/review-task/SKILL.zh-CN.md +1 -1
  79. package/templates/.agents/skills/review-task/config/verify.json +3 -1
  80. package/templates/.agents/skills/update-agent-infra/SKILL.en.md +2 -0
  81. package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +2 -0
  82. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +56 -5
  83. package/templates/.claude/commands/create-issue.en.md +1 -1
  84. package/templates/.claude/commands/create-issue.zh-CN.md +1 -1
  85. package/templates/.claude/commands/import-issue.en.md +1 -1
  86. package/templates/.claude/commands/import-issue.zh-CN.md +1 -1
  87. package/templates/.claude/commands/init-labels.en.md +1 -1
  88. package/templates/.claude/commands/init-labels.zh-CN.md +1 -1
  89. package/templates/.claude/commands/init-milestones.en.md +1 -1
  90. package/templates/.claude/commands/init-milestones.zh-CN.md +1 -1
  91. package/templates/.claude/commands/restore-task.en.md +1 -1
  92. package/templates/.claude/commands/restore-task.zh-CN.md +1 -1
  93. package/templates/.claude/hooks/check-version-format.sh +1 -1
  94. package/templates/.gemini/commands/_project_/create-issue.en.toml +1 -1
  95. package/templates/.gemini/commands/_project_/create-issue.zh-CN.toml +1 -1
  96. package/templates/.gemini/commands/_project_/import-issue.en.toml +1 -1
  97. package/templates/.gemini/commands/_project_/import-issue.zh-CN.toml +1 -1
  98. package/templates/.gemini/commands/_project_/init-labels.en.toml +2 -2
  99. package/templates/.gemini/commands/_project_/init-labels.zh-CN.toml +2 -2
  100. package/templates/.gemini/commands/_project_/init-milestones.en.toml +2 -2
  101. package/templates/.gemini/commands/_project_/init-milestones.zh-CN.toml +2 -2
  102. package/templates/.gemini/commands/_project_/restore-task.en.toml +1 -1
  103. package/templates/.gemini/commands/_project_/restore-task.zh-CN.toml +1 -1
  104. package/templates/{.github/hooks → .git-hooks}/check-version-format.sh +2 -2
  105. package/templates/.github/workflows/pr-label.yml +1 -1
  106. package/templates/.opencode/commands/create-issue.en.md +1 -1
  107. package/templates/.opencode/commands/create-issue.zh-CN.md +1 -1
  108. package/templates/.opencode/commands/import-issue.en.md +1 -1
  109. package/templates/.opencode/commands/import-issue.zh-CN.md +1 -1
  110. package/templates/.opencode/commands/init-labels.en.md +1 -1
  111. package/templates/.opencode/commands/init-labels.zh-CN.md +1 -1
  112. package/templates/.opencode/commands/init-milestones.en.md +1 -1
  113. package/templates/.opencode/commands/init-milestones.zh-CN.md +1 -1
  114. package/templates/.opencode/commands/restore-task.en.md +1 -1
  115. package/templates/.opencode/commands/restore-task.zh-CN.md +1 -1
  116. /package/templates/{.github/hooks → .git-hooks}/pre-commit +0 -0
@@ -9,7 +9,7 @@ description: "从平台 Issue 评论还原本地任务文件"
9
9
 
10
10
  ## 行为边界 / 关键规则
11
11
 
12
- - 只从带 `<!-- sync-issue:{task-id}:... -->` 标记的评论恢复文件
12
+ - 只从匹配 `.agents/rules/issue-sync.md` 标记注册表的评论恢复文件
13
13
  - 默认恢复到 `.agents/workspace/active/{task-id}/`
14
14
  - 如果目标目录已存在,立即停止并提示用户先处理目录冲突
15
15
  - 执行本技能后,你**必须**立即更新恢复出的 `task.md`
@@ -31,16 +31,11 @@ description: "从平台 Issue 评论还原本地任务文件"
31
31
 
32
32
  ### 3. 确定 task-id 与待恢复文件
33
33
 
34
- 从评论中筛选隐藏标记:
35
-
36
- ```html
37
- <!-- sync-issue:{task-id}:{file-stem} -->
38
- <!-- sync-issue:{task-id}:{file-stem}:{part}/{total} -->
39
- ```
34
+ 按 `.agents/rules/issue-sync.md` 中定义的 task、artifact 和分片 artifact 标记筛选评论。
40
35
 
41
36
  处理规则:
42
37
  - 用户提供了 `{task-id}` 时,仅匹配该任务
43
- - 未提供时,优先从 `<!-- sync-issue:{task-id}:task -->` 评论推断
38
+ - 未提供时,优先从 task 评论标记推断
44
39
  - 若找不到唯一 task-id,立即停止并告知用户
45
40
  - 忽略 `summary` 标记评论;它是 complete-task 的聚合产物,不对应本地任务文件
46
41
  - 将 `{file-stem}` 映射回文件名:
@@ -58,7 +53,7 @@ description: "从平台 Issue 评论还原本地任务文件"
58
53
  对每个文件执行:
59
54
  - 收集单条评论或分片评论
60
55
  - 对 `task.md` 评论按 issue-sync.md 中的 `<details>` frontmatter 格式反向拆解,提取 frontmatter 后再与正文拼合
61
- - 如存在 `{part}/{total}`,按 part 升序排序并校验分片完整
56
+ - 如分片标记中存在 parttotal 序号,按 part 升序排序并校验分片完整
62
57
  - 从评论正文中提取文件内容,去掉隐藏标记、标题和页脚
63
58
  - 拼接得到最终文件内容
64
59
 
@@ -88,66 +83,20 @@ date "+%Y-%m-%d %H:%M:%S%:z"
88
83
  - `status`:`active`
89
84
  - `assigned_to`:{当前 AI 代理}
90
85
  - `updated_at`:{当前时间}
91
- - 保留原 `current_step`
92
- - 在 `## 活动日志` 追加:
93
- ```
94
- - {YYYY-MM-DD HH:mm:ss±HH:MM} — **Restore Task** by {agent} — Restored task from Issue #{issue-number}
95
- ```
96
-
97
- ### 7. 完成校验
98
-
99
- 运行完成校验:
100
-
101
- ```bash
102
- node .agents/scripts/validate-artifact.js gate restore-task .agents/workspace/active/{task-id} --format text
103
- ```
104
-
105
- 处理结果:
106
- - 退出码 0(全部通过)-> 继续到「告知用户」步骤
107
- - 退出码 1(校验失败)-> 根据输出修复问题后重新运行校验
108
- - 退出码 2(网络中断)-> 停止执行并告知用户需要人工介入
109
86
 
110
- 将校验输出保留在回复中作为当次验证输出。没有当次校验输出,不得声明完成。
87
+ 追加 Activity Log,说明任务已从平台 Issue 还原。
111
88
 
112
- ### 8. 告知用户
89
+ ### 7. 告知用户
113
90
 
114
- > 仅在校验通过后执行本步骤。
115
-
116
- > **重要**:以下「下一步」中列出的所有 TUI 命令格式必须完整输出,不要只展示当前 AI 代理对应的格式。如果 `.agents/.airc.json` 中配置了自定义 TUI(`customTUIs`),读取每个工具的 `name` 和 `invoke`,按同样格式补充对应命令行(`${skillName}` 替换为技能名,`${projectName}` 替换为项目名)。
117
-
118
- 输出格式:
119
-
120
- ```text
121
- 任务 {task-id} 已从 Issue #{issue-number} 还原。
122
-
123
- 摘要:
124
- - 恢复文件:{数量}
125
- - 任务目录:.agents/workspace/active/{task-id}/
126
- - 当前步骤:{current_step}
127
-
128
- 下一步 - 查看任务状态:
129
- - Claude Code / OpenCode:/check-task {task-id}
130
- - Gemini CLI:/{{project}}:check-task {task-id}
131
- - Codex CLI:$check-task {task-id}
132
- ```
91
+ 报告已恢复的 task id、恢复文件数量和 active task 目录。
133
92
 
134
93
  ## 完成检查清单
135
94
 
136
- - [ ] 已获取并解析 Issue 评论
137
- - [ ] 已还原 `task.md` 和所有可用产物文件
138
- - [ ] 已更新恢复后的 task.md
139
- - [ ] 已运行并通过完成校验
140
- - [ ] 已向用户展示所有 TUI 格式的下一步命令(含自定义 TUI)
141
-
142
- ## 停止
143
-
144
- 完成检查清单后立即停止。不要自动继续执行工作流。
95
+ - [ ] 已从平台获取 Issue 评论
96
+ - [ ] 已恢复本地任务文件
97
+ - [ ] 已更新恢复出的任务元数据
98
+ - [ ] 已报告恢复目录
145
99
 
146
- ## 错误处理
100
+ ### 8. 停止
147
101
 
148
- - Issue 不存在或无权访问
149
- - 平台 CLI 未认证
150
- - 找不到带 sync 标记的评论
151
- - 无法唯一确定 `task-id`
152
- - 目标目录已存在
153
- - 分片缺失或顺序不完整
102
+ 完成检查清单后立即停止。不要自动提交。
@@ -56,7 +56,7 @@ Update task.md and append:
56
56
  If task.md contains a valid `issue_number`, perform these sync actions (skip and continue on any failure):
57
57
  - Read `.agents/rules/issue-sync.md` before syncing, and complete upstream repository detection plus permission detection
58
58
  - Set `status: in-progress` by following issue-sync.md
59
- - Create or update the `<!-- sync-issue:{task-id}:task -->` comment (follow the task.md comment sync rule in issue-sync.md)
59
+ - Create or update the task comment marker defined in `.agents/rules/issue-sync.md` (follow the task.md comment sync rule in issue-sync.md)
60
60
  - Publish the `{review-artifact}` comment
61
61
 
62
62
  ### 7. Verification Gate
@@ -56,7 +56,7 @@ date "+%Y-%m-%d %H:%M:%S%:z"
56
56
  如果 task.md 中存在有效的 `issue_number`,执行以下同步操作(任一失败则跳过并继续):
57
57
  - 执行前先读取 `.agents/rules/issue-sync.md`,完成 upstream 仓库检测和权限检测
58
58
  - 按 issue-sync.md 设置 `status: in-progress`
59
- - 创建或更新 `<!-- sync-issue:{task-id}:task -->` 评论(按 issue-sync.md 的 task.md 评论同步规则)
59
+ - 创建或更新 `.agents/rules/issue-sync.md` 中定义的 task 评论标记(按 issue-sync.md 的 task.md 评论同步规则)
60
60
  - 发布 `{review-artifact}` 评论
61
61
 
62
62
  ### 7. 完成校验
@@ -36,7 +36,9 @@
36
36
  "verify_comment_content": true,
37
37
  "verify_task_comment_content": true,
38
38
  "verify_issue_type": true,
39
- "verify_milestone": true
39
+ "verify_milestone": true,
40
+ "expected_status_label_key": "inProgress",
41
+ "expected_comment_marker_key": "artifact"
40
42
  }
41
43
  }
42
44
  }
@@ -45,6 +45,8 @@ The script outputs JSON to stdout. Parse and record the report.
45
45
  list these in the report so users know which files were ignored because a
46
46
  built-in template or later external source won
47
47
  - `managed.written` / `managed.created`: updated / newly created managed files
48
+ - `managed.removed`: deleted managed files (including old paths removed during template migrations)
49
+ - `managed.skippedPlatform`: managed / merged entries skipped because they belong to a different platform
48
50
  - `merged.pending`: list of merged files for AI to process
49
51
  - Each item has `target` (project-relative path) and `template` (template-root-relative path)
50
52
  - `registryAdded`: newly added file registry entries
@@ -37,6 +37,8 @@ node .agents/skills/update-agent-infra/scripts/sync-templates.js
37
37
  - `templateRoot`:模板文件根目录绝对路径
38
38
  - `templateSources.conflicts`:外部模板源冲突列表;报告中必须显式展示,说明哪些文件因内置模板或后续外部源获胜而被忽略
39
39
  - `managed.written` / `managed.created`:已更新/新建的 managed 文件
40
+ - `managed.removed`:被删除的 managed 文件(包括模板迁移时移除的旧路径)
41
+ - `managed.skippedPlatform`:因归属其他平台而被跳过的 managed / merged 条目
40
42
  - `merged.pending`:需要 AI 处理的 merged 文件列表
41
43
  - 每项包含 `target`(项目中的目标路径)和 `template`(模板根目录下的相对路径)
42
44
  - `registryAdded`:新增的文件注册条目
@@ -57,29 +57,30 @@ const DEFAULTS = {
57
57
  ".claude/commands/",
58
58
  ".claude/hooks/",
59
59
  ".gemini/commands/",
60
- ".github/hooks/check-version-format.sh",
60
+ ".git-hooks/check-version-format.sh",
61
61
  ".github/scripts/",
62
62
  ".opencode/commands/"
63
63
  ],
64
64
  "merged": [
65
+ "**/post-release.*",
65
66
  "**/release.*",
66
67
  "**/test-integration.*",
67
68
  "**/test.*",
68
69
  "**/upgrade-dependency.*",
70
+ ".agents/skills/post-release/SKILL.*",
69
71
  ".agents/skills/release/SKILL.*",
70
72
  ".agents/skills/test-integration/SKILL.*",
71
73
  ".agents/skills/test/SKILL.*",
72
74
  ".agents/skills/upgrade-dependency/SKILL.*",
73
75
  ".claude/settings.json",
74
76
  ".gemini/settings.json",
75
- ".github/hooks/pre-commit",
77
+ ".git-hooks/pre-commit",
76
78
  ".gitignore"
77
79
  ],
78
80
  "ejected": []
79
81
  }
80
82
  };
81
83
 
82
- const INSTALLER_VERSION = "v0.5.7";
83
84
  const PACKAGE_NAME = '@fitlab-ai/agent-infra';
84
85
  // Add a new identifier here only after shipping matching .{platform}. template variants.
85
86
  const KNOWN_PLATFORMS = new Set(['github']);
@@ -102,6 +103,16 @@ function isInsideProject(projectRoot, relativePath) {
102
103
  return rel !== '' && !rel.startsWith('..') && !path.isAbsolute(rel);
103
104
  }
104
105
 
106
+ function isPathOwnedByOtherPlatform(relativePath, platformType) {
107
+ const normalized = norm(relativePath).replace(/^\.\//, '');
108
+ const top = normalized.split('/')[0];
109
+ if (!top.startsWith('.')) return false;
110
+
111
+ const candidate = top.slice(1);
112
+ if (!KNOWN_PLATFORMS.has(candidate)) return false;
113
+ return candidate !== platformType;
114
+ }
115
+
105
116
  function globMatch(pattern, filePath) {
106
117
  const p = norm(pattern), f = norm(filePath);
107
118
  const globstarDir = '__GLOBSTAR_DIR__';
@@ -141,6 +152,12 @@ function removeEmptyDirs(dir) {
141
152
  }
142
153
  }
143
154
 
155
+ function resolveVersionFromTemplateRoot(tplRoot) {
156
+ const pkgPath = path.join(path.dirname(tplRoot), 'package.json');
157
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
158
+ return 'v' + pkg.version;
159
+ }
160
+
144
161
  function parseSkillFrontmatter(filePath) {
145
162
  const content = fs.readFileSync(filePath, 'utf8');
146
163
  const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
@@ -945,7 +962,7 @@ function syncTemplates(projectRoot, templateRootOverride) {
945
962
  };
946
963
  }
947
964
  }
948
- const version = INSTALLER_VERSION;
965
+ const version = resolveVersionFromTemplateRoot(templateRoot);
949
966
  const hadTemplateSource = Object.prototype.hasOwnProperty.call(cfg, 'templateSource');
950
967
 
951
968
  const { project, org, language: lang = 'en' } = cfg;
@@ -970,7 +987,7 @@ function syncTemplates(projectRoot, templateRootOverride) {
970
987
  errors: [],
971
988
  conflicts: []
972
989
  },
973
- managed: { written: [], created: [], unchanged: [], skippedMerged: [], removed: [] },
990
+ managed: { written: [], created: [], unchanged: [], skippedMerged: [], skippedPlatform: [], removed: [] },
974
991
  custom: {
975
992
  detected: [],
976
993
  generated: [],
@@ -996,9 +1013,11 @@ function syncTemplates(projectRoot, templateRootOverride) {
996
1013
 
997
1014
  const known = new Set([...managed, ...merged, ...ejected]);
998
1015
  for (const e of (DEFAULTS.files.managed || [])) {
1016
+ if (isPathOwnedByOtherPlatform(e, platformType)) continue;
999
1017
  if (!known.has(e)) { managed.push(e); known.add(e); report.registryAdded.push({ entry: e, list: 'managed' }); }
1000
1018
  }
1001
1019
  for (const e of (DEFAULTS.files.merged || [])) {
1020
+ if (isPathOwnedByOtherPlatform(e, platformType)) continue;
1002
1021
  if (!known.has(e)) { merged.push(e); known.add(e); report.registryAdded.push({ entry: e, list: 'merged' }); }
1003
1022
  }
1004
1023
 
@@ -1007,7 +1026,34 @@ function syncTemplates(projectRoot, templateRootOverride) {
1007
1026
  const { mergedRels, sourceMap } = mergeTemplateSources(templateRoot, templateSources, report);
1008
1027
  const allRels = mergedRels;
1009
1028
  const allSet = new Set(allRels);
1029
+
1030
+ for (const entry of [...managed, ...merged, ...ejected]) {
1031
+ if (!isPathOwnedByOtherPlatform(entry, platformType)) continue;
1032
+
1033
+ if (entry.endsWith('/')) {
1034
+ const dir = path.join(projectRoot, entry);
1035
+ if (!fs.existsSync(dir)) continue;
1036
+
1037
+ for (const filePath of walkDir(dir)) {
1038
+ fs.unlinkSync(filePath);
1039
+ report.managed.removed.push(norm(path.relative(projectRoot, filePath)));
1040
+ }
1041
+ removeEmptyDirs(dir);
1042
+ continue;
1043
+ }
1044
+
1045
+ const target = path.join(projectRoot, renderPathname(entry, project));
1046
+ if (!fs.existsSync(target)) continue;
1047
+ fs.unlinkSync(target);
1048
+ report.managed.removed.push(norm(path.relative(projectRoot, target)));
1049
+ }
1050
+
1010
1051
  for (const entry of managed) {
1052
+ if (isPathOwnedByOtherPlatform(entry, platformType)) {
1053
+ report.managed.skippedPlatform.push(entry);
1054
+ continue;
1055
+ }
1056
+
1011
1057
  const isDir = entry.endsWith('/');
1012
1058
  let entryRels;
1013
1059
  const expectedTargets = isDir ? new Set() : null;
@@ -1116,6 +1162,11 @@ function syncTemplates(projectRoot, templateRootOverride) {
1116
1162
 
1117
1163
  const mergedMap = new Map();
1118
1164
  for (const entry of merged) {
1165
+ if (isPathOwnedByOtherPlatform(entry, platformType)) {
1166
+ report.managed.skippedPlatform.push(entry);
1167
+ continue;
1168
+ }
1169
+
1119
1170
  if (entry.includes('*')) {
1120
1171
  const hits = allRels.filter(r => {
1121
1172
  const t = norm(renderPathname(stripLangVariant(r), project));
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Create a GitHub Issue from a task file"
2
+ description: "Create an Issue from a task file"
3
3
  usage: "/create-issue <task-id>"
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "从任务文件创建 GitHub Issue"
2
+ description: "从任务文件创建 Issue"
3
3
  usage: "/create-issue <task-id>"
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Import a GitHub Issue and create a task"
2
+ description: "Import an Issue and create a task"
3
3
  usage: "/import-issue <issue-number>"
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "从 GitHub Issue 导入并创建任务"
2
+ description: "从 Issue 导入并创建任务"
3
3
  usage: "/import-issue <issue-number>"
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Initialize the repository's standard GitHub Labels taxonomy"
2
+ description: "Initialize the repository's standard labels taxonomy"
3
3
  disable-model-invocation: true
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "初始化仓库的 GitHub Labels 体系"
2
+ description: "初始化仓库的 labels 体系"
3
3
  disable-model-invocation: true
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Initialize the repository's standard GitHub Milestones taxonomy"
2
+ description: "Initialize the repository's standard milestones taxonomy"
3
3
  usage: "/init-milestones [--history]"
4
4
  disable-model-invocation: true
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "初始化仓库的 GitHub Milestones 体系"
2
+ description: "初始化仓库的 milestones 体系"
3
3
  usage: "/init-milestones [--history]"
4
4
  disable-model-invocation: true
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Restore local task files from GitHub Issue comments"
2
+ description: "Restore local task files from Issue comments"
3
3
  usage: "/restore-task <issue-number> [task-id]"
4
4
  disable-model-invocation: true
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "从 GitHub Issue 评论还原本地任务文件"
2
+ description: "从 Issue 评论还原本地任务文件"
3
3
  usage: "/restore-task <issue-number> [task-id]"
4
4
  disable-model-invocation: true
5
5
  ---
@@ -29,7 +29,7 @@ repo_root=$(
29
29
  CDPATH= cd -- "$script_dir/../.." && pwd
30
30
  )
31
31
 
32
- if sh "$repo_root/.github/hooks/check-version-format.sh"; then
32
+ if sh "$repo_root/.git-hooks/check-version-format.sh"; then
33
33
  echo "Claude hook: version check passed."
34
34
  exit 0
35
35
  else
@@ -1,4 +1,4 @@
1
- description = "Create a GitHub Issue from a task file"
1
+ description = "Create an Issue from a task file"
2
2
  prompt = """
3
3
  Create Issue for task {{args}}.
4
4
 
@@ -1,4 +1,4 @@
1
- description = "从任务文件创建 GitHub Issue"
1
+ description = "从任务文件创建 Issue"
2
2
  prompt = """
3
3
  为任务 {{args}} 创建 Issue。
4
4
 
@@ -1,4 +1,4 @@
1
- description = "Import a GitHub Issue and create a task"
1
+ description = "Import an Issue and create a task"
2
2
  prompt = """
3
3
  Import Issue #{{args}}.
4
4
 
@@ -1,4 +1,4 @@
1
- description = "从 GitHub Issue 导入并创建任务"
1
+ description = "从 Issue 导入并创建任务"
2
2
  prompt = """
3
3
  导入 Issue #{{args}}。
4
4
 
@@ -1,6 +1,6 @@
1
- description = "Initialize the repository's standard GitHub Labels taxonomy"
1
+ description = "Initialize the repository's standard labels taxonomy"
2
2
  prompt = """
3
- Initialize GitHub Labels for {{project}}.
3
+ Initialize labels for {{project}}.
4
4
 
5
5
  Read and execute the init-labels skill from `.agents/skills/init-labels/SKILL.md`.
6
6
 
@@ -1,6 +1,6 @@
1
- description = "初始化仓库的 GitHub Labels 体系"
1
+ description = "初始化仓库的 labels 体系"
2
2
  prompt = """
3
- 为 {{project}} 初始化 GitHub Labels
3
+ 为 {{project}} 初始化 labels
4
4
 
5
5
  读取并执行 `.agents/skills/init-labels/SKILL.md` 中的 init-labels 技能。
6
6
 
@@ -1,8 +1,8 @@
1
- description = "Initialize the repository's standard GitHub Milestones taxonomy"
1
+ description = "Initialize the repository's standard milestones taxonomy"
2
2
  prompt = """
3
3
  Initialize milestones: {{args}}
4
4
 
5
- Initialize GitHub Milestones for {{project}}.
5
+ Initialize milestones for {{project}}.
6
6
 
7
7
  Read and execute the init-milestones skill from `.agents/skills/init-milestones/SKILL.md`.
8
8
 
@@ -1,8 +1,8 @@
1
- description = "初始化仓库的 GitHub Milestones 体系"
1
+ description = "初始化仓库的 milestones 体系"
2
2
  prompt = """
3
3
  初始化里程碑:{{args}}
4
4
 
5
- 为 {{project}} 初始化 GitHub Milestones
5
+ 为 {{project}} 初始化 milestones
6
6
 
7
7
  读取并执行 `.agents/skills/init-milestones/SKILL.md` 中的 init-milestones 技能。
8
8
 
@@ -1,4 +1,4 @@
1
- description = "Restore local task files from GitHub Issue comments"
1
+ description = "Restore local task files from Issue comments"
2
2
  prompt = """
3
3
  Restore task from Issue: {{args}}
4
4
 
@@ -1,4 +1,4 @@
1
- description = "从 GitHub Issue 评论还原本地任务文件"
1
+ description = "从 Issue 评论还原本地任务文件"
2
2
  prompt = """
3
3
  从 Issue 还原任务:{{args}}
4
4
 
@@ -5,7 +5,7 @@ script_dir=$(
5
5
  CDPATH= cd -- "$(dirname -- "$0")" && pwd
6
6
  )
7
7
  repo_root=$(
8
- CDPATH= cd -- "$script_dir/../.." && pwd
8
+ CDPATH= cd -- "$script_dir/.." && pwd
9
9
  )
10
10
 
11
11
  airc_file="$repo_root/.agents/.airc.json"
@@ -21,7 +21,7 @@ template_version=$(
21
21
  exit 1
22
22
  }
23
23
 
24
- if ! printf '%s\n' "$template_version" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
24
+ if ! printf '%s\n' "$template_version" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$'; then
25
25
  echo "Error: .agents/.airc.json templateVersion must use v-prefixed semver (found: $template_version)."
26
26
  exit 1
27
27
  fi
@@ -26,7 +26,7 @@ jobs:
26
26
  PR_NUMBER: ${{ github.event.pull_request.number }}
27
27
  run: |
28
28
  changed_files=$(gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/files" \
29
- --paginate --jq '[.[].filename]')
29
+ --paginate --jq '.[].filename' | jq -Rn '[inputs]')
30
30
 
31
31
  should_labels=$(jq -rn \
32
32
  --argjson files "$changed_files" \
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Create a GitHub Issue from a task file"
2
+ description: "Create an Issue from a task file"
3
3
  agent: general
4
4
  subtask: false
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "从任务文件创建 GitHub Issue"
2
+ description: "从任务文件创建 Issue"
3
3
  agent: general
4
4
  subtask: false
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Import a GitHub Issue and create a task"
2
+ description: "Import an Issue and create a task"
3
3
  agent: general
4
4
  subtask: false
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "从 GitHub Issue 导入并创建任务"
2
+ description: "从 Issue 导入并创建任务"
3
3
  agent: general
4
4
  subtask: false
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Initialize the repository's standard GitHub Labels taxonomy"
2
+ description: "Initialize the repository's standard labels taxonomy"
3
3
  agent: general
4
4
  subtask: false
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "初始化仓库的 GitHub Labels 体系"
2
+ description: "初始化仓库的 labels 体系"
3
3
  agent: general
4
4
  subtask: false
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Initialize the repository's standard GitHub Milestones taxonomy"
2
+ description: "Initialize the repository's standard milestones taxonomy"
3
3
  agent: general
4
4
  subtask: false
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "初始化仓库的 GitHub Milestones 体系"
2
+ description: "初始化仓库的 milestones 体系"
3
3
  agent: general
4
4
  subtask: false
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Restore local task files from GitHub Issue comments"
2
+ description: "Restore local task files from Issue comments"
3
3
  agent: general
4
4
  subtask: false
5
5
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "从 GitHub Issue 评论还原本地任务文件"
2
+ description: "从 Issue 评论还原本地任务文件"
3
3
  agent: general
4
4
  subtask: false
5
5
  ---