@neyugn/agent-kits 0.1.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 (158) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +514 -0
  3. package/README.vi.md +410 -0
  4. package/README.zh.md +410 -0
  5. package/dist/cli.d.ts +1 -0
  6. package/dist/cli.js +422 -0
  7. package/kits/coder/ARCHITECTURE.md +289 -0
  8. package/kits/coder/agents/ai-engineer.md +344 -0
  9. package/kits/coder/agents/backend-specialist.md +270 -0
  10. package/kits/coder/agents/cloud-architect.md +363 -0
  11. package/kits/coder/agents/code-reviewer.md +284 -0
  12. package/kits/coder/agents/data-engineer.md +401 -0
  13. package/kits/coder/agents/database-specialist.md +251 -0
  14. package/kits/coder/agents/debugger.md +209 -0
  15. package/kits/coder/agents/devops-engineer.md +281 -0
  16. package/kits/coder/agents/documentation-writer.md +296 -0
  17. package/kits/coder/agents/frontend-specialist.md +298 -0
  18. package/kits/coder/agents/i18n-specialist.md +348 -0
  19. package/kits/coder/agents/integration-specialist.md +314 -0
  20. package/kits/coder/agents/mobile-developer.md +271 -0
  21. package/kits/coder/agents/multi-tenant-architect.md +281 -0
  22. package/kits/coder/agents/orchestrator.md +263 -0
  23. package/kits/coder/agents/performance-analyst.md +327 -0
  24. package/kits/coder/agents/project-planner.md +277 -0
  25. package/kits/coder/agents/queue-specialist.md +282 -0
  26. package/kits/coder/agents/realtime-specialist.md +267 -0
  27. package/kits/coder/agents/security-auditor.md +253 -0
  28. package/kits/coder/agents/test-engineer.md +315 -0
  29. package/kits/coder/agents/ux-researcher.md +388 -0
  30. package/kits/coder/rules/.cursorrules +287 -0
  31. package/kits/coder/rules/CLAUDE.md +287 -0
  32. package/kits/coder/rules/CODEX.md +287 -0
  33. package/kits/coder/rules/GEMINI.md +287 -0
  34. package/kits/coder/scripts/checklist.py +318 -0
  35. package/kits/coder/scripts/kit_status.py +292 -0
  36. package/kits/coder/scripts/skills_manager.py +243 -0
  37. package/kits/coder/scripts/verify_all.py +391 -0
  38. package/kits/coder/skills/accessibility-patterns/SKILL.md +372 -0
  39. package/kits/coder/skills/accessibility-patterns/scripts/a11y_checker.py +211 -0
  40. package/kits/coder/skills/ai-rag-patterns/SKILL.md +444 -0
  41. package/kits/coder/skills/api-patterns/SKILL.md +316 -0
  42. package/kits/coder/skills/api-patterns/assets/.gitkeep +1 -0
  43. package/kits/coder/skills/api-patterns/references/deep-dive.md +21 -0
  44. package/kits/coder/skills/api-patterns/scripts/api_validator.py +253 -0
  45. package/kits/coder/skills/api-patterns/scripts/validate.py +56 -0
  46. package/kits/coder/skills/auth-patterns/SKILL.md +267 -0
  47. package/kits/coder/skills/aws-patterns/SKILL.md +576 -0
  48. package/kits/coder/skills/brainstorming/SKILL.md +370 -0
  49. package/kits/coder/skills/brainstorming/assets/.gitkeep +1 -0
  50. package/kits/coder/skills/brainstorming/references/deep-dive.md +21 -0
  51. package/kits/coder/skills/brainstorming/scripts/validate.py +56 -0
  52. package/kits/coder/skills/clean-code/SKILL.md +240 -0
  53. package/kits/coder/skills/clean-code/assets/.gitkeep +1 -0
  54. package/kits/coder/skills/clean-code/references/deep-dive.md +21 -0
  55. package/kits/coder/skills/clean-code/scripts/lint_runner.py +186 -0
  56. package/kits/coder/skills/clean-code/scripts/validate.py +56 -0
  57. package/kits/coder/skills/database-design/SKILL.md +255 -0
  58. package/kits/coder/skills/database-design/assets/.gitkeep +1 -0
  59. package/kits/coder/skills/database-design/references/deep-dive.md +21 -0
  60. package/kits/coder/skills/database-design/scripts/schema_validator.py +272 -0
  61. package/kits/coder/skills/database-design/scripts/validate.py +56 -0
  62. package/kits/coder/skills/docker-patterns/SKILL.md +240 -0
  63. package/kits/coder/skills/documentation-templates/SKILL.md +441 -0
  64. package/kits/coder/skills/e2e-testing/SKILL.md +457 -0
  65. package/kits/coder/skills/flutter-patterns/SKILL.md +330 -0
  66. package/kits/coder/skills/frontend-design/SKILL.md +127 -0
  67. package/kits/coder/skills/github-actions/SKILL.md +349 -0
  68. package/kits/coder/skills/gitlab-ci-patterns/SKILL.md +466 -0
  69. package/kits/coder/skills/graphql-patterns/SKILL.md +558 -0
  70. package/kits/coder/skills/i18n-localization/SKILL.md +345 -0
  71. package/kits/coder/skills/i18n-localization/scripts/i18n_checker.py +267 -0
  72. package/kits/coder/skills/kubernetes-patterns/SKILL.md +357 -0
  73. package/kits/coder/skills/mermaid-diagrams/SKILL.md +351 -0
  74. package/kits/coder/skills/mobile-design/SKILL.md +305 -0
  75. package/kits/coder/skills/monitoring-observability/SKILL.md +458 -0
  76. package/kits/coder/skills/multi-tenancy/SKILL.md +317 -0
  77. package/kits/coder/skills/multi-tenancy/assets/.gitkeep +1 -0
  78. package/kits/coder/skills/multi-tenancy/references/deep-dive.md +21 -0
  79. package/kits/coder/skills/multi-tenancy/scripts/validate.py +56 -0
  80. package/kits/coder/skills/nodejs-best-practices/SKILL.md +220 -0
  81. package/kits/coder/skills/performance-profiling/SKILL.md +333 -0
  82. package/kits/coder/skills/performance-profiling/assets/.gitkeep +1 -0
  83. package/kits/coder/skills/performance-profiling/references/deep-dive.md +21 -0
  84. package/kits/coder/skills/performance-profiling/scripts/validate.py +56 -0
  85. package/kits/coder/skills/plan-writing/SKILL.md +360 -0
  86. package/kits/coder/skills/plan-writing/assets/.gitkeep +1 -0
  87. package/kits/coder/skills/plan-writing/references/deep-dive.md +21 -0
  88. package/kits/coder/skills/plan-writing/scripts/validate.py +56 -0
  89. package/kits/coder/skills/postgres-patterns/SKILL.md +361 -0
  90. package/kits/coder/skills/prompt-engineering/SKILL.md +277 -0
  91. package/kits/coder/skills/queue-patterns/SKILL.md +359 -0
  92. package/kits/coder/skills/queue-patterns/assets/.gitkeep +1 -0
  93. package/kits/coder/skills/queue-patterns/references/deep-dive.md +21 -0
  94. package/kits/coder/skills/queue-patterns/scripts/validate.py +56 -0
  95. package/kits/coder/skills/react-native-patterns/SKILL.md +393 -0
  96. package/kits/coder/skills/react-patterns/SKILL.md +319 -0
  97. package/kits/coder/skills/realtime-patterns/SKILL.md +506 -0
  98. package/kits/coder/skills/realtime-patterns/assets/.gitkeep +1 -0
  99. package/kits/coder/skills/realtime-patterns/references/deep-dive.md +21 -0
  100. package/kits/coder/skills/realtime-patterns/scripts/validate.py +56 -0
  101. package/kits/coder/skills/redis-patterns/SKILL.md +484 -0
  102. package/kits/coder/skills/security-fundamentals/SKILL.md +363 -0
  103. package/kits/coder/skills/security-fundamentals/assets/.gitkeep +1 -0
  104. package/kits/coder/skills/security-fundamentals/references/deep-dive.md +21 -0
  105. package/kits/coder/skills/security-fundamentals/scripts/security_scan.py +326 -0
  106. package/kits/coder/skills/security-fundamentals/scripts/validate.py +56 -0
  107. package/kits/coder/skills/seo-patterns/SKILL.md +262 -0
  108. package/kits/coder/skills/seo-patterns/scripts/seo_checker.py +211 -0
  109. package/kits/coder/skills/systematic-debugging/SKILL.md +478 -0
  110. package/kits/coder/skills/systematic-debugging/assets/.gitkeep +1 -0
  111. package/kits/coder/skills/systematic-debugging/references/deep-dive.md +21 -0
  112. package/kits/coder/skills/systematic-debugging/scripts/validate.py +56 -0
  113. package/kits/coder/skills/tailwind-patterns/SKILL.md +395 -0
  114. package/kits/coder/skills/terraform-patterns/SKILL.md +470 -0
  115. package/kits/coder/skills/testing-patterns/SKILL.md +285 -0
  116. package/kits/coder/skills/testing-patterns/assets/.gitkeep +1 -0
  117. package/kits/coder/skills/testing-patterns/references/deep-dive.md +21 -0
  118. package/kits/coder/skills/testing-patterns/scripts/test_runner.py +219 -0
  119. package/kits/coder/skills/testing-patterns/scripts/validate.py +56 -0
  120. package/kits/coder/skills/typescript-patterns/SKILL.md +417 -0
  121. package/kits/coder/skills/ui-ux-pro-max/SKILL.md +364 -0
  122. package/kits/coder/skills/ui-ux-pro-max/data/charts.csv +26 -0
  123. package/kits/coder/skills/ui-ux-pro-max/data/colors.csv +97 -0
  124. package/kits/coder/skills/ui-ux-pro-max/data/icons.csv +101 -0
  125. package/kits/coder/skills/ui-ux-pro-max/data/landing.csv +31 -0
  126. package/kits/coder/skills/ui-ux-pro-max/data/products.csv +97 -0
  127. package/kits/coder/skills/ui-ux-pro-max/data/prompts.csv +24 -0
  128. package/kits/coder/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  129. package/kits/coder/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  130. package/kits/coder/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  131. package/kits/coder/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  132. package/kits/coder/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  133. package/kits/coder/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  134. package/kits/coder/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  135. package/kits/coder/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  136. package/kits/coder/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  137. package/kits/coder/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  138. package/kits/coder/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  139. package/kits/coder/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  140. package/kits/coder/skills/ui-ux-pro-max/data/styles.csv +59 -0
  141. package/kits/coder/skills/ui-ux-pro-max/data/typography.csv +58 -0
  142. package/kits/coder/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  143. package/kits/coder/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  144. package/kits/coder/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  145. package/kits/coder/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-314.pyc +0 -0
  146. package/kits/coder/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-314.pyc +0 -0
  147. package/kits/coder/skills/ui-ux-pro-max/scripts/core.py +257 -0
  148. package/kits/coder/skills/ui-ux-pro-max/scripts/design_system.py +488 -0
  149. package/kits/coder/skills/ui-ux-pro-max/scripts/search.py +76 -0
  150. package/kits/coder/workflows/.gitkeep +20 -0
  151. package/kits/coder/workflows/create.md +152 -0
  152. package/kits/coder/workflows/debug.md +223 -0
  153. package/kits/coder/workflows/deploy.md +283 -0
  154. package/kits/coder/workflows/orchestrate.md +243 -0
  155. package/kits/coder/workflows/plan.md +134 -0
  156. package/kits/coder/workflows/test.md +237 -0
  157. package/kits/coder/workflows/ui-ux-pro-max.md +109 -0
  158. package/package.json +49 -0
package/dist/cli.js ADDED
@@ -0,0 +1,422 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli.ts
4
+ import * as p from "@clack/prompts";
5
+ import fs2 from "fs";
6
+ import os2 from "os";
7
+ import path3 from "path";
8
+ import pc from "picocolors";
9
+
10
+ // src/config.ts
11
+ import os from "os";
12
+ import path from "path";
13
+ function getGlobalPath(tool) {
14
+ const folderName = tool.globalPathPattern.replace("~/", "");
15
+ return path.join(os.homedir(), folderName);
16
+ }
17
+ function getGlobalPathDisplay(tool) {
18
+ if (process.platform === "win32") {
19
+ return getGlobalPath(tool);
20
+ }
21
+ return tool.globalPathPattern;
22
+ }
23
+ var AI_TOOLS = [
24
+ {
25
+ id: "claude",
26
+ name: "Claude Code",
27
+ icon: "\u{1F7E0}",
28
+ path: ".claude",
29
+ globalPathPattern: "~/.claude",
30
+ // Resolved to home dir at runtime
31
+ rulesFile: "CLAUDE.md",
32
+ kitRulesFile: "CLAUDE.md"
33
+ },
34
+ {
35
+ id: "gemini",
36
+ name: "Gemini CLI",
37
+ icon: "\u{1F535}",
38
+ path: ".gemini",
39
+ globalPathPattern: "~/.gemini",
40
+ rulesFile: "GEMINI.md",
41
+ kitRulesFile: "GEMINI.md"
42
+ },
43
+ {
44
+ id: "codex",
45
+ name: "Codex CLI",
46
+ icon: "\u{1F7E2}",
47
+ path: ".codex",
48
+ globalPathPattern: "~/.codex",
49
+ rulesFile: "CODEX.md",
50
+ kitRulesFile: "CODEX.md"
51
+ },
52
+ {
53
+ id: "antigravity",
54
+ name: "Antigravity",
55
+ icon: "\u{1F7E3}",
56
+ path: ".agent",
57
+ globalPathPattern: "~/.agent",
58
+ rulesFile: "GEMINI.md",
59
+ kitRulesFile: "GEMINI.md"
60
+ },
61
+ {
62
+ id: "cursor",
63
+ name: "Cursor",
64
+ icon: "\u26AA",
65
+ path: ".cursor",
66
+ globalPathPattern: "~/.cursor",
67
+ rulesFile: ".cursorrules",
68
+ kitRulesFile: ".cursorrules"
69
+ },
70
+ {
71
+ id: "custom",
72
+ name: "Custom",
73
+ icon: "\u2699\uFE0F",
74
+ path: ".ai",
75
+ globalPathPattern: "~/.ai",
76
+ rulesFile: "RULES.md",
77
+ kitRulesFile: "GEMINI.md"
78
+ // Use GEMINI.md as base for custom
79
+ }
80
+ ];
81
+ var KITS = [
82
+ {
83
+ id: "coder",
84
+ name: "Coder",
85
+ icon: "\u{1F4BB}",
86
+ description: "22 agents, 39 skills, 7 workflows for software development",
87
+ agents: 22,
88
+ skills: 39,
89
+ workflows: 7,
90
+ available: true
91
+ },
92
+ {
93
+ id: "writer",
94
+ name: "Writer",
95
+ icon: "\u270D\uFE0F",
96
+ description: "Content creation, copywriting, documentation",
97
+ agents: 0,
98
+ skills: 0,
99
+ workflows: 0,
100
+ available: false
101
+ },
102
+ {
103
+ id: "researcher",
104
+ name: "Researcher",
105
+ icon: "\u{1F52C}",
106
+ description: "Research, analysis, synthesis",
107
+ agents: 0,
108
+ skills: 0,
109
+ workflows: 0,
110
+ available: false
111
+ },
112
+ {
113
+ id: "designer",
114
+ name: "Designer",
115
+ icon: "\u{1F3A8}",
116
+ description: "UI/UX design, branding, visual assets",
117
+ agents: 0,
118
+ skills: 0,
119
+ workflows: 0,
120
+ available: false
121
+ }
122
+ ];
123
+
124
+ // src/installers/index.ts
125
+ import fs from "fs/promises";
126
+ import path2 from "path";
127
+ import { fileURLToPath } from "url";
128
+ var __dirname = path2.dirname(fileURLToPath(import.meta.url));
129
+ var KITS_DIR = path2.resolve(__dirname, "../../kits");
130
+ var COMMON_DIR = path2.resolve(__dirname, "../../common");
131
+ async function installKit(options) {
132
+ const { aiTool, kits, targetPath } = options;
133
+ const results = [];
134
+ for (const kitId of kits) {
135
+ const kit = KITS.find((k) => k.id === kitId);
136
+ if (!kit || !kit.available) {
137
+ throw new Error(`Kit "${kitId}" is not available`);
138
+ }
139
+ const kitSourcePath = path2.join(KITS_DIR, kitId);
140
+ const kitTargetPath = path2.join(targetPath, aiTool.path);
141
+ await fs.mkdir(kitTargetPath, { recursive: true });
142
+ await copyDirectory(kitSourcePath, kitTargetPath, ["rules"]);
143
+ const rulesSource = path2.join(kitSourcePath, "rules", aiTool.kitRulesFile);
144
+ const rulesTarget = path2.join(targetPath, aiTool.rulesFile);
145
+ try {
146
+ let rulesContent = await fs.readFile(rulesSource, "utf-8");
147
+ rulesContent = rulesContent.replace(
148
+ /\.(agent|claude|gemini|cursor|codex)\//g,
149
+ `${aiTool.path}/`
150
+ );
151
+ await fs.writeFile(rulesTarget, rulesContent);
152
+ } catch {
153
+ try {
154
+ const fallbackSource = path2.join(kitSourcePath, "rules", "GEMINI.md");
155
+ let rulesContent = await fs.readFile(fallbackSource, "utf-8");
156
+ rulesContent = rulesContent.replace(
157
+ /\.(agent|claude|gemini|cursor|codex)\//g,
158
+ `${aiTool.path}/`
159
+ );
160
+ await fs.writeFile(rulesTarget, rulesContent);
161
+ } catch {
162
+ }
163
+ }
164
+ try {
165
+ const commonSkillsPath = path2.join(COMMON_DIR, "skills");
166
+ const commonWorkflowsPath = path2.join(COMMON_DIR, "workflows");
167
+ const commonDocPath = path2.join(COMMON_DIR, "COMMON.md");
168
+ const targetSkillsPath = path2.join(kitTargetPath, "skills");
169
+ await fs.mkdir(targetSkillsPath, { recursive: true });
170
+ await copyDirectory(commonSkillsPath, targetSkillsPath);
171
+ const targetWorkflowsPath = path2.join(kitTargetPath, "workflows");
172
+ await fs.mkdir(targetWorkflowsPath, { recursive: true });
173
+ await copyDirectory(commonWorkflowsPath, targetWorkflowsPath);
174
+ const targetCommonDoc = path2.join(kitTargetPath, "COMMON.md");
175
+ await fs.copyFile(commonDocPath, targetCommonDoc);
176
+ } catch {
177
+ }
178
+ const agents = await countItems(path2.join(kitTargetPath, "agents"));
179
+ const skills = await countItems(path2.join(kitTargetPath, "skills"));
180
+ const workflows = await countItems(path2.join(kitTargetPath, "workflows"));
181
+ results.push({
182
+ kit: kit.name,
183
+ agents,
184
+ skills,
185
+ workflows
186
+ });
187
+ }
188
+ return results;
189
+ }
190
+ async function copyDirectory(src, dest, exclude = []) {
191
+ await fs.mkdir(dest, { recursive: true });
192
+ const entries = await fs.readdir(src, { withFileTypes: true });
193
+ for (const entry of entries) {
194
+ if (exclude.includes(entry.name)) {
195
+ continue;
196
+ }
197
+ const srcPath = path2.join(src, entry.name);
198
+ const destPath = path2.join(dest, entry.name);
199
+ if (entry.isDirectory()) {
200
+ await copyDirectory(srcPath, destPath, exclude);
201
+ } else {
202
+ await fs.copyFile(srcPath, destPath);
203
+ }
204
+ }
205
+ }
206
+ async function countItems(dirPath) {
207
+ try {
208
+ const entries = await fs.readdir(dirPath);
209
+ return entries.length;
210
+ } catch {
211
+ return 0;
212
+ }
213
+ }
214
+
215
+ // src/cli.ts
216
+ function expandPath(inputPath) {
217
+ if (inputPath.startsWith("~")) {
218
+ return path3.join(os2.homedir(), inputPath.slice(1));
219
+ }
220
+ return inputPath;
221
+ }
222
+ function directoryExists(dirPath) {
223
+ try {
224
+ return fs2.existsSync(dirPath) && fs2.statSync(dirPath).isDirectory();
225
+ } catch {
226
+ return false;
227
+ }
228
+ }
229
+ function getInstallPath(aiTool, scope, workspacePath) {
230
+ if (scope === "global") {
231
+ return getGlobalPath(aiTool);
232
+ }
233
+ return path3.join(workspacePath, aiTool.path);
234
+ }
235
+ function getDisplayPath(absolutePath) {
236
+ const home = os2.homedir();
237
+ const isWindows = process.platform === "win32";
238
+ if (!isWindows && absolutePath.startsWith(home)) {
239
+ return "~" + absolutePath.slice(home.length);
240
+ }
241
+ return absolutePath;
242
+ }
243
+ async function main() {
244
+ console.clear();
245
+ console.log(
246
+ pc.cyan(`
247
+ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
248
+ \u2551 \u2551
249
+ \u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2551
250
+ \u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D \u2551
251
+ \u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2551
252
+ \u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u2551
253
+ \u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2551
254
+ \u2551 \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u2551
255
+ \u2551 ${pc.bold("K I T S")} \u2551
256
+ \u2551 \u2551
257
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
258
+ `)
259
+ );
260
+ p.intro(pc.bgCyan(pc.black(" Universal AI Agent Toolkit ")));
261
+ const aiToolResult = await p.select({
262
+ message: "Which AI tool are you using?",
263
+ options: AI_TOOLS.map((tool) => ({
264
+ value: tool.id,
265
+ label: `${tool.icon} ${tool.name}`,
266
+ hint: `workspace: ${tool.path} | global: ${getGlobalPathDisplay(tool)}`
267
+ }))
268
+ });
269
+ if (p.isCancel(aiToolResult)) {
270
+ p.cancel("Installation cancelled.");
271
+ process.exit(0);
272
+ }
273
+ const aiTool = AI_TOOLS.find((t) => t.id === aiToolResult);
274
+ const scopeResult = await p.select({
275
+ message: "Where do you want to install?",
276
+ options: [
277
+ {
278
+ value: "workspace",
279
+ label: "\u{1F4C1} Workspace (Current Project)",
280
+ hint: `Install to ${path3.join(process.cwd(), aiTool.path)}`
281
+ },
282
+ {
283
+ value: "global",
284
+ label: "\u{1F30D} Global (All Projects)",
285
+ hint: `Install to ${getGlobalPathDisplay(aiTool)}`
286
+ }
287
+ ]
288
+ });
289
+ if (p.isCancel(scopeResult)) {
290
+ p.cancel("Installation cancelled.");
291
+ process.exit(0);
292
+ }
293
+ const scope = scopeResult;
294
+ let workspacePath = process.cwd();
295
+ if (scope === "workspace") {
296
+ const pathResult = await p.text({
297
+ message: "Workspace path:",
298
+ placeholder: process.cwd(),
299
+ defaultValue: process.cwd(),
300
+ validate: (value) => {
301
+ if (!value) return "Path is required";
302
+ const expanded = expandPath(value);
303
+ if (!directoryExists(expanded)) {
304
+ return `Directory does not exist: ${expanded}`;
305
+ }
306
+ }
307
+ });
308
+ if (p.isCancel(pathResult)) {
309
+ p.cancel("Installation cancelled.");
310
+ process.exit(0);
311
+ }
312
+ workspacePath = expandPath(pathResult);
313
+ }
314
+ const finalInstallPath = getInstallPath(aiTool, scope, workspacePath);
315
+ const rulesFilePath = scope === "global" ? path3.join(os2.homedir(), aiTool.rulesFile) : path3.join(workspacePath, aiTool.rulesFile);
316
+ if (directoryExists(finalInstallPath)) {
317
+ p.log.warn(
318
+ `${pc.yellow("\u26A0")} Existing installation detected at: ${pc.cyan(getDisplayPath(finalInstallPath))}`
319
+ );
320
+ const replaceResult = await p.select({
321
+ message: "What would you like to do?",
322
+ options: [
323
+ {
324
+ value: "replace",
325
+ label: "\u{1F504} Replace",
326
+ hint: "Remove existing and install fresh"
327
+ },
328
+ {
329
+ value: "merge",
330
+ label: "\u{1F500} Merge",
331
+ hint: "Keep config files, update skills only"
332
+ },
333
+ {
334
+ value: "skip",
335
+ label: "\u23ED\uFE0F Skip",
336
+ hint: "Keep existing, don't install"
337
+ },
338
+ {
339
+ value: "cancel",
340
+ label: "\u274C Cancel",
341
+ hint: "Exit installer"
342
+ }
343
+ ]
344
+ });
345
+ if (p.isCancel(replaceResult) || replaceResult === "cancel") {
346
+ p.cancel("Installation cancelled.");
347
+ process.exit(0);
348
+ }
349
+ if (replaceResult === "skip") {
350
+ p.log.info("Skipping installation. Existing files preserved.");
351
+ process.exit(0);
352
+ }
353
+ if (replaceResult === "replace") {
354
+ p.log.step(`Removing existing installation...`);
355
+ fs2.rmSync(finalInstallPath, { recursive: true, force: true });
356
+ }
357
+ }
358
+ const selectedKits = await p.multiselect({
359
+ message: "Select kits to install:",
360
+ options: KITS.filter((kit) => kit.available).map((kit) => ({
361
+ value: kit.id,
362
+ label: `${kit.icon} ${kit.name}`,
363
+ hint: kit.description
364
+ })),
365
+ required: true
366
+ });
367
+ if (p.isCancel(selectedKits)) {
368
+ p.cancel("Installation cancelled.");
369
+ process.exit(0);
370
+ }
371
+ const displayInstallPath = getDisplayPath(finalInstallPath);
372
+ const displayRulesPath = getDisplayPath(rulesFilePath);
373
+ const summaryLines = [
374
+ `${pc.bold("AI Tool:")} ${aiTool.icon} ${aiTool.name}`,
375
+ `${pc.bold("Scope:")} ${scope === "global" ? "\u{1F30D} Global" : "\u{1F4C1} Workspace"}`,
376
+ `${pc.bold("Install Path:")} ${pc.cyan(displayInstallPath)}`,
377
+ `${pc.bold("Rules File:")} ${pc.cyan(displayRulesPath)}`,
378
+ `${pc.bold("Kits:")} ${selectedKits.join(", ")}`
379
+ ];
380
+ p.note(summaryLines.join("\n"), "Installation Summary");
381
+ const confirmed = await p.confirm({
382
+ message: `Proceed with installation?`
383
+ });
384
+ if (p.isCancel(confirmed) || !confirmed) {
385
+ p.cancel("Installation cancelled.");
386
+ process.exit(0);
387
+ }
388
+ const s = p.spinner();
389
+ s.start(`Installing to ${pc.cyan(displayInstallPath)}...`);
390
+ try {
391
+ const results = await installKit({
392
+ aiTool,
393
+ kits: selectedKits,
394
+ targetPath: scope === "global" ? os2.homedir() : workspacePath,
395
+ scope
396
+ });
397
+ s.stop("Installation complete!");
398
+ p.note(
399
+ [
400
+ `${pc.bold("\u{1F4CD} Location:")} ${displayInstallPath}`,
401
+ `${pc.bold("\u{1F4DC} Rules:")} ${displayRulesPath}`,
402
+ "",
403
+ ...results.map(
404
+ (r) => `${pc.green("\u2713")} ${r.kit}: ${r.agents} agents, ${r.skills} skills, ${r.workflows} workflows`
405
+ )
406
+ ].join("\n"),
407
+ "Installed Successfully"
408
+ );
409
+ const archPath = scope === "global" ? `${getGlobalPathDisplay(aiTool)}/ARCHITECTURE.md` : `${aiTool.path}/ARCHITECTURE.md`;
410
+ p.outro(
411
+ pc.green("Success! ") + pc.dim("Next steps:\n") + ` ${pc.cyan("\u2022")} Use ${pc.bold("/filter")} to optimize skills for your project
412
+ ${pc.cyan("\u2022")} Use ${pc.bold("/plan")} to create project plans
413
+ ${pc.cyan("\u2022")} Use ${pc.bold("@backend-specialist")} for APIs
414
+ ${pc.cyan("\u2022")} Read ${pc.bold(archPath)}`
415
+ );
416
+ } catch (error) {
417
+ s.stop("Installation failed!");
418
+ p.log.error(error instanceof Error ? error.message : "Unknown error");
419
+ process.exit(1);
420
+ }
421
+ }
422
+ main().catch(console.error);