@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.
Files changed (285) hide show
  1. package/License.txt +21 -0
  2. package/README.md +170 -0
  3. package/README.zh-CN.md +170 -0
  4. package/bin/cli.js +65 -0
  5. package/lib/defaults.json +45 -0
  6. package/lib/init.js +203 -0
  7. package/lib/log.js +27 -0
  8. package/lib/paths.js +48 -0
  9. package/lib/prompt.js +70 -0
  10. package/lib/render.js +99 -0
  11. package/lib/update.js +161 -0
  12. package/lib/version.js +7 -0
  13. package/package.json +48 -0
  14. package/templates/.agent-workspace/README.md +26 -0
  15. package/templates/.agent-workspace/README.zh-CN.md +26 -0
  16. package/templates/.agents/QUICKSTART.md +166 -0
  17. package/templates/.agents/QUICKSTART.zh-CN.md +166 -0
  18. package/templates/.agents/README.md +134 -0
  19. package/templates/.agents/README.zh-CN.md +134 -0
  20. package/templates/.agents/skills/analyze-task/SKILL.md +169 -0
  21. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +169 -0
  22. package/templates/.agents/skills/block-task/SKILL.md +164 -0
  23. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +163 -0
  24. package/templates/.agents/skills/check-task/SKILL.md +122 -0
  25. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +122 -0
  26. package/templates/.agents/skills/close-codescan/SKILL.md +122 -0
  27. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +122 -0
  28. package/templates/.agents/skills/close-dependabot/SKILL.md +130 -0
  29. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +130 -0
  30. package/templates/.agents/skills/commit/SKILL.md +218 -0
  31. package/templates/.agents/skills/commit/SKILL.zh-CN.md +217 -0
  32. package/templates/.agents/skills/complete-task/SKILL.md +139 -0
  33. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +137 -0
  34. package/templates/.agents/skills/create-pr/SKILL.md +126 -0
  35. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +125 -0
  36. package/templates/.agents/skills/create-release-note/SKILL.md +167 -0
  37. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +166 -0
  38. package/templates/.agents/skills/create-task/SKILL.md +143 -0
  39. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +143 -0
  40. package/templates/.agents/skills/implement-task/SKILL.md +229 -0
  41. package/templates/.agents/skills/implement-task/SKILL.zh-CN.md +227 -0
  42. package/templates/.agents/skills/import-codescan/SKILL.md +103 -0
  43. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +103 -0
  44. package/templates/.agents/skills/import-dependabot/SKILL.md +107 -0
  45. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +107 -0
  46. package/templates/.agents/skills/import-issue/SKILL.md +119 -0
  47. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +119 -0
  48. package/templates/.agents/skills/init-labels/SKILL.md +74 -0
  49. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +74 -0
  50. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +111 -0
  51. package/templates/.agents/skills/init-milestones/SKILL.md +74 -0
  52. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +74 -0
  53. package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +169 -0
  54. package/templates/.agents/skills/plan-task/SKILL.md +225 -0
  55. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +225 -0
  56. package/templates/.agents/skills/refine-task/SKILL.md +200 -0
  57. package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +200 -0
  58. package/templates/.agents/skills/refine-title/SKILL.md +84 -0
  59. package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +83 -0
  60. package/templates/.agents/skills/release/SKILL.md +142 -0
  61. package/templates/.agents/skills/release/SKILL.zh-CN.md +141 -0
  62. package/templates/.agents/skills/release/scripts/manage-milestones.sh +80 -0
  63. package/templates/.agents/skills/review-task/SKILL.md +276 -0
  64. package/templates/.agents/skills/review-task/SKILL.zh-CN.md +276 -0
  65. package/templates/.agents/skills/sync-issue/SKILL.md +569 -0
  66. package/templates/.agents/skills/sync-issue/SKILL.zh-CN.md +569 -0
  67. package/templates/.agents/skills/sync-pr/SKILL.md +142 -0
  68. package/templates/.agents/skills/sync-pr/SKILL.zh-CN.md +142 -0
  69. package/templates/.agents/skills/test/SKILL.md +61 -0
  70. package/templates/.agents/skills/test/SKILL.zh-CN.md +61 -0
  71. package/templates/.agents/skills/test-integration/SKILL.md +70 -0
  72. package/templates/.agents/skills/test-integration/SKILL.zh-CN.md +69 -0
  73. package/templates/.agents/skills/update-agent-infra/SKILL.md +136 -0
  74. package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +124 -0
  75. package/templates/.agents/skills/update-agent-infra/scripts/package.json +3 -0
  76. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +469 -0
  77. package/templates/.agents/skills/upgrade-dependency/SKILL.md +88 -0
  78. package/templates/.agents/skills/upgrade-dependency/SKILL.zh-CN.md +87 -0
  79. package/templates/.agents/templates/handoff.md +60 -0
  80. package/templates/.agents/templates/handoff.zh-CN.md +60 -0
  81. package/templates/.agents/templates/review-report.md +67 -0
  82. package/templates/.agents/templates/review-report.zh-CN.md +67 -0
  83. package/templates/.agents/templates/task.md +65 -0
  84. package/templates/.agents/templates/task.zh-CN.md +65 -0
  85. package/templates/.agents/workflows/bug-fix.yaml +149 -0
  86. package/templates/.agents/workflows/bug-fix.zh-CN.yaml +149 -0
  87. package/templates/.agents/workflows/code-review.yaml +60 -0
  88. package/templates/.agents/workflows/code-review.zh-CN.yaml +60 -0
  89. package/templates/.agents/workflows/feature-development.yaml +150 -0
  90. package/templates/.agents/workflows/feature-development.zh-CN.yaml +150 -0
  91. package/templates/.agents/workflows/refactoring.yaml +154 -0
  92. package/templates/.agents/workflows/refactoring.zh-CN.yaml +154 -0
  93. package/templates/.claude/CLAUDE.md +163 -0
  94. package/templates/.claude/CLAUDE.zh-CN.md +163 -0
  95. package/templates/.claude/commands/analyze-task.md +8 -0
  96. package/templates/.claude/commands/analyze-task.zh-CN.md +8 -0
  97. package/templates/.claude/commands/block-task.md +8 -0
  98. package/templates/.claude/commands/block-task.zh-CN.md +8 -0
  99. package/templates/.claude/commands/check-task.md +8 -0
  100. package/templates/.claude/commands/check-task.zh-CN.md +8 -0
  101. package/templates/.claude/commands/close-codescan.md +8 -0
  102. package/templates/.claude/commands/close-codescan.zh-CN.md +8 -0
  103. package/templates/.claude/commands/close-dependabot.md +8 -0
  104. package/templates/.claude/commands/close-dependabot.zh-CN.md +8 -0
  105. package/templates/.claude/commands/commit.md +7 -0
  106. package/templates/.claude/commands/commit.zh-CN.md +7 -0
  107. package/templates/.claude/commands/complete-task.md +8 -0
  108. package/templates/.claude/commands/complete-task.zh-CN.md +8 -0
  109. package/templates/.claude/commands/create-pr.md +8 -0
  110. package/templates/.claude/commands/create-pr.zh-CN.md +8 -0
  111. package/templates/.claude/commands/create-release-note.md +8 -0
  112. package/templates/.claude/commands/create-release-note.zh-CN.md +8 -0
  113. package/templates/.claude/commands/create-task.md +8 -0
  114. package/templates/.claude/commands/create-task.zh-CN.md +8 -0
  115. package/templates/.claude/commands/implement-task.md +8 -0
  116. package/templates/.claude/commands/implement-task.zh-CN.md +8 -0
  117. package/templates/.claude/commands/import-codescan.md +8 -0
  118. package/templates/.claude/commands/import-codescan.zh-CN.md +8 -0
  119. package/templates/.claude/commands/import-dependabot.md +8 -0
  120. package/templates/.claude/commands/import-dependabot.zh-CN.md +8 -0
  121. package/templates/.claude/commands/import-issue.md +8 -0
  122. package/templates/.claude/commands/import-issue.zh-CN.md +8 -0
  123. package/templates/.claude/commands/init-labels.md +7 -0
  124. package/templates/.claude/commands/init-labels.zh-CN.md +7 -0
  125. package/templates/.claude/commands/init-milestones.md +8 -0
  126. package/templates/.claude/commands/init-milestones.zh-CN.md +8 -0
  127. package/templates/.claude/commands/plan-task.md +8 -0
  128. package/templates/.claude/commands/plan-task.zh-CN.md +8 -0
  129. package/templates/.claude/commands/refine-task.md +8 -0
  130. package/templates/.claude/commands/refine-task.zh-CN.md +8 -0
  131. package/templates/.claude/commands/refine-title.md +8 -0
  132. package/templates/.claude/commands/refine-title.zh-CN.md +8 -0
  133. package/templates/.claude/commands/release.md +8 -0
  134. package/templates/.claude/commands/release.zh-CN.md +8 -0
  135. package/templates/.claude/commands/review-task.md +8 -0
  136. package/templates/.claude/commands/review-task.zh-CN.md +8 -0
  137. package/templates/.claude/commands/sync-issue.md +8 -0
  138. package/templates/.claude/commands/sync-issue.zh-CN.md +8 -0
  139. package/templates/.claude/commands/sync-pr.md +8 -0
  140. package/templates/.claude/commands/sync-pr.zh-CN.md +8 -0
  141. package/templates/.claude/commands/test-integration.md +7 -0
  142. package/templates/.claude/commands/test-integration.zh-CN.md +7 -0
  143. package/templates/.claude/commands/test.md +7 -0
  144. package/templates/.claude/commands/test.zh-CN.md +7 -0
  145. package/templates/.claude/commands/update-agent-infra.md +7 -0
  146. package/templates/.claude/commands/update-agent-infra.zh-CN.md +7 -0
  147. package/templates/.claude/commands/upgrade-dependency.md +8 -0
  148. package/templates/.claude/commands/upgrade-dependency.zh-CN.md +8 -0
  149. package/templates/.claude/project-rules.md +65 -0
  150. package/templates/.claude/project-rules.zh-CN.md +65 -0
  151. package/templates/.claude/settings.json +20 -0
  152. package/templates/.codex/README.md +38 -0
  153. package/templates/.codex/README.zh-CN.md +37 -0
  154. package/templates/.editorconfig +15 -0
  155. package/templates/.gemini/commands/_project_/analyze-task.toml +8 -0
  156. package/templates/.gemini/commands/_project_/analyze-task.zh-CN.toml +8 -0
  157. package/templates/.gemini/commands/_project_/block-task.toml +8 -0
  158. package/templates/.gemini/commands/_project_/block-task.zh-CN.toml +8 -0
  159. package/templates/.gemini/commands/_project_/check-task.toml +8 -0
  160. package/templates/.gemini/commands/_project_/check-task.zh-CN.toml +8 -0
  161. package/templates/.gemini/commands/_project_/close-codescan.toml +8 -0
  162. package/templates/.gemini/commands/_project_/close-codescan.zh-CN.toml +8 -0
  163. package/templates/.gemini/commands/_project_/close-dependabot.toml +8 -0
  164. package/templates/.gemini/commands/_project_/close-dependabot.zh-CN.toml +8 -0
  165. package/templates/.gemini/commands/_project_/commit.toml +6 -0
  166. package/templates/.gemini/commands/_project_/commit.zh-CN.toml +6 -0
  167. package/templates/.gemini/commands/_project_/complete-task.toml +8 -0
  168. package/templates/.gemini/commands/_project_/complete-task.zh-CN.toml +8 -0
  169. package/templates/.gemini/commands/_project_/create-pr.toml +8 -0
  170. package/templates/.gemini/commands/_project_/create-pr.zh-CN.toml +8 -0
  171. package/templates/.gemini/commands/_project_/create-release-note.toml +8 -0
  172. package/templates/.gemini/commands/_project_/create-release-note.zh-CN.toml +8 -0
  173. package/templates/.gemini/commands/_project_/create-task.toml +8 -0
  174. package/templates/.gemini/commands/_project_/create-task.zh-CN.toml +8 -0
  175. package/templates/.gemini/commands/_project_/implement-task.toml +8 -0
  176. package/templates/.gemini/commands/_project_/implement-task.zh-CN.toml +8 -0
  177. package/templates/.gemini/commands/_project_/import-codescan.toml +8 -0
  178. package/templates/.gemini/commands/_project_/import-codescan.zh-CN.toml +8 -0
  179. package/templates/.gemini/commands/_project_/import-dependabot.toml +8 -0
  180. package/templates/.gemini/commands/_project_/import-dependabot.zh-CN.toml +8 -0
  181. package/templates/.gemini/commands/_project_/import-issue.toml +8 -0
  182. package/templates/.gemini/commands/_project_/import-issue.zh-CN.toml +8 -0
  183. package/templates/.gemini/commands/_project_/init-labels.toml +8 -0
  184. package/templates/.gemini/commands/_project_/init-labels.zh-CN.toml +8 -0
  185. package/templates/.gemini/commands/_project_/init-milestones.toml +10 -0
  186. package/templates/.gemini/commands/_project_/init-milestones.zh-CN.toml +10 -0
  187. package/templates/.gemini/commands/_project_/plan-task.toml +8 -0
  188. package/templates/.gemini/commands/_project_/plan-task.zh-CN.toml +8 -0
  189. package/templates/.gemini/commands/_project_/refine-task.toml +8 -0
  190. package/templates/.gemini/commands/_project_/refine-task.zh-CN.toml +8 -0
  191. package/templates/.gemini/commands/_project_/refine-title.toml +8 -0
  192. package/templates/.gemini/commands/_project_/refine-title.zh-CN.toml +8 -0
  193. package/templates/.gemini/commands/_project_/release.toml +8 -0
  194. package/templates/.gemini/commands/_project_/release.zh-CN.toml +8 -0
  195. package/templates/.gemini/commands/_project_/review-task.toml +8 -0
  196. package/templates/.gemini/commands/_project_/review-task.zh-CN.toml +8 -0
  197. package/templates/.gemini/commands/_project_/sync-issue.toml +8 -0
  198. package/templates/.gemini/commands/_project_/sync-issue.zh-CN.toml +8 -0
  199. package/templates/.gemini/commands/_project_/sync-pr.toml +8 -0
  200. package/templates/.gemini/commands/_project_/sync-pr.zh-CN.toml +8 -0
  201. package/templates/.gemini/commands/_project_/test-integration.toml +6 -0
  202. package/templates/.gemini/commands/_project_/test-integration.zh-CN.toml +6 -0
  203. package/templates/.gemini/commands/_project_/test.toml +6 -0
  204. package/templates/.gemini/commands/_project_/test.zh-CN.toml +6 -0
  205. package/templates/.gemini/commands/_project_/update-agent-infra.toml +6 -0
  206. package/templates/.gemini/commands/_project_/update-agent-infra.zh-CN.toml +6 -0
  207. package/templates/.gemini/commands/_project_/upgrade-dependency.toml +8 -0
  208. package/templates/.gemini/commands/_project_/upgrade-dependency.zh-CN.toml +8 -0
  209. package/templates/.gemini/settings.json +3 -0
  210. package/templates/.github/ISSUE_TEMPLATE/01_bug_report.yml +149 -0
  211. package/templates/.github/ISSUE_TEMPLATE/02_question.yml +101 -0
  212. package/templates/.github/ISSUE_TEMPLATE/03_feature_request.yml +131 -0
  213. package/templates/.github/ISSUE_TEMPLATE/04_documentation.yml +165 -0
  214. package/templates/.github/ISSUE_TEMPLATE/05_other.yml +147 -0
  215. package/templates/.github/ISSUE_TEMPLATE/config.yml +11 -0
  216. package/templates/.github/PULL_REQUEST_TEMPLATE.md +123 -0
  217. package/templates/.github/dependabot.yml +17 -0
  218. package/templates/.github/hooks/check-utf8-encoding.sh +25 -0
  219. package/templates/.github/release.yml +27 -0
  220. package/templates/.github/workflows/pr-title-check.yml +42 -0
  221. package/templates/.mailmap +4 -0
  222. package/templates/.opencode/COMMAND_STYLE_GUIDE.md +232 -0
  223. package/templates/.opencode/COMMAND_STYLE_GUIDE.zh-CN.md +232 -0
  224. package/templates/.opencode/README.md +76 -0
  225. package/templates/.opencode/README.zh-CN.md +77 -0
  226. package/templates/.opencode/commands/analyze-task.md +11 -0
  227. package/templates/.opencode/commands/analyze-task.zh-CN.md +11 -0
  228. package/templates/.opencode/commands/block-task.md +11 -0
  229. package/templates/.opencode/commands/block-task.zh-CN.md +11 -0
  230. package/templates/.opencode/commands/check-task.md +11 -0
  231. package/templates/.opencode/commands/check-task.zh-CN.md +11 -0
  232. package/templates/.opencode/commands/close-codescan.md +11 -0
  233. package/templates/.opencode/commands/close-codescan.zh-CN.md +11 -0
  234. package/templates/.opencode/commands/close-dependabot.md +11 -0
  235. package/templates/.opencode/commands/close-dependabot.zh-CN.md +11 -0
  236. package/templates/.opencode/commands/commit.md +9 -0
  237. package/templates/.opencode/commands/commit.zh-CN.md +9 -0
  238. package/templates/.opencode/commands/complete-task.md +11 -0
  239. package/templates/.opencode/commands/complete-task.zh-CN.md +11 -0
  240. package/templates/.opencode/commands/create-pr.md +11 -0
  241. package/templates/.opencode/commands/create-pr.zh-CN.md +11 -0
  242. package/templates/.opencode/commands/create-release-note.md +11 -0
  243. package/templates/.opencode/commands/create-release-note.zh-CN.md +11 -0
  244. package/templates/.opencode/commands/create-task.md +11 -0
  245. package/templates/.opencode/commands/create-task.zh-CN.md +11 -0
  246. package/templates/.opencode/commands/implement-task.md +11 -0
  247. package/templates/.opencode/commands/implement-task.zh-CN.md +11 -0
  248. package/templates/.opencode/commands/import-codescan.md +11 -0
  249. package/templates/.opencode/commands/import-codescan.zh-CN.md +11 -0
  250. package/templates/.opencode/commands/import-dependabot.md +11 -0
  251. package/templates/.opencode/commands/import-dependabot.zh-CN.md +11 -0
  252. package/templates/.opencode/commands/import-issue.md +11 -0
  253. package/templates/.opencode/commands/import-issue.zh-CN.md +11 -0
  254. package/templates/.opencode/commands/init-labels.md +9 -0
  255. package/templates/.opencode/commands/init-labels.zh-CN.md +9 -0
  256. package/templates/.opencode/commands/init-milestones.md +11 -0
  257. package/templates/.opencode/commands/init-milestones.zh-CN.md +11 -0
  258. package/templates/.opencode/commands/plan-task.md +11 -0
  259. package/templates/.opencode/commands/plan-task.zh-CN.md +11 -0
  260. package/templates/.opencode/commands/refine-task.md +11 -0
  261. package/templates/.opencode/commands/refine-task.zh-CN.md +11 -0
  262. package/templates/.opencode/commands/refine-title.md +11 -0
  263. package/templates/.opencode/commands/refine-title.zh-CN.md +11 -0
  264. package/templates/.opencode/commands/release.md +11 -0
  265. package/templates/.opencode/commands/release.zh-CN.md +11 -0
  266. package/templates/.opencode/commands/review-task.md +11 -0
  267. package/templates/.opencode/commands/review-task.zh-CN.md +11 -0
  268. package/templates/.opencode/commands/sync-issue.md +11 -0
  269. package/templates/.opencode/commands/sync-issue.zh-CN.md +11 -0
  270. package/templates/.opencode/commands/sync-pr.md +11 -0
  271. package/templates/.opencode/commands/sync-pr.zh-CN.md +11 -0
  272. package/templates/.opencode/commands/test-integration.md +9 -0
  273. package/templates/.opencode/commands/test-integration.zh-CN.md +9 -0
  274. package/templates/.opencode/commands/test.md +9 -0
  275. package/templates/.opencode/commands/test.zh-CN.md +9 -0
  276. package/templates/.opencode/commands/update-agent-infra.md +9 -0
  277. package/templates/.opencode/commands/update-agent-infra.zh-CN.md +9 -0
  278. package/templates/.opencode/commands/upgrade-dependency.md +11 -0
  279. package/templates/.opencode/commands/upgrade-dependency.zh-CN.md +11 -0
  280. package/templates/AGENTS.md +91 -0
  281. package/templates/AGENTS.zh-CN.md +91 -0
  282. package/templates/CONTRIBUTING.md +126 -0
  283. package/templates/CONTRIBUTING.zh-CN.md +124 -0
  284. package/templates/SECURITY.md +131 -0
  285. package/templates/SECURITY.zh-CN.md +131 -0
package/lib/log.js ADDED
@@ -0,0 +1,27 @@
1
+ const isTTY = process.stdout.isTTY;
2
+ const isTTYErr = process.stderr.isTTY;
3
+
4
+ function color(code, text, tty) {
5
+ return tty ? `\x1b[${code}m${text}\x1b[0m` : text;
6
+ }
7
+
8
+ function info(...args) {
9
+ const msg = args.join(' ');
10
+ process.stdout.write(` ${color('1;34', '>', isTTY)} ${msg}\n`);
11
+ }
12
+
13
+ function ok(...args) {
14
+ const msg = args.join(' ');
15
+ process.stdout.write(` ${color('1;32', '\u2713', isTTY)} ${msg}\n`);
16
+ }
17
+
18
+ function err(...args) {
19
+ const msg = args.join(' ');
20
+ process.stderr.write(` ${color('1;31', '\u2717', isTTYErr)} ${msg}\n`);
21
+ }
22
+
23
+ function ask(text) {
24
+ process.stdout.write(` ${color('1;33', '?', isTTY)} ${text}`);
25
+ }
26
+
27
+ export { info, ok, err, ask };
package/lib/paths.js ADDED
@@ -0,0 +1,48 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ function resolveBundledTemplateDir() {
7
+ return fileURLToPath(new URL('../templates', import.meta.url));
8
+ }
9
+
10
+ function resolveCloneTemplateDir() {
11
+ return path.join(os.homedir(), '.agent-infra', 'templates');
12
+ }
13
+
14
+ function normalizePath(targetPath) {
15
+ try {
16
+ return fs.realpathSync(targetPath);
17
+ } catch {
18
+ return path.resolve(targetPath);
19
+ }
20
+ }
21
+
22
+ function resolveTemplateDir() {
23
+ // npm install mode: templates shipped alongside the package
24
+ const npmPath = resolveBundledTemplateDir();
25
+ if (fs.existsSync(npmPath)) {
26
+ return npmPath;
27
+ }
28
+
29
+ // clone install mode: ~/.agent-infra/templates
30
+ const clonePath = resolveCloneTemplateDir();
31
+ if (fs.existsSync(clonePath)) {
32
+ return clonePath;
33
+ }
34
+
35
+ return null;
36
+ }
37
+
38
+ function resolveInstallDir() {
39
+ return path.join(os.homedir(), '.agent-infra');
40
+ }
41
+
42
+ function isCloneInstall() {
43
+ const npmPath = resolveBundledTemplateDir();
44
+ const clonePath = resolveCloneTemplateDir();
45
+ return fs.existsSync(npmPath) && normalizePath(npmPath) === normalizePath(clonePath);
46
+ }
47
+
48
+ export { resolveTemplateDir, resolveInstallDir, isCloneInstall };
package/lib/prompt.js ADDED
@@ -0,0 +1,70 @@
1
+ import readline from 'node:readline';
2
+ import { ask } from './log.js';
3
+
4
+ let _rl = null;
5
+ let _lines = [];
6
+ let _lineResolve = null;
7
+ let _stdinDone = false;
8
+
9
+ function setupInterface() {
10
+ if (_rl || _stdinDone) return;
11
+ _rl = readline.createInterface({
12
+ input: process.stdin,
13
+ terminal: false
14
+ });
15
+
16
+ _rl.on('line', (line) => {
17
+ if (_lineResolve) {
18
+ const resolve = _lineResolve;
19
+ _lineResolve = null;
20
+ resolve(line);
21
+ } else {
22
+ _lines.push(line);
23
+ }
24
+ });
25
+
26
+ _rl.on('close', () => {
27
+ _stdinDone = true;
28
+ _rl = null;
29
+ if (_lineResolve) {
30
+ const resolve = _lineResolve;
31
+ _lineResolve = null;
32
+ resolve(null);
33
+ }
34
+ });
35
+ }
36
+
37
+ function nextLine() {
38
+ return new Promise((resolve) => {
39
+ if (_lines.length > 0) {
40
+ resolve(_lines.shift());
41
+ } else if (_stdinDone) {
42
+ resolve(null);
43
+ } else {
44
+ _lineResolve = resolve;
45
+ }
46
+ });
47
+ }
48
+
49
+ async function prompt(question, defaultValue) {
50
+ const label = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
51
+ ask(label);
52
+
53
+ setupInterface();
54
+
55
+ const line = await nextLine();
56
+ if (line === null) {
57
+ return defaultValue || '';
58
+ }
59
+ return line.trim() || defaultValue || '';
60
+ }
61
+
62
+ function closePrompt() {
63
+ if (_rl) {
64
+ _rl.close();
65
+ _rl = null;
66
+ _stdinDone = true;
67
+ }
68
+ }
69
+
70
+ export { prompt, closePrompt };
package/lib/render.js ADDED
@@ -0,0 +1,99 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ function renderFile(src, dst, replacements) {
5
+ if (!fs.existsSync(src)) {
6
+ throw new Error(`Template file not found: ${src}`);
7
+ }
8
+
9
+ let content = fs.readFileSync(src, 'utf8');
10
+ content = content
11
+ .replace(/\{\{project\}\}/g, replacements.project)
12
+ .replace(/\{\{org\}\}/g, replacements.org || '');
13
+
14
+ const dir = path.dirname(dst);
15
+ fs.mkdirSync(dir, { recursive: true });
16
+ fs.writeFileSync(dst, content, 'utf8');
17
+ }
18
+
19
+ function copyFile(src, dst) {
20
+ if (!fs.existsSync(src)) {
21
+ throw new Error(`Template file not found: ${src}`);
22
+ }
23
+
24
+ const dir = path.dirname(dst);
25
+ fs.mkdirSync(dir, { recursive: true });
26
+ fs.copyFileSync(src, dst);
27
+
28
+ try {
29
+ fs.chmodSync(dst, fs.statSync(src).mode);
30
+ } catch {
31
+ // Ignore permission sync failures on unsupported filesystems.
32
+ }
33
+ }
34
+
35
+ function walkFiles(dir) {
36
+ const results = [];
37
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
38
+ const entryPath = path.join(dir, entry.name);
39
+ if (entry.isDirectory()) {
40
+ results.push(...walkFiles(entryPath));
41
+ } else {
42
+ results.push(entryPath);
43
+ }
44
+ }
45
+ return results;
46
+ }
47
+
48
+ function containsPlaceholders(src) {
49
+ const content = fs.readFileSync(src, 'utf8');
50
+ return content.includes('{{project}}') || content.includes('{{org}}');
51
+ }
52
+
53
+ function selectLocalizedFiles(srcDir, language) {
54
+ const selected = new Map();
55
+
56
+ for (const src of walkFiles(srcDir)) {
57
+ const relativePath = path.relative(srcDir, src);
58
+ if (relativePath.includes('.zh-CN.')) {
59
+ continue;
60
+ }
61
+ selected.set(relativePath, src);
62
+ }
63
+
64
+ if (language === 'zh-CN') {
65
+ for (const src of walkFiles(srcDir)) {
66
+ const relativePath = path.relative(srcDir, src);
67
+ if (!relativePath.includes('.zh-CN.')) {
68
+ continue;
69
+ }
70
+
71
+ selected.set(relativePath.replace('.zh-CN.', '.'), src);
72
+ }
73
+ }
74
+
75
+ return selected;
76
+ }
77
+
78
+ function copySkillDir(srcDir, dstDir, replacements, language) {
79
+ if (!fs.existsSync(srcDir)) {
80
+ throw new Error(`Template directory not found: ${srcDir}`);
81
+ }
82
+
83
+ for (const [relativePath, src] of selectLocalizedFiles(srcDir, language)) {
84
+ const dst = path.join(dstDir, relativePath);
85
+ if (containsPlaceholders(src)) {
86
+ renderFile(src, dst, replacements);
87
+ try {
88
+ fs.chmodSync(dst, fs.statSync(src).mode);
89
+ } catch {
90
+ // Ignore permission sync failures on unsupported filesystems.
91
+ }
92
+ continue;
93
+ }
94
+
95
+ copyFile(src, dst);
96
+ }
97
+ }
98
+
99
+ export { renderFile, copyFile, copySkillDir };
package/lib/update.js ADDED
@@ -0,0 +1,161 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { execSync } from 'node:child_process';
4
+ import { info, ok, err } from './log.js';
5
+ import { resolveTemplateDir, resolveInstallDir, isCloneInstall } from './paths.js';
6
+ import { renderFile, copySkillDir } from './render.js';
7
+
8
+ const defaults = JSON.parse(
9
+ fs.readFileSync(new URL('./defaults.json', import.meta.url), 'utf8')
10
+ );
11
+
12
+ function syncFileRegistry(config) {
13
+ const allExisting = [
14
+ ...config.files.managed,
15
+ ...config.files.merged,
16
+ ...config.files.ejected
17
+ ];
18
+ const added = { managed: [], merged: [] };
19
+
20
+ for (const entry of defaults.files.managed) {
21
+ if (!allExisting.includes(entry)) {
22
+ config.files.managed.push(entry);
23
+ added.managed.push(entry);
24
+ }
25
+ }
26
+ for (const entry of defaults.files.merged) {
27
+ if (!allExisting.includes(entry)) {
28
+ config.files.merged.push(entry);
29
+ added.merged.push(entry);
30
+ }
31
+ }
32
+
33
+ return added;
34
+ }
35
+
36
+ async function cmdUpdate() {
37
+ console.log('');
38
+ console.log(' agent-infra update');
39
+ console.log(' ==================================');
40
+ console.log('');
41
+
42
+ // check .airc.json exists
43
+ if (!fs.existsSync('.airc.json')) {
44
+ err('No .airc.json found in current directory.');
45
+ err('Run "ai init" first to initialize the project.');
46
+ process.exitCode = 1;
47
+ return;
48
+ }
49
+
50
+ // resolve templates
51
+ const templateDir = resolveTemplateDir();
52
+ if (!templateDir) {
53
+ err('Template directory not found.');
54
+ err('Install via npm: npm install -g @fitlab-ai/agent-infra');
55
+ err('Or via clone: curl -fsSL https://raw.githubusercontent.com/fitlab-ai/agent-infra/main/install.sh | sh');
56
+ process.exitCode = 1;
57
+ return;
58
+ }
59
+
60
+ // auto-update: only for clone installs
61
+ if (isCloneInstall()) {
62
+ const installDir = resolveInstallDir();
63
+ if (fs.existsSync(path.join(installDir, '.git'))) {
64
+ info('Updating templates to latest version...');
65
+ try {
66
+ execSync('git pull --rebase --quiet', { cwd: installDir, stdio: 'pipe' });
67
+ ok('Templates updated.');
68
+ } catch {
69
+ err('Failed to update templates (network issue?). Using local version.');
70
+ }
71
+ }
72
+ }
73
+
74
+ // read project config
75
+ const config = JSON.parse(fs.readFileSync('.airc.json', 'utf8'));
76
+ const { project, org, language } = config;
77
+ const replacements = { project, org };
78
+
79
+ info(`Updating seed files for: ${project}`);
80
+ console.log('');
81
+
82
+ // select language-specific template filenames
83
+ let claudeSrc, geminiSrc, opencodeSrc;
84
+ if (language === 'zh-CN') {
85
+ claudeSrc = 'update-agent-infra.zh-CN.md';
86
+ geminiSrc = 'update-agent-infra.zh-CN.toml';
87
+ opencodeSrc = 'update-agent-infra.zh-CN.md';
88
+ } else {
89
+ claudeSrc = 'update-agent-infra.md';
90
+ geminiSrc = 'update-agent-infra.toml';
91
+ opencodeSrc = 'update-agent-infra.md';
92
+ }
93
+
94
+ // update skill
95
+ copySkillDir(
96
+ path.join(templateDir, '.agents', 'skills', 'update-agent-infra'),
97
+ path.join('.agents', 'skills', 'update-agent-infra'),
98
+ replacements,
99
+ language
100
+ );
101
+ ok('Updated .agents/skills/update-agent-infra/');
102
+ try {
103
+ fs.unlinkSync(path.join('.agents', 'skills', 'update-agent-infra', 'scripts', 'sync-templates.cjs'));
104
+ } catch {
105
+ // Ignore missing legacy script from pre-ESM installs.
106
+ }
107
+
108
+ // update Claude command
109
+ renderFile(
110
+ path.join(templateDir, '.claude', 'commands', claudeSrc),
111
+ path.join('.claude', 'commands', 'update-agent-infra.md'),
112
+ replacements
113
+ );
114
+ ok('Updated .claude/commands/update-agent-infra.md');
115
+
116
+ // update Gemini command
117
+ renderFile(
118
+ path.join(templateDir, '.gemini', 'commands', '_project_', geminiSrc),
119
+ path.join('.gemini', 'commands', project, 'update-agent-infra.toml'),
120
+ replacements
121
+ );
122
+ ok(`Updated .gemini/commands/${project}/update-agent-infra.toml`);
123
+
124
+ // update OpenCode command
125
+ renderFile(
126
+ path.join(templateDir, '.opencode', 'commands', opencodeSrc),
127
+ path.join('.opencode', 'commands', 'update-agent-infra.md'),
128
+ replacements
129
+ );
130
+ ok('Updated .opencode/commands/update-agent-infra.md');
131
+
132
+ // sync file registry
133
+ const added = syncFileRegistry(config);
134
+ const hasNewEntries = added.managed.length > 0 || added.merged.length > 0;
135
+
136
+ if (hasNewEntries) {
137
+ console.log('');
138
+ info('New file entries synced to .airc.json:');
139
+ for (const entry of added.managed) {
140
+ ok(` managed: ${entry}`);
141
+ }
142
+ for (const entry of added.merged) {
143
+ ok(` merged: ${entry}`);
144
+ }
145
+ fs.writeFileSync('.airc.json', JSON.stringify(config, null, 2) + '\n', 'utf8');
146
+ ok('Updated .airc.json');
147
+ }
148
+
149
+ // done
150
+ console.log('');
151
+ ok('Seed files updated successfully!');
152
+ console.log('');
153
+ console.log(' Next step: run the full update in your AI TUI:');
154
+ console.log('');
155
+ console.log(' Claude Code / OpenCode: /update-agent-infra');
156
+ console.log(` Gemini CLI: /${project}:update-agent-infra`);
157
+ console.log(' Codex CLI: $update-agent-infra');
158
+ console.log('');
159
+ }
160
+
161
+ export { cmdUpdate };
package/lib/version.js ADDED
@@ -0,0 +1,7 @@
1
+ import { readFileSync } from 'node:fs';
2
+
3
+ const { version: VERSION } = JSON.parse(
4
+ readFileSync(new URL('../package.json', import.meta.url), 'utf8')
5
+ );
6
+
7
+ export { VERSION };
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@fitlab-ai/agent-infra",
3
+ "version": "0.3.0",
4
+ "description": "Bootstrap tool for AI multi-tool collaboration infrastructure — works with Claude Code, Codex, Gemini CLI, and OpenCode",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "author": "CodeCaster <codecaster365@outlook.com>",
8
+ "homepage": "https://github.com/fitlab-ai/agent-infra#readme",
9
+ "bugs": {
10
+ "url": "https://github.com/fitlab-ai/agent-infra/issues"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/fitlab-ai/agent-infra.git"
15
+ },
16
+ "publishConfig": {
17
+ "access": "public",
18
+ "registry": "https://registry.npmjs.org/"
19
+ },
20
+ "bin": {
21
+ "agent-infra": "./bin/cli.js",
22
+ "ai": "./bin/cli.js"
23
+ },
24
+ "files": [
25
+ "bin/cli.js",
26
+ "lib/",
27
+ "templates/"
28
+ ],
29
+ "engines": {
30
+ "node": ">=18"
31
+ },
32
+ "keywords": [
33
+ "ai",
34
+ "collaboration",
35
+ "claude-code",
36
+ "codex",
37
+ "gemini",
38
+ "opencode",
39
+ "cli",
40
+ "bootstrap",
41
+ "installer"
42
+ ],
43
+ "scripts": {
44
+ "build": "node scripts/build-inline.js",
45
+ "test": "node scripts/build-inline.js --check && node --test tests/*.test.js",
46
+ "prepublishOnly": "node scripts/build-inline.js --check && node --test tests/*.test.js"
47
+ }
48
+ }
@@ -0,0 +1,26 @@
1
+ # AI Workspace
2
+
3
+ This directory is the runtime workspace for multi-AI collaboration. All contents are **git-ignored** except for this README and `.gitkeep` files.
4
+
5
+ ## Directory Structure
6
+
7
+ ```
8
+ .agent-workspace/
9
+ active/ # Currently active tasks and handoff documents
10
+ blocked/ # Tasks that are blocked and waiting for resolution
11
+ completed/ # Completed tasks (kept for reference)
12
+ logs/ # Collaboration logs and session records
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ - **active/**: Place task files here when work begins. Move them to `completed/` or `blocked/` as appropriate.
18
+ - **blocked/**: Move tasks here when they cannot proceed. Document the blocker in the task file.
19
+ - **completed/**: Move tasks here when they are done. These serve as a historical record.
20
+ - **logs/**: Store session logs, AI conversation exports, or collaboration notes.
21
+
22
+ ## Important
23
+
24
+ - Contents of this directory are **not version-controlled** (git-ignored).
25
+ - Do not store anything here that needs to be shared via git.
26
+ - Templates and workflow definitions belong in `.agents/`, not here.
@@ -0,0 +1,26 @@
1
+ # AI 工作区
2
+
3
+ 本目录是多 AI 协作的运行时工作区。除本 README 和 `.gitkeep` 文件外,所有内容均被 **git ignore**。
4
+
5
+ ## 目录结构
6
+
7
+ ```
8
+ .agent-workspace/
9
+ active/ # 当前活跃的任务和交接文档
10
+ blocked/ # 被阻塞的任务,等待解决
11
+ completed/ # 已完成的任务(保留供参考)
12
+ logs/ # 协作日志和会话记录
13
+ ```
14
+
15
+ ## 使用方法
16
+
17
+ - **active/**:工作开始时将任务文件放在这里。根据情况将其移至 `completed/` 或 `blocked/`。
18
+ - **blocked/**:当任务无法继续时将其移至此处。在任务文件中记录阻塞原因。
19
+ - **completed/**:任务完成后将其移至此处。这些作为历史记录保留。
20
+ - **logs/**:存储会话日志、AI 对话导出或协作笔记。
21
+
22
+ ## 重要事项
23
+
24
+ - 本目录的内容**不受版本控制**(已被 git ignore)。
25
+ - 不要在这里存储需要通过 git 共享的内容。
26
+ - 模板和工作流定义属于 `.agents/` 目录,而非此处。
@@ -0,0 +1,166 @@
1
+ # Quick Start: Multi-AI Collaboration
2
+
3
+ This guide walks you through using multiple AI coding assistants together on a project.
4
+
5
+ ## Prerequisites
6
+
7
+ - At least one AI coding tool installed (Claude Code, Codex CLI, Gemini CLI, or Cursor)
8
+ - A project with `.agents/` directory set up (this project)
9
+ - Familiarity with your project's codebase
10
+
11
+ ## Creating Your First Task
12
+
13
+ 1. Copy the task template to the active workspace:
14
+
15
+ ```bash
16
+ cp .agents/templates/task.md .agent-workspace/active/task-001.md
17
+ ```
18
+
19
+ 2. Fill in the task metadata:
20
+
21
+ ```yaml
22
+ id: task-001
23
+ type: feature # feature | bugfix | refactor | docs | review
24
+ status: open # open | in-progress | review | blocked | completed
25
+ assigned_to: claude # claude | codex | gemini | cursor | human
26
+ ```
27
+
28
+ 3. Describe the task in the body of the document.
29
+
30
+ ## Using Different AIs for Different Phases
31
+
32
+ ### Phase 1: Analysis (Recommended: Claude Code)
33
+
34
+ ```bash
35
+ # Start Claude Code and ask it to analyze the task
36
+ claude
37
+
38
+ # Example prompt:
39
+ # "Analyze task-001. Explore the codebase and identify all files
40
+ # that need to change. Update the task with your findings."
41
+ ```
42
+
43
+ Claude Code excels at codebase exploration and understanding complex relationships between files.
44
+
45
+ ### Phase 2: Design (Recommended: Claude Code or Gemini CLI)
46
+
47
+ ```bash
48
+ # Continue with Claude Code or switch to Gemini CLI for large codebases
49
+ gemini
50
+
51
+ # Example prompt:
52
+ # "Based on the analysis in .agent-workspace/active/task-001.md,
53
+ # create a technical design. Define interfaces and outline the approach."
54
+ ```
55
+
56
+ ### Phase 3: Implementation (Recommended: Codex CLI or Cursor)
57
+
58
+ ```bash
59
+ # Switch to Codex CLI for implementation
60
+ codex
61
+
62
+ # Example prompt:
63
+ # "Implement the changes described in .agent-workspace/active/task-001.md.
64
+ # Follow the design section. Create a new branch for this work."
65
+ ```
66
+
67
+ ### Phase 4: Review (Recommended: Claude Code)
68
+
69
+ ```bash
70
+ # Switch back to Claude Code for review
71
+ claude
72
+
73
+ # Example prompt:
74
+ # "Review the implementation on branch feature-xxx.
75
+ # Check for correctness, style, and best practices.
76
+ # Create a review report."
77
+ ```
78
+
79
+ ## Common Scenarios
80
+
81
+ ### Bug Fix
82
+
83
+ 1. **Reproduce & Analyze** (Claude Code): Identify the root cause.
84
+ 2. **Implement Fix** (Codex CLI / Cursor): Write the fix and tests.
85
+ 3. **Review** (Claude Code): Verify the fix is correct and complete.
86
+ 4. **Commit**: Create PR with bug fix description.
87
+
88
+ ```bash
89
+ # Quick bug fix workflow
90
+ cp .agents/templates/task.md .agent-workspace/active/bugfix-001.md
91
+ # Edit the task, then:
92
+ # 1. Use Claude Code to analyze
93
+ # 2. Use Codex/Cursor to fix
94
+ # 3. Use Claude Code to review
95
+ ```
96
+
97
+ ### Code Review
98
+
99
+ 1. **Load Context** (Claude Code): Read the PR diff and related files.
100
+ 2. **Review** (Claude Code): Check logic, style, tests, and edge cases.
101
+ 3. **Report**: Generate review report from template.
102
+
103
+ ```bash
104
+ cp .agents/templates/review-report.md .agent-workspace/active/review-pr-42.md
105
+ # Use Claude Code to fill in the review
106
+ ```
107
+
108
+ ### Refactoring
109
+
110
+ 1. **Analyze Scope** (Claude Code / Gemini CLI): Map all affected areas.
111
+ 2. **Design** (Claude Code): Plan the refactoring approach.
112
+ 3. **Implement** (Codex CLI / Cursor): Execute the refactoring.
113
+ 4. **Verify** (Claude Code): Ensure no regressions, run tests.
114
+
115
+ ```bash
116
+ cp .agents/templates/task.md .agent-workspace/active/refactor-001.md
117
+ # Follow the refactoring workflow in .agents/workflows/refactoring.yaml
118
+ ```
119
+
120
+ ## Creating Handoff Documents
121
+
122
+ When switching between AI tools, create a handoff document:
123
+
124
+ ```bash
125
+ cp .agents/templates/handoff.md .agent-workspace/active/handoff-task-001-phase2.md
126
+ ```
127
+
128
+ Fill in:
129
+ - What was completed
130
+ - Current state of the code
131
+ - What needs to happen next
132
+ - Any blockers or concerns
133
+
134
+ The receiving AI should read this document first to get up to speed.
135
+
136
+ ## Best Practices
137
+
138
+ ### 1. One AI Per Phase
139
+
140
+ Don't have multiple AIs working on the same files simultaneously. Follow the sequential workflow: analyze, design, implement, review, fix, commit.
141
+
142
+ ### 2. Always Create Handoff Documents
143
+
144
+ Even if you're switching between AIs quickly, a brief handoff note saves time and prevents context loss.
145
+
146
+ ### 3. Use the Right Tool for the Job
147
+
148
+ - Complex analysis? Use Claude Code or Gemini CLI.
149
+ - Straightforward implementation? Use Codex CLI or Cursor.
150
+ - Large file review? Use Gemini CLI.
151
+
152
+ ### 4. Keep Tasks Small
153
+
154
+ Break large tasks into smaller, well-defined subtasks. Each subtask should be completable in a single AI session.
155
+
156
+ ### 5. Version Control Your Progress
157
+
158
+ Commit frequently. Each phase completion is a good commit point. This makes it easy to roll back if needed.
159
+
160
+ ### 6. Update Task Status
161
+
162
+ Always update the task's `status`, `current_step`, and `assigned_to` fields when transitioning between phases.
163
+
164
+ ### 7. Review AI Output
165
+
166
+ Always review what an AI produces before committing. AI tools are assistants, not autonomous agents.