@neyugn/agent-kits 0.2.8 → 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/README.md CHANGED
@@ -68,7 +68,7 @@ npx @neyugn/agent-kits
68
68
  ```
69
69
 
70
70
  ```
71
- ╭──────────────────────────────────────────────────────────────────────────╮
71
+ ╭──────────────────────────────────────────────────────────────────────────────╮
72
72
  │ │
73
73
  │ _ ____ _____ _ _ _____ _ __ ___ _____ ____ │
74
74
  │ / \ / ___|| ____|| \ | ||_ _| | |/ /|_ _||_ _|/ ___| │
@@ -78,15 +78,13 @@ npx @neyugn/agent-kits
78
78
  │ │
79
79
  │ ⚡ The Universal AI Agent Toolkit ⚡ │
80
80
  │ │
81
- ╰──────────────────────────────────────────────────────────────────────────╯
81
+ ╰──────────────────────────────────────────────────────────────────────────────╯
82
82
 
83
83
  SETUP WIZARD
84
84
 
85
85
  ◆ 🤖 Which AI assistant are you using?
86
- Claude Code (.claude/)
87
- │ ● Gemini CLI (.gemini/)
86
+ Antigravity (.agent/)
88
87
  │ ○ Cursor (.cursor/)
89
- │ ○ Custom...
90
88
 
91
89
  ◆ 📂 Where should we install?
92
90
  │ ● Workspace (Project)
@@ -123,16 +121,16 @@ If the installer detects an existing installation, you'll be prompted:
123
121
 
124
122
  ### 🔌 Universal Compatibility
125
123
 
126
- | Tool | Workspace Path | Global Path | Status |
127
- | ----------- | ----------------- | ------------ | --------------- |
128
- | Cursor | `.cursor/skills/` | `~/.cursor/` | ✅ Verified |
129
- | Antigravity | `.agent/skills/` | `~/.agent/` | ✅ Verified |
130
- | Claude Code | `.claude/skills/` | `~/.claude/` | 🧪 Experimental |
131
- | Gemini CLI | `.gemini/skills/` | `~/.gemini/` | 🧪 Experimental |
132
- | Codex CLI | `.codex/skills/` | `~/.codex/` | 🧪 Experimental |
133
- | Custom | Configurable | `~/.ai/` | 🧪 Experimental |
124
+ | Tool | Workspace Path | Global Path | Status |
125
+ | ----------- | ----------------- | ------------ | ------------------ |
126
+ | Antigravity | `.agent/skills/` | `~/.agent/` | ✅ Fully Supported |
127
+ | Cursor | `.cursor/skills/` | `~/.cursor/` | ✅ Fully Supported |
128
+ | Claude Code | `.claude/skills/` | `~/.claude/` | 🔜 Coming Soon |
129
+ | Gemini CLI | `.gemini/skills/` | `~/.gemini/` | 🔜 Coming Soon |
130
+ | Codex CLI | `.codex/skills/` | `~/.codex/` | 🔜 Coming Soon |
131
+ | Custom | Configurable | `~/.ai/` | 🔜 Coming Soon |
134
132
 
135
- > **Note:** Tools marked as 🧪 Experimental have not been fully tested and may require additional user configuration. Contributions and feedback are welcome!
133
+ > **Note:** Tools marked as 🔜 Coming Soon are planned for future releases. The infrastructure is ready, but these tools require additional testing and configuration.
136
134
 
137
135
  ### 💻 Cross-Platform Support
138
136
 
package/README.vi.md CHANGED
@@ -60,7 +60,7 @@ npx @neyugn/agent-kits
60
60
  ```
61
61
 
62
62
  ```
63
- ╭──────────────────────────────────────────────────────────────────────────╮
63
+ ╭──────────────────────────────────────────────────────────────────────────────╮
64
64
  │ │
65
65
  │ _ ____ _____ _ _ _____ _ __ ___ _____ ____ │
66
66
  │ / \ / ___|| ____|| \ | ||_ _| | |/ /|_ _||_ _|/ ___| │
@@ -70,15 +70,13 @@ npx @neyugn/agent-kits
70
70
  │ │
71
71
  │ ⚡ The Universal AI Agent Toolkit ⚡ │
72
72
  │ │
73
- ╰──────────────────────────────────────────────────────────────────────────╯
73
+ ╯──────────────────────────────────────────────────────────────────────────────╯
74
74
 
75
75
  SETUP WIZARD
76
76
 
77
77
  ◆ 🤖 Bạn đang sử dụng công cụ AI nào?
78
- Claude Code (.claude/)
79
- │ ● Gemini CLI (.gemini/)
78
+ Antigravity (.agent/)
80
79
  │ ○ Cursor (.cursor/)
81
- │ ○ Tùy chỉnh...
82
80
 
83
81
  ◆ 📂 Bạn muốn cài đặt ở đâu?
84
82
  │ ● Workspace (Dự án hiện tại)
@@ -115,16 +113,16 @@ Nếu installer phát hiện cài đặt đã tồn tại, bạn sẽ được h
115
113
 
116
114
  ### 🔌 Tương thích phổ quát
117
115
 
118
- | Công cụ | Đường dẫn Workspace | Đường dẫn Global | Trạng thái |
119
- | ----------- | ------------------- | ---------------- | -------------- |
120
- | Cursor | `.cursor/skills/` | `~/.cursor/` | ✅ Đã xác nhận |
121
- | Antigravity | `.agent/skills/` | `~/.agent/` | ✅ Đã xác nhận |
122
- | Claude Code | `.claude/skills/` | `~/.claude/` | 🧪 Thực nghiệm |
123
- | Gemini CLI | `.gemini/skills/` | `~/.gemini/` | 🧪 Thực nghiệm |
124
- | Codex CLI | `.codex/skills/` | `~/.codex/` | 🧪 Thực nghiệm |
125
- | Tùy chỉnh | Có thể cấu hình | `~/.ai/` | 🧪 Thực nghiệm |
116
+ | Công cụ | Đường dẫn Workspace | Đường dẫn Global | Trạng thái |
117
+ | ----------- | ------------------- | ---------------- | ---------------- |
118
+ | Antigravity | `.agent/skills/` | `~/.agent/` | ✅ Hỗ trợ đầy đủ |
119
+ | Cursor | `.cursor/skills/` | `~/.cursor/` | ✅ Hỗ trợ đầy đủ |
120
+ | Claude Code | `.claude/skills/` | `~/.claude/` | 🔜 Sắp ra mắt |
121
+ | Gemini CLI | `.gemini/skills/` | `~/.gemini/` | 🔜 Sắp ra mắt |
122
+ | Codex CLI | `.codex/skills/` | `~/.codex/` | 🔜 Sắp ra mắt |
123
+ | Tùy chỉnh | Có thể cấu hình | `~/.ai/` | 🔜 Sắp ra mắt |
126
124
 
127
- > **Lưu ý:** Các công cụ đánh dấu 🧪 Thực nghiệm chưa được kiểm tra đầy đủ thể cần người dùng tùy chỉnh thêm. Đóng góp phản hồi luôn được hoan nghênh!
125
+ > **Lưu ý:** Các công cụ đánh dấu 🔜 Sắp ra mắt đang được lên kế hoạch cho các phiên bản tương lai. Hạ tầng đã sẵn sàng, nhưng các công cụ này cần thêm kiểm tra và cấu hình.
128
126
 
129
127
  ### 💻 Hỗ trợ đa nền tảng
130
128
 
package/README.zh.md CHANGED
@@ -60,7 +60,7 @@ npx @neyugn/agent-kits
60
60
  ```
61
61
 
62
62
  ```
63
- ╭──────────────────────────────────────────────────────────────────────────╮
63
+ ╭──────────────────────────────────────────────────────────────────────────────╮
64
64
  │ │
65
65
  │ _ ____ _____ _ _ _____ _ __ ___ _____ ____ │
66
66
  │ / \ / ___|| ____|| \ | ||_ _| | |/ /|_ _||_ _|/ ___| │
@@ -70,15 +70,13 @@ npx @neyugn/agent-kits
70
70
  │ │
71
71
  │ ⚡ The Universal AI Agent Toolkit ⚡ │
72
72
  │ │
73
- ╰──────────────────────────────────────────────────────────────────────────╯
73
+ ╯──────────────────────────────────────────────────────────────────────────────╯
74
74
 
75
75
  SETUP WIZARD
76
76
 
77
77
  ◆ 🤖 您正在使用哪个 AI 工具?
78
- Claude Code (.claude/)
79
- │ ● Gemini CLI (.gemini/)
78
+ Antigravity (.agent/)
80
79
  │ ○ Cursor (.cursor/)
81
- │ ○ 自定义...
82
80
 
83
81
  ◆ 📂 您想安装在哪里?
84
82
  │ ● Workspace(当前项目)
@@ -115,16 +113,16 @@ npx @neyugn/agent-kits
115
113
 
116
114
  ### 🔌 通用兼容性
117
115
 
118
- | 工具 | Workspace 路径 | Global 路径 | 状态 |
119
- | ----------- | ----------------- | ------------ | --------- |
120
- | Cursor | `.cursor/skills/` | `~/.cursor/` | ✅ 已验证 |
121
- | Antigravity | `.agent/skills/` | `~/.agent/` | ✅ 已验证 |
122
- | Claude Code | `.claude/skills/` | `~/.claude/` | 🧪 实验性 |
123
- | Gemini CLI | `.gemini/skills/` | `~/.gemini/` | 🧪 实验性 |
124
- | Codex CLI | `.codex/skills/` | `~/.codex/` | 🧪 实验性 |
125
- | 自定义 | 可配置 | `~/.ai/` | 🧪 实验性 |
116
+ | 工具 | Workspace 路径 | Global 路径 | 状态 |
117
+ | ----------- | ----------------- | ------------ | ----------- |
118
+ | Antigravity | `.agent/skills/` | `~/.agent/` | ✅ 完全支持 |
119
+ | Cursor | `.cursor/skills/` | `~/.cursor/` | ✅ 完全支持 |
120
+ | Claude Code | `.claude/skills/` | `~/.claude/` | 🔜 即将推出 |
121
+ | Gemini CLI | `.gemini/skills/` | `~/.gemini/` | 🔜 即将推出 |
122
+ | Codex CLI | `.codex/skills/` | `~/.codex/` | 🔜 即将推出 |
123
+ | 自定义 | 可配置 | `~/.ai/` | 🔜 即将推出 |
126
124
 
127
- > **注意:** 标记为 🧪 实验性的工具尚未完全测试,可能需要用户进行额外配置。欢迎贡献和反馈!
125
+ > **注意:** 标记为 🔜 即将推出的工具已纳入未来版本计划。基础架构已就绪,但这些工具需要额外的测试和配置。
128
126
 
129
127
  ### 💻 跨平台支持
130
128
 
package/dist/cli.js CHANGED
@@ -4,10 +4,10 @@
4
4
  import * as p from "@clack/prompts";
5
5
  import boxen from "boxen";
6
6
  import figlet from "figlet";
7
- import fs2 from "fs";
7
+ import fs4 from "fs";
8
8
  import gradient from "gradient-string";
9
9
  import os2 from "os";
10
- import path3 from "path";
10
+ import path5 from "path";
11
11
  import pc from "picocolors";
12
12
 
13
13
  // src/config.ts
@@ -33,8 +33,10 @@ var AI_TOOLS = [
33
33
  // Resolved to home dir at runtime
34
34
  rulesFile: "CLAUDE.md",
35
35
  kitRulesFile: "CLAUDE.md",
36
- rulesInsideKit: true
36
+ rulesInsideKit: true,
37
37
  // Claude reads from .claude/CLAUDE.md (2025 standard)
38
+ available: false
39
+ // Coming soon
38
40
  },
39
41
  {
40
42
  id: "gemini",
@@ -44,8 +46,10 @@ var AI_TOOLS = [
44
46
  globalPathPattern: "~/.gemini",
45
47
  rulesFile: "GEMINI.md",
46
48
  kitRulesFile: "GEMINI.md",
47
- rulesInsideKit: true
49
+ rulesInsideKit: true,
48
50
  // Gemini reads from .gemini/GEMINI.md
51
+ available: false
52
+ // Coming soon
49
53
  },
50
54
  {
51
55
  id: "codex",
@@ -55,8 +59,10 @@ var AI_TOOLS = [
55
59
  globalPathPattern: "~/.codex",
56
60
  rulesFile: "AGENTS.md",
57
61
  kitRulesFile: "AGENTS.md",
58
- rulesInsideKit: true
62
+ rulesInsideKit: true,
59
63
  // Codex reads from .codex/AGENTS.md
64
+ available: false
65
+ // Coming soon
60
66
  },
61
67
  {
62
68
  id: "antigravity",
@@ -66,21 +72,25 @@ var AI_TOOLS = [
66
72
  globalPathPattern: "~/.agent",
67
73
  rulesFile: "GEMINI.md",
68
74
  kitRulesFile: "GEMINI.md",
69
- rulesInsideKit: true
75
+ rulesInsideKit: true,
70
76
  // Antigravity reads GEMINI.md from inside .agent/
77
+ available: true
71
78
  },
72
79
  {
73
80
  id: "cursor",
74
81
  name: "Cursor",
75
82
  icon: "\u26AA",
76
- path: ".cursor/rules",
77
- // Modern path: .cursor/rules/ (2025 standard)
78
- globalPathPattern: "~/.cursor/rules",
79
- rulesFile: "rules.md",
83
+ path: ".cursor",
84
+ // Base path for Cursor (contains rules/ and commands/)
85
+ globalPathPattern: "~/.cursor",
86
+ rulesFile: "rules/rules.md",
80
87
  // Modern: .cursor/rules/rules.md instead of .cursorrules
81
88
  kitRulesFile: "CURSOR.md",
82
89
  // Source file in kit
83
- rulesInsideKit: true
90
+ rulesInsideKit: true,
91
+ workflowsAs: "commands",
92
+ // Cursor calls workflows "commands" in .cursor/commands/
93
+ available: true
84
94
  },
85
95
  {
86
96
  id: "custom",
@@ -89,8 +99,10 @@ var AI_TOOLS = [
89
99
  path: ".ai",
90
100
  globalPathPattern: "~/.ai",
91
101
  rulesFile: "RULES.md",
92
- kitRulesFile: "GEMINI.md"
102
+ kitRulesFile: "GEMINI.md",
93
103
  // Use GEMINI.md as base for custom
104
+ available: false
105
+ // Coming soon
94
106
  }
95
107
  ];
96
108
  var KITS = [
@@ -136,81 +148,24 @@ var KITS = [
136
148
  }
137
149
  ];
138
150
 
139
- // src/installers/index.ts
151
+ // src/installers/antigravity.ts
152
+ import fs2 from "fs/promises";
153
+ import path3 from "path";
154
+
155
+ // src/installers/base.ts
140
156
  import fs from "fs/promises";
141
157
  import path2 from "path";
142
158
  import { fileURLToPath } from "url";
143
159
  var __dirname = path2.dirname(fileURLToPath(import.meta.url));
144
160
  var KITS_DIR = path2.resolve(__dirname, "../kits");
145
161
  var COMMON_DIR = path2.resolve(__dirname, "../common");
146
- async function installKit(options) {
147
- const { aiTool, kits, targetPath } = options;
148
- const results = [];
149
- for (const kitId of kits) {
150
- const kit = KITS.find((k) => k.id === kitId);
151
- if (!kit || !kit.available) {
152
- throw new Error(`Kit "${kitId}" is not available`);
153
- }
154
- const kitSourcePath = path2.join(KITS_DIR, kitId);
155
- const kitTargetPath = path2.join(targetPath, aiTool.path);
156
- await fs.mkdir(kitTargetPath, { recursive: true });
157
- await copyDirectory(kitSourcePath, kitTargetPath, ["rules"], aiTool.path);
158
- const rulesSource = path2.join(kitSourcePath, "rules", aiTool.kitRulesFile);
159
- const rulesTarget = options.scope === "global" || aiTool.rulesInsideKit ? path2.join(kitTargetPath, aiTool.rulesFile) : path2.join(targetPath, aiTool.rulesFile);
160
- try {
161
- let rulesContent = await fs.readFile(rulesSource, "utf-8");
162
- rulesContent = rulesContent.replace(
163
- /\.(agent|claude|gemini|cursor|codex)\//g,
164
- `${aiTool.path}/`
165
- );
166
- await fs.writeFile(rulesTarget, rulesContent);
167
- } catch {
168
- try {
169
- const fallbackSource = path2.join(kitSourcePath, "rules", "GEMINI.md");
170
- let rulesContent = await fs.readFile(fallbackSource, "utf-8");
171
- rulesContent = rulesContent.replace(
172
- /\.(agent|claude|gemini|cursor|codex)\//g,
173
- `${aiTool.path}/`
174
- );
175
- await fs.writeFile(rulesTarget, rulesContent);
176
- } catch {
177
- }
178
- }
179
- try {
180
- const commonSkillsPath = path2.join(COMMON_DIR, "skills");
181
- const commonWorkflowsPath = path2.join(COMMON_DIR, "workflows");
182
- const commonDocPath = path2.join(COMMON_DIR, "COMMON.md");
183
- const targetSkillsPath = path2.join(kitTargetPath, "skills");
184
- await fs.mkdir(targetSkillsPath, { recursive: true });
185
- await copyDirectory(commonSkillsPath, targetSkillsPath, [], aiTool.path);
186
- const targetWorkflowsPath = path2.join(kitTargetPath, "workflows");
187
- await fs.mkdir(targetWorkflowsPath, { recursive: true });
188
- await copyDirectory(
189
- commonWorkflowsPath,
190
- targetWorkflowsPath,
191
- [],
192
- aiTool.path
193
- );
194
- const targetCommonDoc = path2.join(kitTargetPath, "COMMON.md");
195
- const commonContent = await fs.readFile(commonDocPath, "utf-8");
196
- const updatedCommonContent = commonContent.replace(
197
- /\.(agent|claude|gemini|cursor|codex)\//g,
198
- `${aiTool.path}/`
199
- );
200
- await fs.writeFile(targetCommonDoc, updatedCommonContent);
201
- } catch {
202
- }
203
- const agents = await countItems(path2.join(kitTargetPath, "agents"));
204
- const skills = await countItems(path2.join(kitTargetPath, "skills"));
205
- const workflows = await countItems(path2.join(kitTargetPath, "workflows"));
206
- results.push({
207
- kit: kit.name,
208
- agents,
209
- skills,
210
- workflows
211
- });
162
+ function getKitSource(kitId) {
163
+ const kit = KITS.find((k) => k.id === kitId);
164
+ if (!kit || !kit.available) {
165
+ throw new Error(`Kit "${kitId}" is not available`);
212
166
  }
213
- return results;
167
+ const kitSourcePath = path2.join(KITS_DIR, kitId);
168
+ return { kitSourcePath, kit };
214
169
  }
215
170
  function replaceToolPaths(content, targetPath) {
216
171
  return content.replace(
@@ -250,17 +205,485 @@ async function countItems(dirPath) {
250
205
  return 0;
251
206
  }
252
207
  }
208
+ async function copyRulesFile(kitSourcePath, kitTargetPath, targetPath, aiTool, scope, workflowsReplacement) {
209
+ const rulesSource = path2.join(kitSourcePath, "rules", aiTool.kitRulesFile);
210
+ const rulesTarget = scope === "global" || aiTool.rulesInsideKit ? path2.join(kitTargetPath, aiTool.rulesFile) : path2.join(targetPath, aiTool.rulesFile);
211
+ await fs.mkdir(path2.dirname(rulesTarget), { recursive: true });
212
+ try {
213
+ let rulesContent = await fs.readFile(rulesSource, "utf-8");
214
+ rulesContent = replaceToolPaths(rulesContent, aiTool.path);
215
+ if (workflowsReplacement) {
216
+ rulesContent = rulesContent.replace(
217
+ /workflows\//g,
218
+ `${workflowsReplacement}/`
219
+ );
220
+ }
221
+ await fs.writeFile(rulesTarget, rulesContent);
222
+ } catch {
223
+ try {
224
+ const fallbackSource = path2.join(kitSourcePath, "rules", "GEMINI.md");
225
+ let rulesContent = await fs.readFile(fallbackSource, "utf-8");
226
+ rulesContent = replaceToolPaths(rulesContent, aiTool.path);
227
+ if (workflowsReplacement) {
228
+ rulesContent = rulesContent.replace(
229
+ /workflows\//g,
230
+ `${workflowsReplacement}/`
231
+ );
232
+ }
233
+ await fs.writeFile(rulesTarget, rulesContent);
234
+ } catch {
235
+ }
236
+ }
237
+ }
238
+ async function copyCommonAssets(kitTargetPath, aiTool, workflowsFolderName = "workflows") {
239
+ const commonSkillsPath = path2.join(COMMON_DIR, "skills");
240
+ const commonWorkflowsPath = path2.join(COMMON_DIR, "workflows");
241
+ const commonDocPath = path2.join(COMMON_DIR, "COMMON.md");
242
+ const targetSkillsPath = path2.join(kitTargetPath, "skills");
243
+ await fs.mkdir(targetSkillsPath, { recursive: true });
244
+ await copyDirectory(commonSkillsPath, targetSkillsPath, [], aiTool.path);
245
+ const targetWorkflowsPath = path2.join(kitTargetPath, workflowsFolderName);
246
+ await fs.mkdir(targetWorkflowsPath, { recursive: true });
247
+ await copyDirectory(
248
+ commonWorkflowsPath,
249
+ targetWorkflowsPath,
250
+ [],
251
+ aiTool.path
252
+ );
253
+ const targetCommonDoc = path2.join(kitTargetPath, "COMMON.md");
254
+ const commonContent = await fs.readFile(commonDocPath, "utf-8");
255
+ const updatedCommonContent = replaceToolPaths(commonContent, aiTool.path);
256
+ await fs.writeFile(targetCommonDoc, updatedCommonContent);
257
+ }
258
+
259
+ // src/installers/antigravity.ts
260
+ var AntigravityInstaller = class {
261
+ async install(options) {
262
+ const { aiTool, kits, targetPath } = options;
263
+ const results = [];
264
+ for (const kitId of kits) {
265
+ const { kitSourcePath, kit } = getKitSource(kitId);
266
+ const kitTargetPath = path3.join(targetPath, aiTool.path);
267
+ await fs2.mkdir(kitTargetPath, { recursive: true });
268
+ await copyDirectory(kitSourcePath, kitTargetPath, ["rules"], aiTool.path);
269
+ await copyRulesFile(
270
+ kitSourcePath,
271
+ kitTargetPath,
272
+ targetPath,
273
+ aiTool,
274
+ options.scope
275
+ );
276
+ try {
277
+ await copyCommonAssets(kitTargetPath, aiTool, "workflows");
278
+ } catch {
279
+ }
280
+ const agents = await countItems(path3.join(kitTargetPath, "agents"));
281
+ const skills = await countItems(path3.join(kitTargetPath, "skills"));
282
+ const workflows = await countItems(path3.join(kitTargetPath, "workflows"));
283
+ results.push({
284
+ kit: kit.name,
285
+ agents,
286
+ skills,
287
+ workflows
288
+ });
289
+ }
290
+ return results;
291
+ }
292
+ };
293
+
294
+ // src/installers/cursor.ts
295
+ import fs3 from "fs/promises";
296
+ import path4 from "path";
297
+
298
+ // src/transformers/utils.ts
299
+ function parseFrontmatter(content) {
300
+ const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;
301
+ const match = content.match(frontmatterRegex);
302
+ if (!match) {
303
+ return {
304
+ data: {},
305
+ content,
306
+ raw: ""
307
+ };
308
+ }
309
+ const rawFrontmatter = match[1];
310
+ const bodyContent = match[2];
311
+ const data = {};
312
+ const lines = rawFrontmatter.split("\n");
313
+ for (const line of lines) {
314
+ const colonIndex = line.indexOf(":");
315
+ if (colonIndex === -1) continue;
316
+ const key = line.slice(0, colonIndex).trim();
317
+ let value = line.slice(colonIndex + 1).trim();
318
+ if (value === "true") value = true;
319
+ else if (value === "false") value = false;
320
+ else if (!isNaN(Number(value)) && value !== "") value = Number(value);
321
+ if (key) {
322
+ data[key] = value;
323
+ }
324
+ }
325
+ return {
326
+ data,
327
+ content: bodyContent,
328
+ raw: rawFrontmatter
329
+ };
330
+ }
331
+ function serializeFrontmatter(data) {
332
+ const lines = ["---"];
333
+ for (const [key, value] of Object.entries(data)) {
334
+ if (value === void 0 || value === null) continue;
335
+ lines.push(`${key}: ${value}`);
336
+ }
337
+ lines.push("---");
338
+ return lines.join("\n");
339
+ }
340
+ function combineMarkdown(frontmatter, content) {
341
+ return `${frontmatter}
342
+ ${content}`;
343
+ }
344
+
345
+ // src/transformers/cursor-agent.ts
346
+ var CursorAgentTransformer = class {
347
+ /**
348
+ * Transform agent content from Agent-Kits format to Cursor subagent format
349
+ */
350
+ transform(content, context) {
351
+ const parsed = parseFrontmatter(content);
352
+ const originalData = parsed.data;
353
+ const skillsString = originalData.skills;
354
+ const skills = skillsString ? skillsString.split(",").map((s) => s.trim()) : [];
355
+ const cursorFrontmatter = {
356
+ name: originalData.name,
357
+ description: originalData.description,
358
+ model: originalData.model || "inherit",
359
+ readonly: false,
360
+ is_background: false
361
+ };
362
+ const newFrontmatter = serializeFrontmatter(
363
+ cursorFrontmatter
364
+ );
365
+ let skillsSection = "";
366
+ if (skills.length > 0) {
367
+ skillsSection = this.createSkillsSection(
368
+ skills,
369
+ context.skillDescriptions || {}
370
+ );
371
+ }
372
+ const bodyContent = parsed.content;
373
+ const insertedBody = this.insertSkillsSection(bodyContent, skillsSection);
374
+ return combineMarkdown(newFrontmatter, insertedBody);
375
+ }
376
+ /**
377
+ * Create markdown section for required skills
378
+ * Uses descriptions from context (loaded from SKILL.md files)
379
+ */
380
+ createSkillsSection(skills, skillDescriptions) {
381
+ const lines = [
382
+ "",
383
+ "## \u{1F4DA} Required Skills",
384
+ "",
385
+ "This agent uses the following skills from `.cursor/skills/`:",
386
+ ""
387
+ ];
388
+ for (const skill of skills) {
389
+ const description = skillDescriptions[skill] || "Domain-specific knowledge module";
390
+ lines.push(`- **${skill}** - ${description}`);
391
+ }
392
+ lines.push("", "---", "");
393
+ return lines.join("\n");
394
+ }
395
+ /**
396
+ * Insert skills section after the first heading
397
+ */
398
+ insertSkillsSection(body, skillsSection) {
399
+ if (!skillsSection) return body;
400
+ const lines = body.split("\n");
401
+ let insertIndex = 0;
402
+ for (let i = 0; i < lines.length; i++) {
403
+ const line = lines[i].trim();
404
+ if (line.startsWith("# ")) {
405
+ insertIndex = i + 1;
406
+ while (insertIndex < lines.length && lines[insertIndex].trim() === "") {
407
+ insertIndex++;
408
+ }
409
+ if (insertIndex < lines.length && !lines[insertIndex].trim().startsWith("#")) {
410
+ insertIndex++;
411
+ }
412
+ break;
413
+ }
414
+ }
415
+ lines.splice(insertIndex, 0, skillsSection);
416
+ return lines.join("\n");
417
+ }
418
+ };
419
+ function createCursorAgentTransformer() {
420
+ return new CursorAgentTransformer();
421
+ }
422
+
423
+ // src/transformers/cursor-workflow.ts
424
+ var CursorWorkflowTransformer = class {
425
+ /**
426
+ * Transform workflow content from Agent-Kits format to Cursor command format
427
+ */
428
+ transform(content, context) {
429
+ const parsed = parseFrontmatter(content);
430
+ const originalData = parsed.data;
431
+ const cursorFrontmatter = {
432
+ description: originalData.description
433
+ };
434
+ const newFrontmatter = serializeFrontmatter(
435
+ cursorFrontmatter
436
+ );
437
+ let bodyContent = parsed.content;
438
+ bodyContent = this.transformPaths(bodyContent, context);
439
+ bodyContent = this.transformTerminology(bodyContent);
440
+ return combineMarkdown(newFrontmatter, bodyContent);
441
+ }
442
+ /**
443
+ * Transform path references from .agent/ to .cursor/
444
+ */
445
+ transformPaths(content, context) {
446
+ let transformed = content;
447
+ const toolPath = context.aiTool?.path || ".cursor";
448
+ transformed = transformed.replace(/\.agent\//g, `${toolPath}/`);
449
+ return transformed;
450
+ }
451
+ /**
452
+ * Transform terminology from Agent-Kits to Cursor
453
+ */
454
+ transformTerminology(content) {
455
+ let transformed = content;
456
+ transformed = transformed.replace(/workflows?\//gi, "commands/");
457
+ transformed = transformed.replace(/\/workflow/gi, "/command");
458
+ transformed = transformed.replace(/workflow/gi, "command");
459
+ transformed = transformed.replace(/Workflow/g, "Command");
460
+ transformed = transformed.replace(/WORKFLOW/g, "COMMAND");
461
+ return transformed;
462
+ }
463
+ };
464
+ function createCursorWorkflowTransformer() {
465
+ return new CursorWorkflowTransformer();
466
+ }
467
+
468
+ // src/installers/cursor.ts
469
+ var CursorInstaller = class {
470
+ // Cursor uses "commands" instead of "workflows"
471
+ COMMANDS_FOLDER = "commands";
472
+ // Transformers for Cursor-specific formats
473
+ agentTransformer = createCursorAgentTransformer();
474
+ workflowTransformer = createCursorWorkflowTransformer();
475
+ async install(options) {
476
+ const { aiTool, kits, targetPath } = options;
477
+ const results = [];
478
+ for (const kitId of kits) {
479
+ const { kitSourcePath, kit } = getKitSource(kitId);
480
+ const kitTargetPath = path4.join(targetPath, aiTool.path);
481
+ await fs3.mkdir(kitTargetPath, { recursive: true });
482
+ const skillDescriptions = await this.loadSkillDescriptions(kitSourcePath);
483
+ await copyDirectory(
484
+ kitSourcePath,
485
+ kitTargetPath,
486
+ ["rules", "workflows", "agents"],
487
+ aiTool.path
488
+ );
489
+ await this.copyAgentsWithTransform(
490
+ kitSourcePath,
491
+ kitTargetPath,
492
+ aiTool.path,
493
+ skillDescriptions
494
+ );
495
+ await this.copyWorkflowsWithTransform(
496
+ kitSourcePath,
497
+ kitTargetPath,
498
+ aiTool.path
499
+ );
500
+ await copyRulesFile(
501
+ kitSourcePath,
502
+ kitTargetPath,
503
+ targetPath,
504
+ aiTool,
505
+ options.scope,
506
+ this.COMMANDS_FOLDER
507
+ // Replace workflows/ with commands/
508
+ );
509
+ try {
510
+ await copyCommonAssets(kitTargetPath, aiTool, this.COMMANDS_FOLDER);
511
+ } catch {
512
+ }
513
+ const agents = await countItems(path4.join(kitTargetPath, "agents"));
514
+ const skills = await countItems(path4.join(kitTargetPath, "skills"));
515
+ const commands = await countItems(
516
+ path4.join(kitTargetPath, this.COMMANDS_FOLDER)
517
+ );
518
+ results.push({
519
+ kit: kit.name,
520
+ agents,
521
+ skills,
522
+ workflows: commands
523
+ // Still called "workflows" in result for consistency
524
+ });
525
+ }
526
+ return results;
527
+ }
528
+ /**
529
+ * Load skill descriptions from SKILL.md files
530
+ *
531
+ * Reads the `description` field from each skill's frontmatter.
532
+ * Loads from both kit-specific skills and common skills.
533
+ *
534
+ * @returns Map of skill name to description
535
+ */
536
+ async loadSkillDescriptions(kitSourcePath) {
537
+ const descriptions = {};
538
+ const kitSkillsPath = path4.join(kitSourcePath, "skills");
539
+ await this.extractSkillDescriptions(kitSkillsPath, descriptions);
540
+ const commonSkillsPath = path4.join(COMMON_DIR, "skills");
541
+ await this.extractSkillDescriptions(commonSkillsPath, descriptions);
542
+ return descriptions;
543
+ }
544
+ /**
545
+ * Extract descriptions from all SKILL.md files in a directory
546
+ */
547
+ async extractSkillDescriptions(skillsDir, descriptions) {
548
+ try {
549
+ const entries = await fs3.readdir(skillsDir, { withFileTypes: true });
550
+ for (const entry of entries) {
551
+ if (!entry.isDirectory()) continue;
552
+ const skillMdPath = path4.join(skillsDir, entry.name, "SKILL.md");
553
+ try {
554
+ const content = await fs3.readFile(skillMdPath, "utf-8");
555
+ const parsed = parseFrontmatter(content);
556
+ if (parsed.data.description) {
557
+ let desc = String(parsed.data.description);
558
+ const sentenceEnd = desc.indexOf(". ");
559
+ if (sentenceEnd > 0 && sentenceEnd < 80) {
560
+ desc = desc.slice(0, sentenceEnd);
561
+ } else if (desc.length > 80) {
562
+ desc = desc.slice(0, 77) + "...";
563
+ }
564
+ descriptions[entry.name] = desc;
565
+ }
566
+ } catch {
567
+ }
568
+ }
569
+ } catch {
570
+ }
571
+ }
572
+ /**
573
+ * Copy agents with transformation to Cursor subagent format
574
+ *
575
+ * This method:
576
+ * 1. Reads each agent file from the kit
577
+ * 2. Transforms the frontmatter to Cursor subagent format
578
+ * 3. Embeds skills references into the agent body
579
+ * 4. Writes the transformed agent to the target directory
580
+ */
581
+ async copyAgentsWithTransform(kitSourcePath, kitTargetPath, toolPath, skillDescriptions) {
582
+ const agentsSource = path4.join(kitSourcePath, "agents");
583
+ const agentsTarget = path4.join(kitTargetPath, "agents");
584
+ try {
585
+ await fs3.access(agentsSource);
586
+ } catch {
587
+ return;
588
+ }
589
+ await fs3.mkdir(agentsTarget, { recursive: true });
590
+ const entries = await fs3.readdir(agentsSource, { withFileTypes: true });
591
+ for (const entry of entries) {
592
+ if (!entry.isFile() || !entry.name.endsWith(".md")) {
593
+ continue;
594
+ }
595
+ const sourcePath = path4.join(agentsSource, entry.name);
596
+ const targetPath = path4.join(agentsTarget, entry.name);
597
+ let content = await fs3.readFile(sourcePath, "utf-8");
598
+ content = replaceToolPaths(content, toolPath);
599
+ const context = {
600
+ aiTool: { path: toolPath },
601
+ sourcePath,
602
+ targetPath,
603
+ skillDescriptions
604
+ };
605
+ const transformedContent = this.agentTransformer.transform(
606
+ content,
607
+ context
608
+ );
609
+ await fs3.writeFile(targetPath, transformedContent);
610
+ }
611
+ }
612
+ /**
613
+ * Copy workflows with transformation to Cursor command format
614
+ *
615
+ * This method:
616
+ * 1. Reads each workflow file from the kit
617
+ * 2. Transforms the frontmatter to Cursor command format
618
+ * 3. Replaces path references (.agent/ -> .cursor/)
619
+ * 4. Replaces terminology (workflow -> command)
620
+ * 5. Writes the transformed command to the commands directory
621
+ */
622
+ async copyWorkflowsWithTransform(kitSourcePath, kitTargetPath, toolPath) {
623
+ const workflowsSource = path4.join(kitSourcePath, "workflows");
624
+ const commandsTarget = path4.join(kitTargetPath, this.COMMANDS_FOLDER);
625
+ try {
626
+ await fs3.access(workflowsSource);
627
+ } catch {
628
+ return;
629
+ }
630
+ await fs3.mkdir(commandsTarget, { recursive: true });
631
+ const entries = await fs3.readdir(workflowsSource, { withFileTypes: true });
632
+ for (const entry of entries) {
633
+ if (!entry.isFile() || !entry.name.endsWith(".md")) {
634
+ continue;
635
+ }
636
+ const sourcePath = path4.join(workflowsSource, entry.name);
637
+ const targetPath = path4.join(commandsTarget, entry.name);
638
+ const content = await fs3.readFile(sourcePath, "utf-8");
639
+ const context = {
640
+ aiTool: { path: toolPath },
641
+ sourcePath,
642
+ targetPath
643
+ };
644
+ const transformedContent = this.workflowTransformer.transform(
645
+ content,
646
+ context
647
+ );
648
+ await fs3.writeFile(targetPath, transformedContent);
649
+ }
650
+ }
651
+ };
652
+
653
+ // src/installers/index.ts
654
+ var installerRegistry = {
655
+ // Antigravity is the base/default installer
656
+ antigravity: new AntigravityInstaller(),
657
+ // These tools use the same installation logic as Antigravity
658
+ claude: new AntigravityInstaller(),
659
+ gemini: new AntigravityInstaller(),
660
+ codex: new AntigravityInstaller(),
661
+ custom: new AntigravityInstaller(),
662
+ // Cursor has special handling (workflows -> commands)
663
+ cursor: new CursorInstaller()
664
+ };
665
+ function getInstaller(toolId) {
666
+ const installer = installerRegistry[toolId];
667
+ if (!installer) {
668
+ return new AntigravityInstaller();
669
+ }
670
+ return installer;
671
+ }
672
+ async function installKit(options) {
673
+ const installer = getInstaller(options.aiTool.id);
674
+ return installer.install(options);
675
+ }
253
676
 
254
677
  // src/cli.ts
255
678
  function expandPath(inputPath) {
256
679
  if (inputPath.startsWith("~")) {
257
- return path3.join(os2.homedir(), inputPath.slice(1));
680
+ return path5.join(os2.homedir(), inputPath.slice(1));
258
681
  }
259
682
  return inputPath;
260
683
  }
261
684
  function directoryExists(dirPath) {
262
685
  try {
263
- return fs2.existsSync(dirPath) && fs2.statSync(dirPath).isDirectory();
686
+ return fs4.existsSync(dirPath) && fs4.statSync(dirPath).isDirectory();
264
687
  } catch {
265
688
  return false;
266
689
  }
@@ -269,7 +692,7 @@ function getInstallPath(aiTool, scope, workspacePath) {
269
692
  if (scope === "global") {
270
693
  return getGlobalPath(aiTool);
271
694
  }
272
- return path3.join(workspacePath, aiTool.path);
695
+ return path5.join(workspacePath, aiTool.path);
273
696
  }
274
697
  function getDisplayPath(absolutePath) {
275
698
  const home = os2.homedir();
@@ -307,7 +730,7 @@ async function main() {
307
730
  p.intro(pc.bgCyan(pc.black(" SETUP WIZARD ")));
308
731
  const aiToolResult = await p.select({
309
732
  message: "\u{1F916} Which AI assistant are you using?",
310
- options: AI_TOOLS.map((tool) => ({
733
+ options: AI_TOOLS.filter((tool) => tool.available).map((tool) => ({
311
734
  value: tool.id,
312
735
  label: `${tool.name}`,
313
736
  hint: `${getGlobalPathDisplay(tool)}`
@@ -324,7 +747,7 @@ async function main() {
324
747
  {
325
748
  value: "workspace",
326
749
  label: "Workspace (Project)",
327
- hint: `Best for sharing with team (${path3.join(process.cwd(), aiTool.path)})`
750
+ hint: `Best for sharing with team (${path5.join(process.cwd(), aiTool.path)})`
328
751
  },
329
752
  {
330
753
  value: "global",
@@ -359,7 +782,7 @@ async function main() {
359
782
  workspacePath = expandPath(pathResult);
360
783
  }
361
784
  const finalInstallPath = getInstallPath(aiTool, scope, workspacePath);
362
- const rulesFilePath = scope === "global" || aiTool.rulesInsideKit ? path3.join(finalInstallPath, aiTool.rulesFile) : path3.join(workspacePath, aiTool.rulesFile);
785
+ const rulesFilePath = scope === "global" || aiTool.rulesInsideKit ? path5.join(finalInstallPath, aiTool.rulesFile) : path5.join(workspacePath, aiTool.rulesFile);
363
786
  if (directoryExists(finalInstallPath)) {
364
787
  p.log.warn(
365
788
  `${pc.yellow("\u26A0")} Existing toolkit found at: ${pc.cyan(getDisplayPath(finalInstallPath))}`
@@ -400,7 +823,7 @@ async function main() {
400
823
  if (replaceResult === "replace") {
401
824
  const s_rm = p.spinner();
402
825
  s_rm.start("Cleaning up old files...");
403
- fs2.rmSync(finalInstallPath, { recursive: true, force: true });
826
+ fs4.rmSync(finalInstallPath, { recursive: true, force: true });
404
827
  s_rm.stop("Cleanup complete.");
405
828
  }
406
829
  }
@@ -1,9 +1,10 @@
1
1
  ---
2
- description: AGT-Kit - AI Agent system rules with 22 agents, 39 skills, 7 workflows
2
+ trigger: always_on
3
+ description: AGT-Kit - AI Agent system rules with 22 agents, 39 skills, 7 commands
3
4
  alwaysApply: true
4
5
  ---
5
6
 
6
- # GEMINI.md - AGT-Kit
7
+ # CURSOR Rules - AGT-Kit
7
8
 
8
9
  > AI Agent Capability Expansion Toolkit - This file defines AI behavior in this workspace.
9
10
 
@@ -15,7 +16,7 @@ AGT-Kit is a portable, modular AI agent system consisting of:
15
16
 
16
17
  - **22 Specialist Agents** - Role-based AI personas
17
18
  - **39 Skills** - Domain-specific knowledge modules
18
- - **7 Workflows** - Slash command procedures
19
+ - **7 Commands** - Slash command procedures
19
20
 
20
21
  ---
21
22
 
@@ -118,7 +119,9 @@ Agent activated → Check frontmatter `skills:` → Read SKILL.md → Apply.
118
119
 
119
120
  ---
120
121
 
121
- ## 📜 WORKFLOWS (Slash Commands)
122
+ ## 📜 COMMANDS (Slash Commands)
123
+
124
+ > **Note:** In Cursor, workflows are called "commands" and stored in `.cursor/commands/`
122
125
 
123
126
  | Command | Description | Agent |
124
127
  | -------------- | ------------------------------------ | --------------- |
@@ -139,10 +142,10 @@ User Request → Check Profile → Skill Description Match → Load SKILL.md →
139
142
 
140
143
  ### Profile-Aware Loading
141
144
 
142
- > **CRITICAL:** Before loading any skill or selecting any agent, check `.agent/profile.json`
145
+ > **CRITICAL:** Before loading any skill or selecting any agent, check `.cursor/profile.json`
143
146
 
144
147
  ```
145
- 1. Check if `.agent/profile.json` exists
148
+ 1. Check if `.cursor/profile.json` exists
146
149
  2. If EXISTS:
147
150
  - Read skills.enabled[] → Only load these skills
148
151
  - Read skills.disabled[] → Skip these skills
@@ -190,7 +193,7 @@ Key skills: `api-patterns`, `database-design`, `react-patterns`, `typescript-pat
190
193
 
191
194
  > 🔴 Read `ARCHITECTURE.md` at session start.
192
195
 
193
- **Paths:** Agents `.agent/agents/`, Skills `.agent/skills/`, Workflows `.agent/workflows/`
196
+ **Paths:** Agents `.cursor/agents/`, Skills `.cursor/skills/`, Commands `.cursor/commands/`
194
197
 
195
198
  ### 🧠 Read → Understand → Apply
196
199
 
@@ -297,12 +300,12 @@ python3 .agent/scripts/skills_manager.py search <query>
297
300
 
298
301
  ## 📊 Kit Statistics
299
302
 
300
- | Metric | Count |
301
- | --------- | ----- |
302
- | Agents | 22 |
303
- | Skills | 39 |
304
- | Workflows | 7 |
305
- | Scripts | 19 |
303
+ | Metric | Count |
304
+ | -------- | ----- |
305
+ | Agents | 22 |
306
+ | Skills | 39 |
307
+ | Commands | 7 |
308
+ | Scripts | 19 |
306
309
 
307
310
  ---
308
311
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neyugn/agent-kits",
3
- "version": "0.2.8",
3
+ "version": "0.3.0",
4
4
  "description": "Universal AI Agent Toolkit - Skills, Agents, and Workflows for any AI coding assistant",
5
5
  "type": "module",
6
6
  "bin": {