@fitlab-ai/agent-infra 0.3.0
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/License.txt +21 -0
- package/README.md +170 -0
- package/README.zh-CN.md +170 -0
- package/bin/cli.js +65 -0
- package/lib/defaults.json +45 -0
- package/lib/init.js +203 -0
- package/lib/log.js +27 -0
- package/lib/paths.js +48 -0
- package/lib/prompt.js +70 -0
- package/lib/render.js +99 -0
- package/lib/update.js +161 -0
- package/lib/version.js +7 -0
- package/package.json +48 -0
- package/templates/.agent-workspace/README.md +26 -0
- package/templates/.agent-workspace/README.zh-CN.md +26 -0
- package/templates/.agents/QUICKSTART.md +166 -0
- package/templates/.agents/QUICKSTART.zh-CN.md +166 -0
- package/templates/.agents/README.md +134 -0
- package/templates/.agents/README.zh-CN.md +134 -0
- package/templates/.agents/skills/analyze-task/SKILL.md +169 -0
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +169 -0
- package/templates/.agents/skills/block-task/SKILL.md +164 -0
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +163 -0
- package/templates/.agents/skills/check-task/SKILL.md +122 -0
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +122 -0
- package/templates/.agents/skills/close-codescan/SKILL.md +122 -0
- package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +122 -0
- package/templates/.agents/skills/close-dependabot/SKILL.md +130 -0
- package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +130 -0
- package/templates/.agents/skills/commit/SKILL.md +218 -0
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +217 -0
- package/templates/.agents/skills/complete-task/SKILL.md +139 -0
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +137 -0
- package/templates/.agents/skills/create-pr/SKILL.md +126 -0
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +125 -0
- package/templates/.agents/skills/create-release-note/SKILL.md +167 -0
- package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +166 -0
- package/templates/.agents/skills/create-task/SKILL.md +143 -0
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +143 -0
- package/templates/.agents/skills/implement-task/SKILL.md +229 -0
- package/templates/.agents/skills/implement-task/SKILL.zh-CN.md +227 -0
- package/templates/.agents/skills/import-codescan/SKILL.md +103 -0
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +103 -0
- package/templates/.agents/skills/import-dependabot/SKILL.md +107 -0
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +107 -0
- package/templates/.agents/skills/import-issue/SKILL.md +119 -0
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +119 -0
- package/templates/.agents/skills/init-labels/SKILL.md +74 -0
- package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +74 -0
- package/templates/.agents/skills/init-labels/scripts/init-labels.sh +111 -0
- package/templates/.agents/skills/init-milestones/SKILL.md +74 -0
- package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +74 -0
- package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +169 -0
- package/templates/.agents/skills/plan-task/SKILL.md +225 -0
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +225 -0
- package/templates/.agents/skills/refine-task/SKILL.md +200 -0
- package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +200 -0
- package/templates/.agents/skills/refine-title/SKILL.md +84 -0
- package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +83 -0
- package/templates/.agents/skills/release/SKILL.md +142 -0
- package/templates/.agents/skills/release/SKILL.zh-CN.md +141 -0
- package/templates/.agents/skills/release/scripts/manage-milestones.sh +80 -0
- package/templates/.agents/skills/review-task/SKILL.md +276 -0
- package/templates/.agents/skills/review-task/SKILL.zh-CN.md +276 -0
- package/templates/.agents/skills/sync-issue/SKILL.md +569 -0
- package/templates/.agents/skills/sync-issue/SKILL.zh-CN.md +569 -0
- package/templates/.agents/skills/sync-pr/SKILL.md +142 -0
- package/templates/.agents/skills/sync-pr/SKILL.zh-CN.md +142 -0
- package/templates/.agents/skills/test/SKILL.md +61 -0
- package/templates/.agents/skills/test/SKILL.zh-CN.md +61 -0
- package/templates/.agents/skills/test-integration/SKILL.md +70 -0
- package/templates/.agents/skills/test-integration/SKILL.zh-CN.md +69 -0
- package/templates/.agents/skills/update-agent-infra/SKILL.md +136 -0
- package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +124 -0
- package/templates/.agents/skills/update-agent-infra/scripts/package.json +3 -0
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +469 -0
- package/templates/.agents/skills/upgrade-dependency/SKILL.md +88 -0
- package/templates/.agents/skills/upgrade-dependency/SKILL.zh-CN.md +87 -0
- package/templates/.agents/templates/handoff.md +60 -0
- package/templates/.agents/templates/handoff.zh-CN.md +60 -0
- package/templates/.agents/templates/review-report.md +67 -0
- package/templates/.agents/templates/review-report.zh-CN.md +67 -0
- package/templates/.agents/templates/task.md +65 -0
- package/templates/.agents/templates/task.zh-CN.md +65 -0
- package/templates/.agents/workflows/bug-fix.yaml +149 -0
- package/templates/.agents/workflows/bug-fix.zh-CN.yaml +149 -0
- package/templates/.agents/workflows/code-review.yaml +60 -0
- package/templates/.agents/workflows/code-review.zh-CN.yaml +60 -0
- package/templates/.agents/workflows/feature-development.yaml +150 -0
- package/templates/.agents/workflows/feature-development.zh-CN.yaml +150 -0
- package/templates/.agents/workflows/refactoring.yaml +154 -0
- package/templates/.agents/workflows/refactoring.zh-CN.yaml +154 -0
- package/templates/.claude/CLAUDE.md +163 -0
- package/templates/.claude/CLAUDE.zh-CN.md +163 -0
- package/templates/.claude/commands/analyze-task.md +8 -0
- package/templates/.claude/commands/analyze-task.zh-CN.md +8 -0
- package/templates/.claude/commands/block-task.md +8 -0
- package/templates/.claude/commands/block-task.zh-CN.md +8 -0
- package/templates/.claude/commands/check-task.md +8 -0
- package/templates/.claude/commands/check-task.zh-CN.md +8 -0
- package/templates/.claude/commands/close-codescan.md +8 -0
- package/templates/.claude/commands/close-codescan.zh-CN.md +8 -0
- package/templates/.claude/commands/close-dependabot.md +8 -0
- package/templates/.claude/commands/close-dependabot.zh-CN.md +8 -0
- package/templates/.claude/commands/commit.md +7 -0
- package/templates/.claude/commands/commit.zh-CN.md +7 -0
- package/templates/.claude/commands/complete-task.md +8 -0
- package/templates/.claude/commands/complete-task.zh-CN.md +8 -0
- package/templates/.claude/commands/create-pr.md +8 -0
- package/templates/.claude/commands/create-pr.zh-CN.md +8 -0
- package/templates/.claude/commands/create-release-note.md +8 -0
- package/templates/.claude/commands/create-release-note.zh-CN.md +8 -0
- package/templates/.claude/commands/create-task.md +8 -0
- package/templates/.claude/commands/create-task.zh-CN.md +8 -0
- package/templates/.claude/commands/implement-task.md +8 -0
- package/templates/.claude/commands/implement-task.zh-CN.md +8 -0
- package/templates/.claude/commands/import-codescan.md +8 -0
- package/templates/.claude/commands/import-codescan.zh-CN.md +8 -0
- package/templates/.claude/commands/import-dependabot.md +8 -0
- package/templates/.claude/commands/import-dependabot.zh-CN.md +8 -0
- package/templates/.claude/commands/import-issue.md +8 -0
- package/templates/.claude/commands/import-issue.zh-CN.md +8 -0
- package/templates/.claude/commands/init-labels.md +7 -0
- package/templates/.claude/commands/init-labels.zh-CN.md +7 -0
- package/templates/.claude/commands/init-milestones.md +8 -0
- package/templates/.claude/commands/init-milestones.zh-CN.md +8 -0
- package/templates/.claude/commands/plan-task.md +8 -0
- package/templates/.claude/commands/plan-task.zh-CN.md +8 -0
- package/templates/.claude/commands/refine-task.md +8 -0
- package/templates/.claude/commands/refine-task.zh-CN.md +8 -0
- package/templates/.claude/commands/refine-title.md +8 -0
- package/templates/.claude/commands/refine-title.zh-CN.md +8 -0
- package/templates/.claude/commands/release.md +8 -0
- package/templates/.claude/commands/release.zh-CN.md +8 -0
- package/templates/.claude/commands/review-task.md +8 -0
- package/templates/.claude/commands/review-task.zh-CN.md +8 -0
- package/templates/.claude/commands/sync-issue.md +8 -0
- package/templates/.claude/commands/sync-issue.zh-CN.md +8 -0
- package/templates/.claude/commands/sync-pr.md +8 -0
- package/templates/.claude/commands/sync-pr.zh-CN.md +8 -0
- package/templates/.claude/commands/test-integration.md +7 -0
- package/templates/.claude/commands/test-integration.zh-CN.md +7 -0
- package/templates/.claude/commands/test.md +7 -0
- package/templates/.claude/commands/test.zh-CN.md +7 -0
- package/templates/.claude/commands/update-agent-infra.md +7 -0
- package/templates/.claude/commands/update-agent-infra.zh-CN.md +7 -0
- package/templates/.claude/commands/upgrade-dependency.md +8 -0
- package/templates/.claude/commands/upgrade-dependency.zh-CN.md +8 -0
- package/templates/.claude/project-rules.md +65 -0
- package/templates/.claude/project-rules.zh-CN.md +65 -0
- package/templates/.claude/settings.json +20 -0
- package/templates/.codex/README.md +38 -0
- package/templates/.codex/README.zh-CN.md +37 -0
- package/templates/.editorconfig +15 -0
- package/templates/.gemini/commands/_project_/analyze-task.toml +8 -0
- package/templates/.gemini/commands/_project_/analyze-task.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/block-task.toml +8 -0
- package/templates/.gemini/commands/_project_/block-task.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/check-task.toml +8 -0
- package/templates/.gemini/commands/_project_/check-task.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/close-codescan.toml +8 -0
- package/templates/.gemini/commands/_project_/close-codescan.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/close-dependabot.toml +8 -0
- package/templates/.gemini/commands/_project_/close-dependabot.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/commit.toml +6 -0
- package/templates/.gemini/commands/_project_/commit.zh-CN.toml +6 -0
- package/templates/.gemini/commands/_project_/complete-task.toml +8 -0
- package/templates/.gemini/commands/_project_/complete-task.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/create-pr.toml +8 -0
- package/templates/.gemini/commands/_project_/create-pr.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/create-release-note.toml +8 -0
- package/templates/.gemini/commands/_project_/create-release-note.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/create-task.toml +8 -0
- package/templates/.gemini/commands/_project_/create-task.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/implement-task.toml +8 -0
- package/templates/.gemini/commands/_project_/implement-task.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/import-codescan.toml +8 -0
- package/templates/.gemini/commands/_project_/import-codescan.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/import-dependabot.toml +8 -0
- package/templates/.gemini/commands/_project_/import-dependabot.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/import-issue.toml +8 -0
- package/templates/.gemini/commands/_project_/import-issue.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/init-labels.toml +8 -0
- package/templates/.gemini/commands/_project_/init-labels.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/init-milestones.toml +10 -0
- package/templates/.gemini/commands/_project_/init-milestones.zh-CN.toml +10 -0
- package/templates/.gemini/commands/_project_/plan-task.toml +8 -0
- package/templates/.gemini/commands/_project_/plan-task.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/refine-task.toml +8 -0
- package/templates/.gemini/commands/_project_/refine-task.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/refine-title.toml +8 -0
- package/templates/.gemini/commands/_project_/refine-title.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/release.toml +8 -0
- package/templates/.gemini/commands/_project_/release.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/review-task.toml +8 -0
- package/templates/.gemini/commands/_project_/review-task.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/sync-issue.toml +8 -0
- package/templates/.gemini/commands/_project_/sync-issue.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/sync-pr.toml +8 -0
- package/templates/.gemini/commands/_project_/sync-pr.zh-CN.toml +8 -0
- package/templates/.gemini/commands/_project_/test-integration.toml +6 -0
- package/templates/.gemini/commands/_project_/test-integration.zh-CN.toml +6 -0
- package/templates/.gemini/commands/_project_/test.toml +6 -0
- package/templates/.gemini/commands/_project_/test.zh-CN.toml +6 -0
- package/templates/.gemini/commands/_project_/update-agent-infra.toml +6 -0
- package/templates/.gemini/commands/_project_/update-agent-infra.zh-CN.toml +6 -0
- package/templates/.gemini/commands/_project_/upgrade-dependency.toml +8 -0
- package/templates/.gemini/commands/_project_/upgrade-dependency.zh-CN.toml +8 -0
- package/templates/.gemini/settings.json +3 -0
- package/templates/.github/ISSUE_TEMPLATE/01_bug_report.yml +149 -0
- package/templates/.github/ISSUE_TEMPLATE/02_question.yml +101 -0
- package/templates/.github/ISSUE_TEMPLATE/03_feature_request.yml +131 -0
- package/templates/.github/ISSUE_TEMPLATE/04_documentation.yml +165 -0
- package/templates/.github/ISSUE_TEMPLATE/05_other.yml +147 -0
- package/templates/.github/ISSUE_TEMPLATE/config.yml +11 -0
- package/templates/.github/PULL_REQUEST_TEMPLATE.md +123 -0
- package/templates/.github/dependabot.yml +17 -0
- package/templates/.github/hooks/check-utf8-encoding.sh +25 -0
- package/templates/.github/release.yml +27 -0
- package/templates/.github/workflows/pr-title-check.yml +42 -0
- package/templates/.mailmap +4 -0
- package/templates/.opencode/COMMAND_STYLE_GUIDE.md +232 -0
- package/templates/.opencode/COMMAND_STYLE_GUIDE.zh-CN.md +232 -0
- package/templates/.opencode/README.md +76 -0
- package/templates/.opencode/README.zh-CN.md +77 -0
- package/templates/.opencode/commands/analyze-task.md +11 -0
- package/templates/.opencode/commands/analyze-task.zh-CN.md +11 -0
- package/templates/.opencode/commands/block-task.md +11 -0
- package/templates/.opencode/commands/block-task.zh-CN.md +11 -0
- package/templates/.opencode/commands/check-task.md +11 -0
- package/templates/.opencode/commands/check-task.zh-CN.md +11 -0
- package/templates/.opencode/commands/close-codescan.md +11 -0
- package/templates/.opencode/commands/close-codescan.zh-CN.md +11 -0
- package/templates/.opencode/commands/close-dependabot.md +11 -0
- package/templates/.opencode/commands/close-dependabot.zh-CN.md +11 -0
- package/templates/.opencode/commands/commit.md +9 -0
- package/templates/.opencode/commands/commit.zh-CN.md +9 -0
- package/templates/.opencode/commands/complete-task.md +11 -0
- package/templates/.opencode/commands/complete-task.zh-CN.md +11 -0
- package/templates/.opencode/commands/create-pr.md +11 -0
- package/templates/.opencode/commands/create-pr.zh-CN.md +11 -0
- package/templates/.opencode/commands/create-release-note.md +11 -0
- package/templates/.opencode/commands/create-release-note.zh-CN.md +11 -0
- package/templates/.opencode/commands/create-task.md +11 -0
- package/templates/.opencode/commands/create-task.zh-CN.md +11 -0
- package/templates/.opencode/commands/implement-task.md +11 -0
- package/templates/.opencode/commands/implement-task.zh-CN.md +11 -0
- package/templates/.opencode/commands/import-codescan.md +11 -0
- package/templates/.opencode/commands/import-codescan.zh-CN.md +11 -0
- package/templates/.opencode/commands/import-dependabot.md +11 -0
- package/templates/.opencode/commands/import-dependabot.zh-CN.md +11 -0
- package/templates/.opencode/commands/import-issue.md +11 -0
- package/templates/.opencode/commands/import-issue.zh-CN.md +11 -0
- package/templates/.opencode/commands/init-labels.md +9 -0
- package/templates/.opencode/commands/init-labels.zh-CN.md +9 -0
- package/templates/.opencode/commands/init-milestones.md +11 -0
- package/templates/.opencode/commands/init-milestones.zh-CN.md +11 -0
- package/templates/.opencode/commands/plan-task.md +11 -0
- package/templates/.opencode/commands/plan-task.zh-CN.md +11 -0
- package/templates/.opencode/commands/refine-task.md +11 -0
- package/templates/.opencode/commands/refine-task.zh-CN.md +11 -0
- package/templates/.opencode/commands/refine-title.md +11 -0
- package/templates/.opencode/commands/refine-title.zh-CN.md +11 -0
- package/templates/.opencode/commands/release.md +11 -0
- package/templates/.opencode/commands/release.zh-CN.md +11 -0
- package/templates/.opencode/commands/review-task.md +11 -0
- package/templates/.opencode/commands/review-task.zh-CN.md +11 -0
- package/templates/.opencode/commands/sync-issue.md +11 -0
- package/templates/.opencode/commands/sync-issue.zh-CN.md +11 -0
- package/templates/.opencode/commands/sync-pr.md +11 -0
- package/templates/.opencode/commands/sync-pr.zh-CN.md +11 -0
- package/templates/.opencode/commands/test-integration.md +9 -0
- package/templates/.opencode/commands/test-integration.zh-CN.md +9 -0
- package/templates/.opencode/commands/test.md +9 -0
- package/templates/.opencode/commands/test.zh-CN.md +9 -0
- package/templates/.opencode/commands/update-agent-infra.md +9 -0
- package/templates/.opencode/commands/update-agent-infra.zh-CN.md +9 -0
- package/templates/.opencode/commands/upgrade-dependency.md +11 -0
- package/templates/.opencode/commands/upgrade-dependency.zh-CN.md +11 -0
- package/templates/AGENTS.md +91 -0
- package/templates/AGENTS.zh-CN.md +91 -0
- package/templates/CONTRIBUTING.md +126 -0
- package/templates/CONTRIBUTING.zh-CN.md +124 -0
- package/templates/SECURITY.md +131 -0
- package/templates/SECURITY.zh-CN.md +131 -0
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* sync-templates.js — Deterministic template sync for managed & ejected files.
|
|
4
|
+
*
|
|
5
|
+
* Handles SKILL steps: 2 (git pull), 3.0 (registry sync), 4 (managed),
|
|
6
|
+
* 6 (ejected), 7 (.airc.json update).
|
|
7
|
+
*
|
|
8
|
+
* Merged files (step 5) are NOT handled — they require AI semantic merge.
|
|
9
|
+
* The report includes `merged.pending` so the AI knows what to process.
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* node .agents/skills/update-agent-infra/scripts/sync-templates.js [project-root]
|
|
13
|
+
*
|
|
14
|
+
* Output: JSON report to stdout.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import childProcess from 'node:child_process';
|
|
18
|
+
import fs from 'node:fs';
|
|
19
|
+
import os from 'node:os';
|
|
20
|
+
import path from 'node:path';
|
|
21
|
+
import { fileURLToPath } from 'node:url';
|
|
22
|
+
|
|
23
|
+
// Keep these helpers aligned with lib/paths.js for clone installs.
|
|
24
|
+
function resolveInstallDir() {
|
|
25
|
+
return path.join(os.homedir(), '.agent-infra');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function resolveTemplateDir() {
|
|
29
|
+
const clonePath = path.join(resolveInstallDir(), 'templates');
|
|
30
|
+
if (fs.existsSync(clonePath)) {
|
|
31
|
+
return clonePath;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const DEFAULTS = {
|
|
38
|
+
"files": {
|
|
39
|
+
"managed": [
|
|
40
|
+
".agents/skills/",
|
|
41
|
+
".agents/templates/",
|
|
42
|
+
".agents/workflows/",
|
|
43
|
+
".agent-workspace/README.md",
|
|
44
|
+
".claude/commands/",
|
|
45
|
+
".editorconfig",
|
|
46
|
+
".gemini/commands/",
|
|
47
|
+
".github/hooks/",
|
|
48
|
+
".github/ISSUE_TEMPLATE/",
|
|
49
|
+
".github/PULL_REQUEST_TEMPLATE.md",
|
|
50
|
+
".github/release.yml",
|
|
51
|
+
".github/workflows/pr-title-check.yml",
|
|
52
|
+
".opencode/commands/"
|
|
53
|
+
],
|
|
54
|
+
"merged": [
|
|
55
|
+
"**/release.*",
|
|
56
|
+
"**/test-integration.*",
|
|
57
|
+
"**/test.*",
|
|
58
|
+
"**/upgrade-dependency.*",
|
|
59
|
+
".agents/QUICKSTART.md",
|
|
60
|
+
".agents/README.md",
|
|
61
|
+
".agents/skills/release/SKILL.*",
|
|
62
|
+
".agents/skills/test-integration/SKILL.*",
|
|
63
|
+
".agents/skills/test/SKILL.*",
|
|
64
|
+
".agents/skills/upgrade-dependency/SKILL.*",
|
|
65
|
+
".claude/CLAUDE.md",
|
|
66
|
+
".claude/project-rules.md",
|
|
67
|
+
".claude/settings.json",
|
|
68
|
+
".codex/README.md",
|
|
69
|
+
".gemini/settings.json",
|
|
70
|
+
".github/dependabot.yml",
|
|
71
|
+
".gitignore",
|
|
72
|
+
".mailmap",
|
|
73
|
+
".opencode/COMMAND_STYLE_GUIDE.md",
|
|
74
|
+
".opencode/README.md",
|
|
75
|
+
"AGENTS.md",
|
|
76
|
+
"CONTRIBUTING.md",
|
|
77
|
+
"SECURITY.md"
|
|
78
|
+
],
|
|
79
|
+
"ejected": []
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const INSTALLER_VERSION = "0.3.0";
|
|
84
|
+
|
|
85
|
+
function norm(p) { return p.replace(/\\/g, '/'); }
|
|
86
|
+
|
|
87
|
+
function globMatch(pattern, filePath) {
|
|
88
|
+
const p = norm(pattern), f = norm(filePath);
|
|
89
|
+
const globstarDir = '__GLOBSTAR_DIR__';
|
|
90
|
+
const globstar = '__GLOBSTAR__';
|
|
91
|
+
const star = '__STAR__';
|
|
92
|
+
const qmark = '__QMARK__';
|
|
93
|
+
const re = p
|
|
94
|
+
.replace(/([.+^${}()|[\]\\])/g, '\\$1')
|
|
95
|
+
.replace(/\*\*\//g, globstarDir)
|
|
96
|
+
.replace(/\*\*/g, globstar)
|
|
97
|
+
.replace(/\*/g, star)
|
|
98
|
+
.replace(/\?/g, qmark)
|
|
99
|
+
.replace(new RegExp(globstarDir, 'g'), '(?:.+/)?')
|
|
100
|
+
.replace(new RegExp(globstar, 'g'), '[^/]*')
|
|
101
|
+
.replace(new RegExp(star, 'g'), '[^/]*')
|
|
102
|
+
.replace(new RegExp(qmark, 'g'), '[^/]');
|
|
103
|
+
return new RegExp('^' + re + '$').test(f);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function walkDir(dir) {
|
|
107
|
+
if (!fs.existsSync(dir)) return [];
|
|
108
|
+
const out = [];
|
|
109
|
+
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
110
|
+
const p = path.join(dir, e.name);
|
|
111
|
+
e.isDirectory() ? out.push(...walkDir(p)) : out.push(p);
|
|
112
|
+
}
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function removeEmptyDirs(dir) {
|
|
117
|
+
if (!fs.existsSync(dir)) return;
|
|
118
|
+
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
119
|
+
if (e.isDirectory()) removeEmptyDirs(path.join(dir, e.name));
|
|
120
|
+
}
|
|
121
|
+
if (fs.readdirSync(dir).length === 0) {
|
|
122
|
+
fs.rmdirSync(dir);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function matchesAny(rel, patterns) {
|
|
127
|
+
const n = norm(rel);
|
|
128
|
+
return patterns.some(p => norm(p) === n || globMatch(p, n));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function renderContent(text, vars) {
|
|
132
|
+
return text
|
|
133
|
+
.replace(/\{\{project\}\}/g, vars.project)
|
|
134
|
+
.replace(/\{\{org\}\}/g, vars.org);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function renderPathname(p, project) {
|
|
138
|
+
return p.replace(/_project_/g, project);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function resolveProjectTemplateDir(projectRoot, templateSource) {
|
|
142
|
+
const fallbackRoot = resolveTemplateDir();
|
|
143
|
+
|
|
144
|
+
const candidates = [];
|
|
145
|
+
if (templateSource) {
|
|
146
|
+
if (path.isAbsolute(templateSource)) {
|
|
147
|
+
candidates.push(templateSource);
|
|
148
|
+
} else {
|
|
149
|
+
if (fallbackRoot) {
|
|
150
|
+
candidates.push(path.resolve(path.dirname(fallbackRoot), templateSource));
|
|
151
|
+
}
|
|
152
|
+
candidates.push(path.resolve(projectRoot, templateSource));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (fallbackRoot) {
|
|
156
|
+
candidates.push(fallbackRoot);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
for (const candidate of candidates) {
|
|
160
|
+
try {
|
|
161
|
+
if (fs.statSync(candidate).isDirectory()) {
|
|
162
|
+
return candidate;
|
|
163
|
+
}
|
|
164
|
+
} catch {
|
|
165
|
+
// Keep scanning until a valid directory is found.
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function isBinary(fp) {
|
|
173
|
+
const fd = fs.openSync(fp, 'r');
|
|
174
|
+
const buf = Buffer.alloc(8192);
|
|
175
|
+
const n = fs.readSync(fd, buf, 0, 8192, 0);
|
|
176
|
+
fs.closeSync(fd);
|
|
177
|
+
if (n === 0) return false;
|
|
178
|
+
for (let i = 0; i < n; i++) if (buf[i] === 0) return true;
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function fileModule(rel) {
|
|
183
|
+
const p = norm(rel);
|
|
184
|
+
if (p.startsWith('.github/')) return 'github';
|
|
185
|
+
if (p.startsWith('.agents/') || p.startsWith('.claude/') ||
|
|
186
|
+
p.startsWith('.gemini/') || p.startsWith('.opencode/') ||
|
|
187
|
+
p.startsWith('.codex/') || p === 'AGENTS.md') return 'ai';
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function gitUrl(dir) {
|
|
192
|
+
try {
|
|
193
|
+
return childProcess.execSync('git remote get-url origin', {
|
|
194
|
+
cwd: dir, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe']
|
|
195
|
+
}).trim();
|
|
196
|
+
} catch { return null; }
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Public-facing docs should keep all available language variants in sync.
|
|
200
|
+
const MULTI_LANG = new Set(['SECURITY.md']);
|
|
201
|
+
|
|
202
|
+
function langSelect(rels, lang, allSet, project) {
|
|
203
|
+
const sel = new Map();
|
|
204
|
+
|
|
205
|
+
if (lang === 'zh-CN') {
|
|
206
|
+
for (const r of rels) {
|
|
207
|
+
if (!r.includes('.zh-CN.')) continue;
|
|
208
|
+
const target = norm(renderPathname(r.replace(/\.zh-CN\./, '.'), project));
|
|
209
|
+
sel.set(target, r);
|
|
210
|
+
}
|
|
211
|
+
for (const r of rels) {
|
|
212
|
+
if (r.includes('.zh-CN.')) continue;
|
|
213
|
+
const target = norm(renderPathname(r, project));
|
|
214
|
+
if (sel.has(target)) continue;
|
|
215
|
+
const ext = path.extname(r), base = r.slice(0, -ext.length);
|
|
216
|
+
if (allSet.has(norm(base + '.zh-CN' + ext))) continue;
|
|
217
|
+
sel.set(target, r);
|
|
218
|
+
}
|
|
219
|
+
} else {
|
|
220
|
+
for (const r of rels) {
|
|
221
|
+
if (r.includes('.zh-CN.')) continue;
|
|
222
|
+
sel.set(norm(renderPathname(r, project)), r);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return sel;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function syncTemplates(projectRoot) {
|
|
230
|
+
const cfgPath = path.join(projectRoot, '.airc.json');
|
|
231
|
+
if (!fs.existsSync(cfgPath)) {
|
|
232
|
+
return { error: 'No .airc.json in project root.' };
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const cfg = JSON.parse(fs.readFileSync(cfgPath, 'utf8'));
|
|
236
|
+
const templateRoot = resolveProjectTemplateDir(projectRoot, cfg.templateSource);
|
|
237
|
+
if (!templateRoot) {
|
|
238
|
+
return { error: 'Template source not found. Install: curl -fsSL https://raw.githubusercontent.com/fitlab-ai/agent-infra/main/install.sh | sh' };
|
|
239
|
+
}
|
|
240
|
+
const installDir = resolveInstallDir();
|
|
241
|
+
|
|
242
|
+
const hasGit = fs.existsSync(path.join(installDir, '.git'));
|
|
243
|
+
if (hasGit) {
|
|
244
|
+
try { childProcess.execSync('git fetch --tags --quiet', { cwd: installDir, stdio: 'pipe' }); } catch { /* network */ }
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
let version = 'unknown';
|
|
248
|
+
if (hasGit) {
|
|
249
|
+
let tagOutput;
|
|
250
|
+
try {
|
|
251
|
+
tagOutput = childProcess.execSync('git tag --sort=-v:refname', {
|
|
252
|
+
cwd: installDir, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe']
|
|
253
|
+
}).trim();
|
|
254
|
+
} catch {
|
|
255
|
+
return { error: 'Failed to list tags in agent-infra repository. Please check git installation.' };
|
|
256
|
+
}
|
|
257
|
+
const latestTag = tagOutput.split('\n')[0];
|
|
258
|
+
if (!latestTag) {
|
|
259
|
+
return { error: 'No tags found in agent-infra repository. This is unexpected — please reinstall.' };
|
|
260
|
+
}
|
|
261
|
+
try { childProcess.execFileSync('git', ['checkout', latestTag, '--quiet'], { cwd: installDir, stdio: 'pipe' }); } catch { /* ignore */ }
|
|
262
|
+
version = latestTag;
|
|
263
|
+
} else {
|
|
264
|
+
version = INSTALLER_VERSION || version;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const { project, org, language: lang = 'en', modules = [] } = cfg;
|
|
268
|
+
const vars = { project, org };
|
|
269
|
+
|
|
270
|
+
const managed = [...(cfg.files.managed || [])];
|
|
271
|
+
const merged = [...(cfg.files.merged || [])];
|
|
272
|
+
const ejected = [...(cfg.files.ejected || [])];
|
|
273
|
+
|
|
274
|
+
const report = {
|
|
275
|
+
templateVersion: version,
|
|
276
|
+
templateRoot: norm(templateRoot),
|
|
277
|
+
registryAdded: [],
|
|
278
|
+
managed: { written: [], created: [], unchanged: [], skippedMerged: [], skippedModule: [], removed: [] },
|
|
279
|
+
ejected: { created: [], skipped: [] },
|
|
280
|
+
merged: { pending: [] },
|
|
281
|
+
configUpdated: false,
|
|
282
|
+
selfUpdate: false
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
const known = new Set([...managed, ...merged, ...ejected]);
|
|
286
|
+
for (const e of (DEFAULTS.files.managed || [])) {
|
|
287
|
+
if (!known.has(e)) { managed.push(e); known.add(e); report.registryAdded.push({ entry: e, list: 'managed' }); }
|
|
288
|
+
}
|
|
289
|
+
for (const e of (DEFAULTS.files.merged || [])) {
|
|
290
|
+
if (!known.has(e)) { merged.push(e); known.add(e); report.registryAdded.push({ entry: e, list: 'merged' }); }
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const allRels = walkDir(templateRoot).map(f => norm(path.relative(templateRoot, f)));
|
|
294
|
+
const allSet = new Set(allRels);
|
|
295
|
+
const modSet = new Set(modules);
|
|
296
|
+
|
|
297
|
+
for (const entry of managed) {
|
|
298
|
+
const isDir = entry.endsWith('/');
|
|
299
|
+
let entryRels;
|
|
300
|
+
const expectedTargets = isDir ? new Set() : null;
|
|
301
|
+
|
|
302
|
+
if (isDir) {
|
|
303
|
+
const dir = path.join(templateRoot, entry);
|
|
304
|
+
if (!fs.existsSync(dir)) continue;
|
|
305
|
+
entryRels = walkDir(dir).map(f => norm(path.relative(templateRoot, f)));
|
|
306
|
+
} else {
|
|
307
|
+
entryRels = [];
|
|
308
|
+
const n = norm(entry);
|
|
309
|
+
if (allSet.has(n)) entryRels.push(n);
|
|
310
|
+
const ext = path.extname(entry), base = entry.slice(0, -ext.length);
|
|
311
|
+
const zh = norm(base + '.zh-CN' + ext);
|
|
312
|
+
if (allSet.has(zh)) entryRels.push(zh);
|
|
313
|
+
if (!entryRels.length) continue;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const selected = MULTI_LANG.has(norm(entry))
|
|
317
|
+
? entryRels.map(r => [norm(renderPathname(r, project)), r])
|
|
318
|
+
: langSelect(entryRels, lang, allSet, project);
|
|
319
|
+
|
|
320
|
+
for (const [tgt, src] of selected) {
|
|
321
|
+
if (expectedTargets) expectedTargets.add(tgt);
|
|
322
|
+
|
|
323
|
+
const mod = fileModule(tgt);
|
|
324
|
+
if (mod !== null && !modSet.has(mod)) {
|
|
325
|
+
report.managed.skippedModule.push(tgt);
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (matchesAny(tgt, merged) || matchesAny(tgt, ejected)) {
|
|
330
|
+
report.managed.skippedMerged.push(tgt);
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const srcFull = path.join(templateRoot, src);
|
|
335
|
+
const dstFull = path.join(projectRoot, tgt);
|
|
336
|
+
const bin = isBinary(srcFull);
|
|
337
|
+
const content = bin
|
|
338
|
+
? fs.readFileSync(srcFull)
|
|
339
|
+
: renderContent(fs.readFileSync(srcFull, 'utf8'), vars);
|
|
340
|
+
|
|
341
|
+
const exists = fs.existsSync(dstFull);
|
|
342
|
+
if (exists) {
|
|
343
|
+
const cur = bin ? fs.readFileSync(dstFull) : fs.readFileSync(dstFull, 'utf8');
|
|
344
|
+
if (bin ? content.equals(cur) : content === cur) {
|
|
345
|
+
report.managed.unchanged.push(tgt);
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const dir = path.dirname(dstFull);
|
|
351
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
352
|
+
fs.writeFileSync(dstFull, content);
|
|
353
|
+
if (tgt.endsWith('.sh')) {
|
|
354
|
+
try { fs.chmodSync(dstFull, 0o755); } catch { /* Windows */ }
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
(exists ? report.managed.written : report.managed.created).push(tgt);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (isDir) {
|
|
361
|
+
const projDir = path.join(projectRoot, entry);
|
|
362
|
+
if (fs.existsSync(projDir)) {
|
|
363
|
+
const removedBefore = report.managed.removed.length;
|
|
364
|
+
const projFiles = walkDir(projDir).map(f => norm(path.relative(projectRoot, f)));
|
|
365
|
+
for (const projFile of projFiles) {
|
|
366
|
+
if (expectedTargets.has(projFile)) continue;
|
|
367
|
+
if (matchesAny(projFile, merged) || matchesAny(projFile, ejected)) continue;
|
|
368
|
+
|
|
369
|
+
const mod = fileModule(projFile);
|
|
370
|
+
if (mod !== null && !modSet.has(mod)) continue;
|
|
371
|
+
|
|
372
|
+
fs.unlinkSync(path.join(projectRoot, projFile));
|
|
373
|
+
report.managed.removed.push(projFile);
|
|
374
|
+
}
|
|
375
|
+
if (report.managed.removed.length > removedBefore) {
|
|
376
|
+
removeEmptyDirs(projDir);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
for (const entry of ejected) {
|
|
383
|
+
const dstFull = path.join(projectRoot, entry);
|
|
384
|
+
if (fs.existsSync(dstFull)) {
|
|
385
|
+
report.ejected.skipped.push(entry);
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
let src = norm(entry);
|
|
390
|
+
if (lang === 'zh-CN') {
|
|
391
|
+
const ext = path.extname(entry), base = entry.slice(0, -ext.length);
|
|
392
|
+
const zh = norm(base + '.zh-CN' + ext);
|
|
393
|
+
if (allSet.has(zh)) src = zh;
|
|
394
|
+
}
|
|
395
|
+
if (!allSet.has(src)) continue;
|
|
396
|
+
|
|
397
|
+
const content = renderContent(fs.readFileSync(path.join(templateRoot, src), 'utf8'), vars);
|
|
398
|
+
const dir = path.dirname(dstFull);
|
|
399
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
400
|
+
fs.writeFileSync(dstFull, content);
|
|
401
|
+
report.ejected.created.push(entry);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const mergedMap = new Map();
|
|
405
|
+
for (const entry of merged) {
|
|
406
|
+
if (entry.includes('*')) {
|
|
407
|
+
const hits = allRels.filter(r => {
|
|
408
|
+
const t = norm(renderPathname(
|
|
409
|
+
r.includes('.zh-CN.') ? r.replace(/\.zh-CN\./, '.') : r, project
|
|
410
|
+
));
|
|
411
|
+
return globMatch(entry, t);
|
|
412
|
+
});
|
|
413
|
+
for (const [t, s] of langSelect(hits, lang, allSet, project)) {
|
|
414
|
+
if (!mergedMap.has(t)) mergedMap.set(t, s);
|
|
415
|
+
}
|
|
416
|
+
} else {
|
|
417
|
+
const rels = [];
|
|
418
|
+
const n = norm(entry);
|
|
419
|
+
if (allSet.has(n)) rels.push(n);
|
|
420
|
+
const ext = path.extname(entry), base = entry.slice(0, -ext.length);
|
|
421
|
+
const zh = norm(base + '.zh-CN' + ext);
|
|
422
|
+
if (allSet.has(zh)) rels.push(zh);
|
|
423
|
+
const selected = MULTI_LANG.has(n)
|
|
424
|
+
? rels.map(r => [norm(renderPathname(r, project)), r])
|
|
425
|
+
: langSelect(rels, lang, allSet, project);
|
|
426
|
+
for (const [t, s] of selected) {
|
|
427
|
+
if (!mergedMap.has(t)) mergedMap.set(t, s);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
report.merged.pending = [...mergedMap].map(
|
|
432
|
+
([target, template]) => ({ target, template })
|
|
433
|
+
);
|
|
434
|
+
|
|
435
|
+
const projUrl = gitUrl(projectRoot);
|
|
436
|
+
const instUrl = gitUrl(installDir);
|
|
437
|
+
report.selfUpdate = !!(projUrl && instUrl && projUrl === instUrl);
|
|
438
|
+
|
|
439
|
+
const hasChanges = (
|
|
440
|
+
report.managed.written.length +
|
|
441
|
+
report.managed.created.length +
|
|
442
|
+
report.managed.removed.length +
|
|
443
|
+
report.ejected.created.length +
|
|
444
|
+
report.registryAdded.length
|
|
445
|
+
) > 0;
|
|
446
|
+
|
|
447
|
+
const prevVersion = cfg.templateVersion;
|
|
448
|
+
|
|
449
|
+
cfg.files.managed = managed;
|
|
450
|
+
cfg.files.merged = merged;
|
|
451
|
+
cfg.files.ejected = ejected;
|
|
452
|
+
cfg.templateVersion = version;
|
|
453
|
+
|
|
454
|
+
report.configUpdated = hasChanges || prevVersion !== version;
|
|
455
|
+
|
|
456
|
+
fs.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2) + '\n', 'utf8');
|
|
457
|
+
|
|
458
|
+
return report;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
const entryPath = process.argv[1] ? path.resolve(process.argv[1]) : null;
|
|
462
|
+
if (entryPath === fileURLToPath(import.meta.url)) {
|
|
463
|
+
const root = path.resolve(process.argv[2] || process.cwd());
|
|
464
|
+
const result = syncTemplates(root);
|
|
465
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
466
|
+
if (result.error) process.exitCode = 1;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
export { syncTemplates };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: upgrade-dependency
|
|
3
|
+
description: >
|
|
4
|
+
Upgrade a specified dependency package to a new version and verify
|
|
5
|
+
the change. Triggered when the user requests dependency upgrade.
|
|
6
|
+
Arguments: package name, old version, new version.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Upgrade Dependency
|
|
10
|
+
|
|
11
|
+
Upgrade a dependency package to the specified version with build and test verification.
|
|
12
|
+
|
|
13
|
+
<!-- TODO: Adapt the commands below to your project's package manager -->
|
|
14
|
+
|
|
15
|
+
## Execution Flow
|
|
16
|
+
|
|
17
|
+
### 1. Parse Arguments
|
|
18
|
+
|
|
19
|
+
Extract from arguments: package name, old version, new version.
|
|
20
|
+
|
|
21
|
+
### 2. Find Dependency Location
|
|
22
|
+
|
|
23
|
+
Search for the package in dependency files:
|
|
24
|
+
- `package.json` (Node.js)
|
|
25
|
+
- `pom.xml` (Maven)
|
|
26
|
+
- `requirements.txt` / `pyproject.toml` (Python)
|
|
27
|
+
- `go.mod` (Go)
|
|
28
|
+
- Other project-specific dependency files
|
|
29
|
+
|
|
30
|
+
### 3. Update Version
|
|
31
|
+
|
|
32
|
+
Update the version number in the dependency file.
|
|
33
|
+
|
|
34
|
+
### 4. Install Dependencies
|
|
35
|
+
|
|
36
|
+
<!-- TODO: Replace with your project's install command -->
|
|
37
|
+
```bash
|
|
38
|
+
# npm install (Node.js)
|
|
39
|
+
# mvn clean install (Maven)
|
|
40
|
+
# pip install -r requirements.txt (Python)
|
|
41
|
+
# go mod tidy (Go)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 5. Verify Build
|
|
45
|
+
|
|
46
|
+
<!-- TODO: Replace with your project's build command -->
|
|
47
|
+
```bash
|
|
48
|
+
# npm run build (Node.js)
|
|
49
|
+
# mvn compile (Maven)
|
|
50
|
+
# make build (generic)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 6. Run Tests
|
|
54
|
+
|
|
55
|
+
Execute the project's test command. Reference the test skill for the project-specific test command.
|
|
56
|
+
|
|
57
|
+
### 7. Output Results
|
|
58
|
+
|
|
59
|
+
Report:
|
|
60
|
+
- Files modified
|
|
61
|
+
- Build status (pass/fail)
|
|
62
|
+
- Test status (pass/fail)
|
|
63
|
+
- Any deprecation warnings or breaking changes noticed
|
|
64
|
+
|
|
65
|
+
Suggest next step:
|
|
66
|
+
|
|
67
|
+
> **IMPORTANT**: All TUI command formats listed below must be output in full. Do not show only the format for the current AI agent.
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
Next step - commit changes:
|
|
71
|
+
- Claude Code / OpenCode: /commit
|
|
72
|
+
- Gemini CLI: /{{project}}:commit
|
|
73
|
+
- Codex CLI: $commit
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Notes
|
|
77
|
+
|
|
78
|
+
1. **No auto-commit**: Do NOT automatically commit changes
|
|
79
|
+
2. **Major version upgrades**: Warn about potential breaking changes
|
|
80
|
+
3. **Test failures**: Report the failure details and wait for user decision
|
|
81
|
+
4. **Lock files**: If the project uses lock files (package-lock.json, yarn.lock, etc.), ensure they are updated
|
|
82
|
+
5. **Transitive dependencies**: Note if the upgrade affects transitive dependencies
|
|
83
|
+
|
|
84
|
+
## Error Handling
|
|
85
|
+
|
|
86
|
+
- Package not found: Prompt "Package {name} not found in dependency files"
|
|
87
|
+
- Build failure: Output errors and suggest checking for breaking changes
|
|
88
|
+
- Test failure: Output test errors and suggest checking migration guide
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: upgrade-dependency
|
|
3
|
+
description: >
|
|
4
|
+
升级项目中的指定依赖包到新版本并验证变更。
|
|
5
|
+
当用户要求升级依赖时触发。参数:包名、原版本和新版本。
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 升级依赖
|
|
9
|
+
|
|
10
|
+
将依赖包升级到指定版本,并进行构建和测试验证。
|
|
11
|
+
|
|
12
|
+
<!-- TODO: 根据你的项目包管理器调整以下命令 -->
|
|
13
|
+
|
|
14
|
+
## 执行流程
|
|
15
|
+
|
|
16
|
+
### 1. 解析参数
|
|
17
|
+
|
|
18
|
+
从参数中提取:包名、原版本、新版本。
|
|
19
|
+
|
|
20
|
+
### 2. 查找依赖位置
|
|
21
|
+
|
|
22
|
+
在依赖文件中搜索目标包:
|
|
23
|
+
- `package.json`(Node.js)
|
|
24
|
+
- `pom.xml`(Maven)
|
|
25
|
+
- `requirements.txt` / `pyproject.toml`(Python)
|
|
26
|
+
- `go.mod`(Go)
|
|
27
|
+
- 其他项目特定的依赖文件
|
|
28
|
+
|
|
29
|
+
### 3. 更新版本
|
|
30
|
+
|
|
31
|
+
在依赖文件中更新版本号。
|
|
32
|
+
|
|
33
|
+
### 4. 安装依赖
|
|
34
|
+
|
|
35
|
+
<!-- TODO: 替换为你的项目安装命令 -->
|
|
36
|
+
```bash
|
|
37
|
+
# npm install (Node.js)
|
|
38
|
+
# mvn clean install (Maven)
|
|
39
|
+
# pip install -r requirements.txt (Python)
|
|
40
|
+
# go mod tidy (Go)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 5. 验证构建
|
|
44
|
+
|
|
45
|
+
<!-- TODO: 替换为你的项目构建命令 -->
|
|
46
|
+
```bash
|
|
47
|
+
# npm run build (Node.js)
|
|
48
|
+
# mvn compile (Maven)
|
|
49
|
+
# make build (通用)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 6. 运行测试
|
|
53
|
+
|
|
54
|
+
执行项目的测试命令。参考 test 技能获取项目特定的测试命令。
|
|
55
|
+
|
|
56
|
+
### 7. 输出结果
|
|
57
|
+
|
|
58
|
+
报告:
|
|
59
|
+
- 修改的文件
|
|
60
|
+
- 构建状态(通过/失败)
|
|
61
|
+
- 测试状态(通过/失败)
|
|
62
|
+
- 发现的任何弃用警告或破坏性变更
|
|
63
|
+
|
|
64
|
+
建议下一步:
|
|
65
|
+
|
|
66
|
+
> **重要**:以下「下一步」中列出的所有 TUI 命令格式必须完整输出,不要只展示当前 AI 代理对应的格式。
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
下一步 - 提交代码:
|
|
70
|
+
- Claude Code / OpenCode:/commit
|
|
71
|
+
- Gemini CLI:/{{project}}:commit
|
|
72
|
+
- Codex CLI:$commit
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## 注意事项
|
|
76
|
+
|
|
77
|
+
1. **禁止自动提交**:不要自动提交变更
|
|
78
|
+
2. **主版本升级**:警告潜在的破坏性变更
|
|
79
|
+
3. **测试失败**:报告失败详情并等待用户决定
|
|
80
|
+
4. **锁文件**:如果项目使用锁文件(package-lock.json、yarn.lock 等),确保一并更新
|
|
81
|
+
5. **传递依赖**:注意升级是否影响传递依赖
|
|
82
|
+
|
|
83
|
+
## 错误处理
|
|
84
|
+
|
|
85
|
+
- 包未找到:提示 "Package {name} not found in dependency files"
|
|
86
|
+
- 构建失败:输出错误并建议检查破坏性变更
|
|
87
|
+
- 测试失败:输出测试错误并建议查看迁移指南
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Handoff Document
|
|
2
|
+
|
|
3
|
+
## Metadata
|
|
4
|
+
|
|
5
|
+
- **Task ID**: task-XXX
|
|
6
|
+
- **From**: [AI tool name, e.g., claude]
|
|
7
|
+
- **To**: [AI tool name, e.g., codex]
|
|
8
|
+
- **Phase Completed**: [e.g., analysis]
|
|
9
|
+
- **Next Phase**: [e.g., design]
|
|
10
|
+
- **Date**: YYYY-MM-DD
|
|
11
|
+
|
|
12
|
+
## Summary of Completed Work
|
|
13
|
+
|
|
14
|
+
[Brief summary of what was accomplished in the completed phase.]
|
|
15
|
+
|
|
16
|
+
## Current State
|
|
17
|
+
|
|
18
|
+
### Files Modified
|
|
19
|
+
|
|
20
|
+
- `path/to/file1` - What was changed and why
|
|
21
|
+
- `path/to/file2` - What was changed and why
|
|
22
|
+
|
|
23
|
+
### Branch Status
|
|
24
|
+
|
|
25
|
+
- **Branch**: `feature/xxx`
|
|
26
|
+
- **Commits**: [Number of commits made]
|
|
27
|
+
- **Tests**: [Passing / Failing / Not yet written]
|
|
28
|
+
|
|
29
|
+
### Key Decisions Made
|
|
30
|
+
|
|
31
|
+
1. [Decision 1 and rationale]
|
|
32
|
+
2. [Decision 2 and rationale]
|
|
33
|
+
|
|
34
|
+
## Next Steps
|
|
35
|
+
|
|
36
|
+
[What the receiving AI should do next. Be specific.]
|
|
37
|
+
|
|
38
|
+
1. [ ] Step 1
|
|
39
|
+
2. [ ] Step 2
|
|
40
|
+
3. [ ] Step 3
|
|
41
|
+
|
|
42
|
+
## Important Context
|
|
43
|
+
|
|
44
|
+
[Anything the receiving AI needs to know that isn't obvious from the code.]
|
|
45
|
+
|
|
46
|
+
### Constraints
|
|
47
|
+
|
|
48
|
+
- [Constraint 1]
|
|
49
|
+
- [Constraint 2]
|
|
50
|
+
|
|
51
|
+
### Risks and Concerns
|
|
52
|
+
|
|
53
|
+
- [Risk 1]
|
|
54
|
+
- [Risk 2]
|
|
55
|
+
|
|
56
|
+
## References
|
|
57
|
+
|
|
58
|
+
- Task file: `.agent-workspace/active/task-XXX.md`
|
|
59
|
+
- Related docs: [links or file paths]
|
|
60
|
+
- Related issues: #XXX
|