@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
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
/**
|
|
3
2
|
* sync-templates.js — Deterministic template sync for managed & ejected files.
|
|
4
3
|
*
|
|
@@ -20,6 +19,9 @@ import path from 'node:path';
|
|
|
20
19
|
import { fileURLToPath } from 'node:url';
|
|
21
20
|
|
|
22
21
|
const DEFAULTS = {
|
|
22
|
+
"platform": {
|
|
23
|
+
"type": "github"
|
|
24
|
+
},
|
|
23
25
|
"sandbox": {
|
|
24
26
|
"runtimes": [
|
|
25
27
|
"node20"
|
|
@@ -74,7 +76,11 @@ const DEFAULTS = {
|
|
|
74
76
|
}
|
|
75
77
|
};
|
|
76
78
|
|
|
77
|
-
const INSTALLER_VERSION = "v0.5.
|
|
79
|
+
const INSTALLER_VERSION = "v0.5.3";
|
|
80
|
+
const PACKAGE_NAME = '@fitlab-ai/agent-infra';
|
|
81
|
+
// Add a new identifier here only after shipping matching .{platform}. template variants.
|
|
82
|
+
const KNOWN_PLATFORMS = new Set(['github']);
|
|
83
|
+
const KNOWN_LANGUAGES = new Set(['en', 'zh-CN']);
|
|
78
84
|
|
|
79
85
|
function norm(p) { return p.replace(/\\/g, '/'); }
|
|
80
86
|
|
|
@@ -132,6 +138,53 @@ function renderPathname(p, project) {
|
|
|
132
138
|
return p.replace(/_project_/g, project);
|
|
133
139
|
}
|
|
134
140
|
|
|
141
|
+
function variantExt(relativePath) {
|
|
142
|
+
return path.extname(relativePath);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function variantBase(relativePath) {
|
|
146
|
+
const ext = variantExt(relativePath);
|
|
147
|
+
return relativePath.slice(0, -ext.length);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function withVariant(relativePath, variant) {
|
|
151
|
+
const ext = variantExt(relativePath);
|
|
152
|
+
const base = variantBase(relativePath);
|
|
153
|
+
return `${base}.${variant}${ext}`;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function stripVariant(relativePath, variant) {
|
|
157
|
+
return relativePath.replace(new RegExp(`\\.${variant.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\.`), '.');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function isPlatformVariant(relativePath, platform) {
|
|
161
|
+
const platforms = new Set([...KNOWN_PLATFORMS, platform]);
|
|
162
|
+
for (const candidate of platforms) {
|
|
163
|
+
if (relativePath.includes(`.${candidate}.`)) {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function isLangVariant(relativePath) {
|
|
171
|
+
for (const lang of KNOWN_LANGUAGES) {
|
|
172
|
+
if (relativePath.includes(`.${lang}.`)) {
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function stripLangVariant(relativePath) {
|
|
180
|
+
for (const lang of KNOWN_LANGUAGES) {
|
|
181
|
+
if (relativePath.includes(`.${lang}.`)) {
|
|
182
|
+
return stripVariant(relativePath, lang);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return relativePath;
|
|
186
|
+
}
|
|
187
|
+
|
|
135
188
|
function isTemplateDir(dir) {
|
|
136
189
|
try {
|
|
137
190
|
return fs.statSync(dir).isDirectory();
|
|
@@ -140,37 +193,107 @@ function isTemplateDir(dir) {
|
|
|
140
193
|
}
|
|
141
194
|
}
|
|
142
195
|
|
|
143
|
-
function
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
196
|
+
function verifyPackageDir(dir) {
|
|
197
|
+
const pkgPath = path.join(dir, 'package.json');
|
|
198
|
+
if (!fs.existsSync(pkgPath)) {
|
|
199
|
+
return { templateRoot: null, reason: `package.json not found at ${pkgPath}` };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
let pkg;
|
|
203
|
+
try {
|
|
204
|
+
pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
205
|
+
} catch {
|
|
206
|
+
return { templateRoot: null, reason: `invalid package.json at ${pkgPath}` };
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (pkg.name !== PACKAGE_NAME) {
|
|
210
|
+
const packageName = typeof pkg.name === 'string' && pkg.name ? pkg.name : 'an unknown package';
|
|
211
|
+
return { templateRoot: null, reason: `${pkgPath} belongs to ${packageName}` };
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const templateRoot = path.join(dir, 'templates');
|
|
215
|
+
if (!isTemplateDir(templateRoot)) {
|
|
216
|
+
return { templateRoot: null, reason: `templates/ not found at ${templateRoot}` };
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return { templateRoot, reason: null };
|
|
147
220
|
}
|
|
148
221
|
|
|
149
|
-
function
|
|
222
|
+
function resolveUnixTemplateRoot(name) {
|
|
223
|
+
let linkPath;
|
|
150
224
|
try {
|
|
151
|
-
|
|
225
|
+
linkPath = childProcess.execSync(`command -v ${name}`, {
|
|
152
226
|
encoding: 'utf8',
|
|
153
227
|
stdio: ['pipe', 'pipe', 'pipe']
|
|
154
228
|
}).trim();
|
|
155
|
-
const globalTemplateRoot = resolveInstalledTemplateDir(globalRoot);
|
|
156
|
-
if (globalTemplateRoot) return globalTemplateRoot;
|
|
157
229
|
} catch {
|
|
158
|
-
|
|
230
|
+
return { templateRoot: null, reason: 'not found in PATH' };
|
|
159
231
|
}
|
|
160
232
|
|
|
233
|
+
if (!linkPath) {
|
|
234
|
+
return { templateRoot: null, reason: 'not found in PATH' };
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
let realPath;
|
|
161
238
|
try {
|
|
162
|
-
|
|
163
|
-
|
|
239
|
+
realPath = fs.realpathSync(linkPath);
|
|
240
|
+
} catch {
|
|
241
|
+
return { templateRoot: null, reason: `cannot resolve symlink target for ${linkPath}` };
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
let dir = path.dirname(realPath);
|
|
245
|
+
while (true) {
|
|
246
|
+
const pkgPath = path.join(dir, 'package.json');
|
|
247
|
+
if (fs.existsSync(pkgPath)) {
|
|
248
|
+
return verifyPackageDir(dir);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const parentDir = path.dirname(dir);
|
|
252
|
+
if (parentDir === dir) {
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
dir = parentDir;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return { templateRoot: null, reason: `no package.json found above ${realPath}` };
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function resolveWindowsTemplateRoot(name) {
|
|
262
|
+
let output;
|
|
263
|
+
try {
|
|
264
|
+
output = childProcess.execSync(`where ${name}`, {
|
|
164
265
|
encoding: 'utf8',
|
|
165
266
|
stdio: ['pipe', 'pipe', 'pipe']
|
|
166
267
|
}).trim();
|
|
167
|
-
const localTemplateRoot = resolveInstalledTemplateDir(localRoot);
|
|
168
|
-
if (localTemplateRoot) return localTemplateRoot;
|
|
169
268
|
} catch {
|
|
170
|
-
|
|
269
|
+
return { templateRoot: null, reason: 'not found in PATH' };
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const wrapperPaths = output.split(/\r?\n/).map(line => line.trim()).filter(Boolean);
|
|
273
|
+
if (wrapperPaths.length === 0) {
|
|
274
|
+
return { templateRoot: null, reason: 'not found in PATH' };
|
|
171
275
|
}
|
|
172
276
|
|
|
173
|
-
|
|
277
|
+
const wrapperPath = wrapperPaths.find(line => /\.cmd$/i.test(line)) || wrapperPaths[0];
|
|
278
|
+
const packageDir = path.join(path.dirname(wrapperPath), 'node_modules', '@fitlab-ai', 'agent-infra');
|
|
279
|
+
return verifyPackageDir(packageDir);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function resolveTemplateRoot() {
|
|
283
|
+
const resolver = process.platform === 'win32'
|
|
284
|
+
? resolveWindowsTemplateRoot
|
|
285
|
+
: resolveUnixTemplateRoot;
|
|
286
|
+
const errors = [];
|
|
287
|
+
|
|
288
|
+
for (const name of ['ai', 'agent-infra']) {
|
|
289
|
+
const result = resolver(name);
|
|
290
|
+
if (result.templateRoot) {
|
|
291
|
+
return result.templateRoot;
|
|
292
|
+
}
|
|
293
|
+
errors.push({ name, reason: result.reason });
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return { templateRoot: null, errors };
|
|
174
297
|
}
|
|
175
298
|
|
|
176
299
|
function isBinary(fp) {
|
|
@@ -194,30 +317,60 @@ function gitUrl(dir) {
|
|
|
194
317
|
function langSelect(rels, lang, allSet, project) {
|
|
195
318
|
const sel = new Map();
|
|
196
319
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
const target = norm(renderPathname(r.replace(/\.zh-CN\./, '.'), project));
|
|
320
|
+
for (const r of rels) {
|
|
321
|
+
if (r.includes(`.${lang}.`)) {
|
|
322
|
+
const target = norm(renderPathname(stripVariant(r, lang), project));
|
|
201
323
|
sel.set(target, r);
|
|
202
|
-
}
|
|
203
|
-
for (const r of rels) {
|
|
204
|
-
if (r.includes('.zh-CN.')) continue;
|
|
324
|
+
} else if (!isLangVariant(r)) {
|
|
205
325
|
const target = norm(renderPathname(r, project));
|
|
206
|
-
if (sel.has(target))
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
sel.set(target, r);
|
|
210
|
-
}
|
|
211
|
-
} else {
|
|
212
|
-
for (const r of rels) {
|
|
213
|
-
if (r.includes('.zh-CN.')) continue;
|
|
214
|
-
sel.set(norm(renderPathname(r, project)), r);
|
|
326
|
+
if (!sel.has(target)) {
|
|
327
|
+
sel.set(target, r);
|
|
328
|
+
}
|
|
215
329
|
}
|
|
216
330
|
}
|
|
217
331
|
|
|
218
332
|
return sel;
|
|
219
333
|
}
|
|
220
334
|
|
|
335
|
+
function platformSelect(entries, platform, project) {
|
|
336
|
+
const sel = new Map();
|
|
337
|
+
|
|
338
|
+
for (const [target, src] of entries) {
|
|
339
|
+
if (!target.includes(`.${platform}.`)) continue;
|
|
340
|
+
sel.set(norm(renderPathname(stripVariant(target, platform), project)), src);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
for (const [target, src] of entries) {
|
|
344
|
+
const normalizedTarget = norm(renderPathname(target, project));
|
|
345
|
+
if (sel.has(normalizedTarget)) continue;
|
|
346
|
+
if (isPlatformVariant(target, platform)) continue;
|
|
347
|
+
sel.set(normalizedTarget, src);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return sel;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function entryVariantRels(entry, allSet, platform) {
|
|
354
|
+
const rels = [];
|
|
355
|
+
const normalized = norm(entry);
|
|
356
|
+
const candidates = [
|
|
357
|
+
normalized,
|
|
358
|
+
withVariant(normalized, 'en'),
|
|
359
|
+
withVariant(normalized, 'zh-CN'),
|
|
360
|
+
withVariant(normalized, platform),
|
|
361
|
+
withVariant(withVariant(normalized, platform), 'en'),
|
|
362
|
+
withVariant(withVariant(normalized, platform), 'zh-CN')
|
|
363
|
+
];
|
|
364
|
+
|
|
365
|
+
for (const candidate of candidates) {
|
|
366
|
+
if (allSet.has(candidate) && !rels.includes(candidate)) {
|
|
367
|
+
rels.push(candidate);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return rels;
|
|
372
|
+
}
|
|
373
|
+
|
|
221
374
|
function syncTemplates(projectRoot, templateRootOverride) {
|
|
222
375
|
const configDir = path.join(projectRoot, '.agents');
|
|
223
376
|
const cfgPath = path.join(configDir, '.airc.json');
|
|
@@ -228,14 +381,35 @@ function syncTemplates(projectRoot, templateRootOverride) {
|
|
|
228
381
|
|
|
229
382
|
const cfg = JSON.parse(fs.readFileSync(cfgPath, 'utf8'));
|
|
230
383
|
const configPathRel = norm(path.relative(projectRoot, cfgPath));
|
|
231
|
-
|
|
384
|
+
let templateRoot = templateRootOverride;
|
|
232
385
|
if (!templateRoot) {
|
|
233
|
-
|
|
386
|
+
const resolvedTemplateRoot = resolveTemplateRoot();
|
|
387
|
+
if (typeof resolvedTemplateRoot === 'string') {
|
|
388
|
+
templateRoot = resolvedTemplateRoot;
|
|
389
|
+
} else {
|
|
390
|
+
const details = resolvedTemplateRoot.errors
|
|
391
|
+
.map(({ name, reason }) => ` - ${name}: ${reason}`)
|
|
392
|
+
.join('\n');
|
|
393
|
+
return {
|
|
394
|
+
error: [
|
|
395
|
+
'Template source not found.',
|
|
396
|
+
'',
|
|
397
|
+
'Attempted binary lookups:',
|
|
398
|
+
details,
|
|
399
|
+
'',
|
|
400
|
+
'Please ensure agent-infra is installed and available on PATH.',
|
|
401
|
+
'If already installed, upgrade to the latest version or reinstall:',
|
|
402
|
+
' npm install -g @fitlab-ai/agent-infra',
|
|
403
|
+
' brew upgrade fitlab-ai/agent-infra/agent-infra || brew install fitlab-ai/agent-infra/agent-infra'
|
|
404
|
+
].join('\n')
|
|
405
|
+
};
|
|
406
|
+
}
|
|
234
407
|
}
|
|
235
408
|
const version = INSTALLER_VERSION;
|
|
236
409
|
const hadTemplateSource = Object.prototype.hasOwnProperty.call(cfg, 'templateSource');
|
|
237
410
|
|
|
238
411
|
const { project, org, language: lang = 'en' } = cfg;
|
|
412
|
+
const platformType = cfg.platform?.type || DEFAULTS.platform.type;
|
|
239
413
|
const vars = { project, org };
|
|
240
414
|
|
|
241
415
|
const managed = [...(cfg.files.managed || [])];
|
|
@@ -274,15 +448,11 @@ function syncTemplates(projectRoot, templateRootOverride) {
|
|
|
274
448
|
entryRels = walkDir(dir).map(f => norm(path.relative(templateRoot, f)));
|
|
275
449
|
} else {
|
|
276
450
|
entryRels = [];
|
|
277
|
-
|
|
278
|
-
if (allSet.has(n)) entryRels.push(n);
|
|
279
|
-
const ext = path.extname(entry), base = entry.slice(0, -ext.length);
|
|
280
|
-
const zh = norm(base + '.zh-CN' + ext);
|
|
281
|
-
if (allSet.has(zh)) entryRels.push(zh);
|
|
451
|
+
entryRels = entryVariantRels(entry, allSet, platformType);
|
|
282
452
|
if (!entryRels.length) continue;
|
|
283
453
|
}
|
|
284
454
|
|
|
285
|
-
const selected = langSelect(entryRels, lang, allSet, project);
|
|
455
|
+
const selected = platformSelect(langSelect(entryRels, lang, allSet, project), platformType, project);
|
|
286
456
|
|
|
287
457
|
for (const [tgt, src] of selected) {
|
|
288
458
|
if (expectedTargets) expectedTargets.add(tgt);
|
|
@@ -345,13 +515,10 @@ function syncTemplates(projectRoot, templateRootOverride) {
|
|
|
345
515
|
continue;
|
|
346
516
|
}
|
|
347
517
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if (allSet.has(zh)) src = zh;
|
|
353
|
-
}
|
|
354
|
-
if (!allSet.has(src)) continue;
|
|
518
|
+
const selected = platformSelect(langSelect(entryVariantRels(entry, allSet, platformType), lang, allSet, project), platformType, project);
|
|
519
|
+
const target = norm(renderPathname(entry, project));
|
|
520
|
+
const src = selected.get(target);
|
|
521
|
+
if (!src) continue;
|
|
355
522
|
|
|
356
523
|
const content = renderContent(fs.readFileSync(path.join(templateRoot, src), 'utf8'), vars);
|
|
357
524
|
const dir = path.dirname(dstFull);
|
|
@@ -364,22 +531,15 @@ function syncTemplates(projectRoot, templateRootOverride) {
|
|
|
364
531
|
for (const entry of merged) {
|
|
365
532
|
if (entry.includes('*')) {
|
|
366
533
|
const hits = allRels.filter(r => {
|
|
367
|
-
const t = norm(renderPathname(
|
|
368
|
-
r.includes('.zh-CN.') ? r.replace(/\.zh-CN\./, '.') : r, project
|
|
369
|
-
));
|
|
534
|
+
const t = norm(renderPathname(stripLangVariant(r), project));
|
|
370
535
|
return globMatch(entry, t);
|
|
371
536
|
});
|
|
372
|
-
for (const [t, s] of langSelect(hits, lang, allSet, project)) {
|
|
537
|
+
for (const [t, s] of platformSelect(langSelect(hits, lang, allSet, project), platformType, project)) {
|
|
373
538
|
if (!mergedMap.has(t)) mergedMap.set(t, s);
|
|
374
539
|
}
|
|
375
540
|
} else {
|
|
376
|
-
const rels =
|
|
377
|
-
const
|
|
378
|
-
if (allSet.has(n)) rels.push(n);
|
|
379
|
-
const ext = path.extname(entry), base = entry.slice(0, -ext.length);
|
|
380
|
-
const zh = norm(base + '.zh-CN' + ext);
|
|
381
|
-
if (allSet.has(zh)) rels.push(zh);
|
|
382
|
-
const selected = langSelect(rels, lang, allSet, project);
|
|
541
|
+
const rels = entryVariantRels(entry, allSet, platformType);
|
|
542
|
+
const selected = platformSelect(langSelect(rels, lang, allSet, project), platformType, project);
|
|
383
543
|
for (const [t, s] of selected) {
|
|
384
544
|
if (!mergedMap.has(t)) mergedMap.set(t, s);
|
|
385
545
|
}
|
|
@@ -4,8 +4,8 @@ type: feature # feature | bugfix | refactor | docs | review
|
|
|
4
4
|
branch: "" # <project>-<type>-<slug>
|
|
5
5
|
workflow: feature-development # feature-development | bug-fix | code-review | refactoring
|
|
6
6
|
status: open # open | in-progress | review | blocked | completed
|
|
7
|
-
created_at: YYYY-MM-
|
|
8
|
-
updated_at: YYYY-MM-
|
|
7
|
+
created_at: YYYY-MM-DDTHH:mm:ss±HH:MM
|
|
8
|
+
updated_at: YYYY-MM-DDTHH:mm:ss±HH:MM
|
|
9
9
|
current_step: analysis # analysis | design | implementation | review | fix | commit
|
|
10
10
|
assigned_to: "" # claude | codex | gemini | opencode | human
|
|
11
11
|
---
|
|
@@ -50,7 +50,7 @@ assigned_to: "" # claude | codex | gemini | opencode | human
|
|
|
50
50
|
## Activity Log
|
|
51
51
|
|
|
52
52
|
<!-- Append a new entry for each workflow step. Do NOT overwrite previous entries. -->
|
|
53
|
-
<!-- Format: - {
|
|
53
|
+
<!-- Format: - {YYYY-MM-DD HH:mm:ss±HH:MM} — **{step}** by {agent} — {brief summary} -->
|
|
54
54
|
|
|
55
55
|
## Completion Checklist
|
|
56
56
|
|
|
@@ -4,8 +4,8 @@ type: feature # feature | bugfix | refactor | docs | review
|
|
|
4
4
|
branch: "" # <project>-<type>-<slug>
|
|
5
5
|
workflow: feature-development # feature-development | bug-fix | code-review | refactoring
|
|
6
6
|
status: open # open | in-progress | review | blocked | completed
|
|
7
|
-
created_at: YYYY-MM-
|
|
8
|
-
updated_at: YYYY-MM-
|
|
7
|
+
created_at: YYYY-MM-DDTHH:mm:ss±HH:MM
|
|
8
|
+
updated_at: YYYY-MM-DDTHH:mm:ss±HH:MM
|
|
9
9
|
current_step: analysis # analysis | design | implementation | review | fix | commit
|
|
10
10
|
assigned_to: "" # claude | codex | gemini | opencode | human
|
|
11
11
|
---
|
|
@@ -50,7 +50,7 @@ assigned_to: "" # claude | codex | gemini | opencode | human
|
|
|
50
50
|
## 活动日志
|
|
51
51
|
|
|
52
52
|
<!-- 每个工作流步骤追加一条新记录,不要覆盖之前的记录。 -->
|
|
53
|
-
<!-- 格式:- {
|
|
53
|
+
<!-- 格式:- {YYYY-MM-DD HH:mm:ss±HH:MM} — **{步骤}** by {执行者} — {简要说明} -->
|
|
54
54
|
|
|
55
55
|
## 完成检查清单
|
|
56
56
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/templates/.agents/rules/{milestone-inference.md → milestone-inference.github.en.md}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/templates/.agents/skills/commit/reference/{commit-message.md → commit-message.en.md}
RENAMED
|
File without changes
|
/package/templates/.agents/skills/commit/reference/{copyright-check.md → copyright-check.en.md}
RENAMED
|
File without changes
|
/package/templates/.agents/skills/commit/reference/{pr-summary-sync.md → pr-summary-sync.en.md}
RENAMED
|
File without changes
|
|
File without changes
|
/package/templates/.agents/skills/create-pr/reference/{branch-strategy.md → branch-strategy.en.md}
RENAMED
|
File without changes
|
/package/templates/.agents/skills/create-pr/reference/{comment-publish.md → comment-publish.en.md}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/templates/.agents/skills/init-labels/scripts/{init-labels.sh → init-labels.github.sh}
RENAMED
|
File without changes
|
|
File without changes
|
/package/templates/.agents/skills/refine-task/reference/{fix-workflow.md → fix-workflow.en.md}
RENAMED
|
File without changes
|
/package/templates/.agents/skills/refine-task/reference/{report-template.md → report-template.en.md}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/templates/.agents/skills/review-task/reference/{report-template.md → report-template.en.md}
RENAMED
|
File without changes
|
/package/templates/.agents/skills/review-task/reference/{review-criteria.md → review-criteria.en.md}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/templates/.agents/workflows/{feature-development.yaml → feature-development.en.yaml}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/templates/.gemini/commands/_project_/{close-codescan.toml → close-codescan.en.toml}
RENAMED
|
File without changes
|
/package/templates/.gemini/commands/_project_/{close-dependabot.toml → close-dependabot.en.toml}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/templates/.gemini/commands/_project_/{implement-task.toml → implement-task.en.toml}
RENAMED
|
File without changes
|
/package/templates/.gemini/commands/_project_/{import-codescan.toml → import-codescan.en.toml}
RENAMED
|
File without changes
|
/package/templates/.gemini/commands/_project_/{import-dependabot.toml → import-dependabot.en.toml}
RENAMED
|
File without changes
|
|
File without changes
|