@musashishao/agent-kit 1.2.2

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 (236) hide show
  1. package/.agent/agents/backend-specialist.md +263 -0
  2. package/.agent/agents/database-architect.md +226 -0
  3. package/.agent/agents/debugger.md +225 -0
  4. package/.agent/agents/devops-engineer.md +242 -0
  5. package/.agent/agents/documentation-writer.md +104 -0
  6. package/.agent/agents/explorer-agent.md +73 -0
  7. package/.agent/agents/frontend-specialist.md +556 -0
  8. package/.agent/agents/game-developer.md +162 -0
  9. package/.agent/agents/mobile-developer.md +377 -0
  10. package/.agent/agents/orchestrator.md +416 -0
  11. package/.agent/agents/penetration-tester.md +188 -0
  12. package/.agent/agents/performance-optimizer.md +187 -0
  13. package/.agent/agents/project-planner.md +403 -0
  14. package/.agent/agents/security-auditor.md +170 -0
  15. package/.agent/agents/seo-specialist.md +111 -0
  16. package/.agent/agents/test-engineer.md +158 -0
  17. package/.agent/mcp/README.md +69 -0
  18. package/.agent/mcp/config/mcp-config.json +62 -0
  19. package/.agent/mcp/config/registry.json +54 -0
  20. package/.agent/mcp/servers/agent-kit-core/package.json +28 -0
  21. package/.agent/mcp/servers/agent-kit-core/src/index.ts +455 -0
  22. package/.agent/mcp/servers/agent-kit-core/tsconfig.json +16 -0
  23. package/.agent/mcp/servers/agent-kit-fs/package.json +25 -0
  24. package/.agent/mcp/servers/agent-kit-fs/src/index.ts +399 -0
  25. package/.agent/mcp/servers/agent-kit-fs/tsconfig.json +16 -0
  26. package/.agent/mcp/servers/agent-kit-git/package.json +24 -0
  27. package/.agent/mcp/servers/agent-kit-git/src/index.ts +283 -0
  28. package/.agent/mcp/servers/agent-kit-git/tsconfig.json +16 -0
  29. package/.agent/mcp/templates/README.md +49 -0
  30. package/.agent/mcp/templates/api/README.md.template +45 -0
  31. package/.agent/mcp/templates/api/src/index.ts.template +185 -0
  32. package/.agent/mcp/templates/base-package.json.template +27 -0
  33. package/.agent/mcp/templates/base-tsconfig.json +21 -0
  34. package/.agent/mcp/templates/custom/src/index.ts.template +133 -0
  35. package/.agent/mcp/templates/database/src/index.ts.template +273 -0
  36. package/.agent/mcp/templates/web-scraper/src/index.ts.template +239 -0
  37. package/.agent/rules/CODEX.md +250 -0
  38. package/.agent/rules/GEMINI.md +251 -0
  39. package/.agent/skills/api-patterns/SKILL.md +81 -0
  40. package/.agent/skills/api-patterns/api-style.md +42 -0
  41. package/.agent/skills/api-patterns/auth.md +24 -0
  42. package/.agent/skills/api-patterns/documentation.md +26 -0
  43. package/.agent/skills/api-patterns/graphql.md +41 -0
  44. package/.agent/skills/api-patterns/rate-limiting.md +31 -0
  45. package/.agent/skills/api-patterns/response.md +37 -0
  46. package/.agent/skills/api-patterns/rest.md +40 -0
  47. package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
  48. package/.agent/skills/api-patterns/security-testing.md +122 -0
  49. package/.agent/skills/api-patterns/trpc.md +41 -0
  50. package/.agent/skills/api-patterns/versioning.md +22 -0
  51. package/.agent/skills/app-builder/SKILL.md +75 -0
  52. package/.agent/skills/app-builder/agent-coordination.md +71 -0
  53. package/.agent/skills/app-builder/feature-building.md +53 -0
  54. package/.agent/skills/app-builder/project-detection.md +34 -0
  55. package/.agent/skills/app-builder/scaffolding.md +118 -0
  56. package/.agent/skills/app-builder/tech-stack.md +40 -0
  57. package/.agent/skills/app-builder/templates/SKILL.md +39 -0
  58. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
  59. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
  60. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
  61. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
  62. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
  63. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
  64. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
  65. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +82 -0
  66. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +100 -0
  67. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +106 -0
  68. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +101 -0
  69. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
  70. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +93 -0
  71. package/.agent/skills/architecture/SKILL.md +55 -0
  72. package/.agent/skills/architecture/context-discovery.md +43 -0
  73. package/.agent/skills/architecture/examples.md +94 -0
  74. package/.agent/skills/architecture/pattern-selection.md +68 -0
  75. package/.agent/skills/architecture/patterns-reference.md +50 -0
  76. package/.agent/skills/architecture/trade-off-analysis.md +77 -0
  77. package/.agent/skills/bash-linux/SKILL.md +199 -0
  78. package/.agent/skills/behavioral-modes/SKILL.md +242 -0
  79. package/.agent/skills/brainstorming/SKILL.md +163 -0
  80. package/.agent/skills/brainstorming/dynamic-questioning.md +350 -0
  81. package/.agent/skills/clean-code/SKILL.md +201 -0
  82. package/.agent/skills/code-review-checklist/SKILL.md +109 -0
  83. package/.agent/skills/context-engineering/SKILL.md +74 -0
  84. package/.agent/skills/context-engineering/examples/advanced_code_request.md +73 -0
  85. package/.agent/skills/context-engineering/scripts/quality_validator.py +294 -0
  86. package/.agent/skills/context-engineering/scripts/repo_mapper.py +27 -0
  87. package/.agent/skills/context-engineering/scripts/skill_checker.py +194 -0
  88. package/.agent/skills/context-engineering/scripts/token_counter.py +65 -0
  89. package/.agent/skills/context-engineering/strategies/context-caching.md +50 -0
  90. package/.agent/skills/context-engineering/strategies/few-shot-examples.md +56 -0
  91. package/.agent/skills/context-engineering/strategies/skeleton-code.md +59 -0
  92. package/.agent/skills/context-engineering/strategies/xml-framing.md +57 -0
  93. package/.agent/skills/database-design/SKILL.md +52 -0
  94. package/.agent/skills/database-design/database-selection.md +43 -0
  95. package/.agent/skills/database-design/indexing.md +39 -0
  96. package/.agent/skills/database-design/migrations.md +48 -0
  97. package/.agent/skills/database-design/optimization.md +36 -0
  98. package/.agent/skills/database-design/orm-selection.md +30 -0
  99. package/.agent/skills/database-design/schema-design.md +56 -0
  100. package/.agent/skills/database-design/scripts/schema_validator.py +172 -0
  101. package/.agent/skills/deployment-procedures/SKILL.md +241 -0
  102. package/.agent/skills/doc.md +177 -0
  103. package/.agent/skills/docker-expert/SKILL.md +409 -0
  104. package/.agent/skills/documentation-templates/SKILL.md +194 -0
  105. package/.agent/skills/frontend-design/SKILL.md +396 -0
  106. package/.agent/skills/frontend-design/animation-guide.md +331 -0
  107. package/.agent/skills/frontend-design/color-system.md +311 -0
  108. package/.agent/skills/frontend-design/decision-trees.md +418 -0
  109. package/.agent/skills/frontend-design/motion-graphics.md +306 -0
  110. package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
  111. package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
  112. package/.agent/skills/frontend-design/typography-system.md +345 -0
  113. package/.agent/skills/frontend-design/ux-psychology.md +541 -0
  114. package/.agent/skills/frontend-design/visual-effects.md +383 -0
  115. package/.agent/skills/game-development/2d-games/SKILL.md +119 -0
  116. package/.agent/skills/game-development/3d-games/SKILL.md +135 -0
  117. package/.agent/skills/game-development/SKILL.md +167 -0
  118. package/.agent/skills/game-development/game-art/SKILL.md +185 -0
  119. package/.agent/skills/game-development/game-audio/SKILL.md +190 -0
  120. package/.agent/skills/game-development/game-design/SKILL.md +129 -0
  121. package/.agent/skills/game-development/mobile-games/SKILL.md +108 -0
  122. package/.agent/skills/game-development/multiplayer/SKILL.md +132 -0
  123. package/.agent/skills/game-development/pc-games/SKILL.md +144 -0
  124. package/.agent/skills/game-development/vr-ar/SKILL.md +123 -0
  125. package/.agent/skills/game-development/web-games/SKILL.md +150 -0
  126. package/.agent/skills/geo-fundamentals/SKILL.md +156 -0
  127. package/.agent/skills/geo-fundamentals/scripts/geo_checker.py +289 -0
  128. package/.agent/skills/i18n-localization/SKILL.md +154 -0
  129. package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
  130. package/.agent/skills/lint-and-validate/SKILL.md +45 -0
  131. package/.agent/skills/lint-and-validate/scripts/lint_runner.py +172 -0
  132. package/.agent/skills/lint-and-validate/scripts/type_coverage.py +173 -0
  133. package/.agent/skills/mcp-builder/SKILL.md +662 -0
  134. package/.agent/skills/mcp-builder/python-template.md +522 -0
  135. package/.agent/skills/mcp-builder/tool-patterns.md +642 -0
  136. package/.agent/skills/mcp-builder/typescript-template.md +361 -0
  137. package/.agent/skills/mobile-design/SKILL.md +394 -0
  138. package/.agent/skills/mobile-design/decision-trees.md +516 -0
  139. package/.agent/skills/mobile-design/mobile-backend.md +491 -0
  140. package/.agent/skills/mobile-design/mobile-color-system.md +420 -0
  141. package/.agent/skills/mobile-design/mobile-debugging.md +122 -0
  142. package/.agent/skills/mobile-design/mobile-design-thinking.md +357 -0
  143. package/.agent/skills/mobile-design/mobile-navigation.md +458 -0
  144. package/.agent/skills/mobile-design/mobile-performance.md +767 -0
  145. package/.agent/skills/mobile-design/mobile-testing.md +356 -0
  146. package/.agent/skills/mobile-design/mobile-typography.md +433 -0
  147. package/.agent/skills/mobile-design/platform-android.md +666 -0
  148. package/.agent/skills/mobile-design/platform-ios.md +561 -0
  149. package/.agent/skills/mobile-design/scripts/mobile_audit.py +670 -0
  150. package/.agent/skills/mobile-design/touch-psychology.md +537 -0
  151. package/.agent/skills/nestjs-expert/SKILL.md +552 -0
  152. package/.agent/skills/nextjs-best-practices/SKILL.md +203 -0
  153. package/.agent/skills/nodejs-best-practices/SKILL.md +333 -0
  154. package/.agent/skills/parallel-agents/SKILL.md +175 -0
  155. package/.agent/skills/performance-profiling/SKILL.md +143 -0
  156. package/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +76 -0
  157. package/.agent/skills/plan-writing/SKILL.md +152 -0
  158. package/.agent/skills/powershell-windows/SKILL.md +167 -0
  159. package/.agent/skills/prisma-expert/SKILL.md +355 -0
  160. package/.agent/skills/problem-solving/SKILL.md +556 -0
  161. package/.agent/skills/problem-solving/collision-zone-thinking.md +285 -0
  162. package/.agent/skills/problem-solving/inversion-exercise.md +205 -0
  163. package/.agent/skills/problem-solving/meta-pattern-recognition.md +313 -0
  164. package/.agent/skills/problem-solving/scale-game.md +300 -0
  165. package/.agent/skills/problem-solving/simplification-cascades.md +321 -0
  166. package/.agent/skills/problem-solving/when-stuck.md +146 -0
  167. package/.agent/skills/python-patterns/SKILL.md +441 -0
  168. package/.agent/skills/react-patterns/SKILL.md +198 -0
  169. package/.agent/skills/red-team-tactics/SKILL.md +199 -0
  170. package/.agent/skills/seo-fundamentals/SKILL.md +129 -0
  171. package/.agent/skills/seo-fundamentals/scripts/seo_checker.py +219 -0
  172. package/.agent/skills/server-management/SKILL.md +161 -0
  173. package/.agent/skills/systematic-debugging/SKILL.md +109 -0
  174. package/.agent/skills/tailwind-patterns/SKILL.md +269 -0
  175. package/.agent/skills/tdd-workflow/SKILL.md +149 -0
  176. package/.agent/skills/testing-patterns/SKILL.md +178 -0
  177. package/.agent/skills/testing-patterns/scripts/test_runner.py +219 -0
  178. package/.agent/skills/typescript-expert/SKILL.md +429 -0
  179. package/.agent/skills/typescript-expert/references/tsconfig-strict.json +92 -0
  180. package/.agent/skills/typescript-expert/references/typescript-cheatsheet.md +383 -0
  181. package/.agent/skills/typescript-expert/references/utility-types.ts +335 -0
  182. package/.agent/skills/typescript-expert/scripts/ts_diagnostic.py +203 -0
  183. package/.agent/skills/ui-ux-pro-max/SKILL.md +351 -0
  184. package/.agent/skills/ui-ux-pro-max/data/charts.csv +26 -0
  185. package/.agent/skills/ui-ux-pro-max/data/colors.csv +97 -0
  186. package/.agent/skills/ui-ux-pro-max/data/icons.csv +101 -0
  187. package/.agent/skills/ui-ux-pro-max/data/landing.csv +31 -0
  188. package/.agent/skills/ui-ux-pro-max/data/products.csv +97 -0
  189. package/.agent/skills/ui-ux-pro-max/data/prompts.csv +24 -0
  190. package/.agent/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  191. package/.agent/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  192. package/.agent/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  193. package/.agent/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  194. package/.agent/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  195. package/.agent/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  196. package/.agent/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  197. package/.agent/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  198. package/.agent/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  199. package/.agent/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  200. package/.agent/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  201. package/.agent/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  202. package/.agent/skills/ui-ux-pro-max/data/styles.csv +59 -0
  203. package/.agent/skills/ui-ux-pro-max/data/typography.csv +58 -0
  204. package/.agent/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  205. package/.agent/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  206. package/.agent/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  207. package/.agent/skills/ui-ux-pro-max/scripts/core.py +257 -0
  208. package/.agent/skills/ui-ux-pro-max/scripts/design_system.py +487 -0
  209. package/.agent/skills/ui-ux-pro-max/scripts/search.py +76 -0
  210. package/.agent/skills/vulnerability-scanner/SKILL.md +276 -0
  211. package/.agent/skills/vulnerability-scanner/checklists.md +121 -0
  212. package/.agent/skills/vulnerability-scanner/scripts/security_scan.py +458 -0
  213. package/.agent/skills/webapp-testing/SKILL.md +187 -0
  214. package/.agent/skills/webapp-testing/scripts/playwright_runner.py +173 -0
  215. package/.agent/templates/AGENTS.backend.md +230 -0
  216. package/.agent/templates/AGENTS.md +121 -0
  217. package/.agent/templates/AGENTS.mobile.md +183 -0
  218. package/.agent/templates/AGENTS.web.md +192 -0
  219. package/.agent/workflows/brainstorm.md +113 -0
  220. package/.agent/workflows/context.md +47 -0
  221. package/.agent/workflows/create.md +59 -0
  222. package/.agent/workflows/debug.md +103 -0
  223. package/.agent/workflows/deploy.md +176 -0
  224. package/.agent/workflows/enhance.md +63 -0
  225. package/.agent/workflows/orchestrate.md +237 -0
  226. package/.agent/workflows/plan.md +89 -0
  227. package/.agent/workflows/preview.md +80 -0
  228. package/.agent/workflows/quality.md +89 -0
  229. package/.agent/workflows/status.md +86 -0
  230. package/.agent/workflows/test.md +144 -0
  231. package/.agent/workflows/ui-ux-pro-max.md +250 -0
  232. package/LICENSE +21 -0
  233. package/README.md +317 -0
  234. package/bin/cli.js +1267 -0
  235. package/index.js +1 -0
  236. package/package.json +50 -0
package/bin/cli.js ADDED
@@ -0,0 +1,1267 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
6
+ const { execSync } = require('child_process');
7
+
8
+ const VERSION = require('../package.json').version;
9
+ const PACKAGE_NAME = '@musashishao/agent-kit';
10
+
11
+ // Colors for terminal
12
+ const colors = {
13
+ reset: '\x1b[0m',
14
+ bright: '\x1b[1m',
15
+ green: '\x1b[32m',
16
+ yellow: '\x1b[33m',
17
+ blue: '\x1b[34m',
18
+ magenta: '\x1b[35m',
19
+ cyan: '\x1b[36m',
20
+ red: '\x1b[31m'
21
+ };
22
+
23
+ const log = {
24
+ info: (msg) => console.log(`${colors.blue}ℹ${colors.reset} ${msg}`),
25
+ success: (msg) => console.log(`${colors.green}✔${colors.reset} ${msg}`),
26
+ warn: (msg) => console.log(`${colors.yellow}⚠${colors.reset} ${msg}`),
27
+ error: (msg) => console.log(`${colors.red}✖${colors.reset} ${msg}`),
28
+ title: (msg) => console.log(`\n${colors.bright}${colors.magenta}${msg}${colors.reset}\n`)
29
+ };
30
+
31
+ function showHelp() {
32
+ console.log(`
33
+ ${colors.bright}${colors.cyan}🚀 Musa Agent Kit${colors.reset} v${VERSION}
34
+
35
+ ${colors.bright}Usage:${colors.reset}
36
+ npx ${PACKAGE_NAME} <command> [options]
37
+
38
+ ${colors.bright}Commands:${colors.reset}
39
+ ${colors.cyan}init${colors.reset} Install .agent folder into current project
40
+ ${colors.cyan}setup-codex${colors.reset} Sync workflows with Codex CLI slash commands
41
+ ${colors.cyan}codex${colors.reset} Generate AGENTS.md for Codex CLI (use --template)
42
+ ${colors.cyan}mcp${colors.reset} MCP server management (setup, list, build)
43
+ ${colors.cyan}agents${colors.reset} List all available agents
44
+ ${colors.cyan}skills${colors.reset} List all available skills
45
+ ${colors.cyan}workflows${colors.reset} List all available workflows
46
+ ${colors.cyan}doctor${colors.reset} Check configuration and diagnose issues
47
+ ${colors.cyan}update${colors.reset} Update .agent folder to latest version
48
+ ${colors.cyan}status${colors.reset} Check installation status
49
+
50
+ ${colors.bright}MCP Subcommands:${colors.reset}
51
+ ${colors.cyan}mcp setup${colors.reset} Configure MCP servers for Claude/Cursor
52
+ ${colors.cyan}mcp list${colors.reset} List available MCP servers
53
+ ${colors.cyan}mcp build${colors.reset} Build MCP servers
54
+
55
+ ${colors.bright}Options:${colors.reset}
56
+ --force Overwrite existing files
57
+ --path <dir> Install in specific directory
58
+ --prefix <str> Custom prefix for slash commands (default: kit-)
59
+ --template <type> Template type: web, mobile, backend (for codex command)
60
+ --client <name> MCP client: claude, cursor (for mcp setup)
61
+ --quiet Suppress output
62
+ --help Show this help message
63
+ --version Show version
64
+
65
+ ${colors.bright}Examples:${colors.reset}
66
+ npx ${PACKAGE_NAME} init
67
+ npx ${PACKAGE_NAME} mcp setup --client claude
68
+ npx ${PACKAGE_NAME} codex --template web
69
+ npx ${PACKAGE_NAME} doctor
70
+
71
+ ${colors.yellow}# To ensure you have the latest version from NPM:${colors.reset}
72
+ npx ${PACKAGE_NAME}@latest update
73
+ `);
74
+ }
75
+
76
+
77
+ function showVersion() {
78
+ console.log(`${PACKAGE_NAME} v${VERSION}`);
79
+ }
80
+
81
+ function copyFolderRecursive(src, dest) {
82
+ if (!fs.existsSync(dest)) {
83
+ fs.mkdirSync(dest, { recursive: true });
84
+ }
85
+
86
+ const entries = fs.readdirSync(src, { withFileTypes: true });
87
+
88
+ for (const entry of entries) {
89
+ const srcPath = path.join(src, entry.name);
90
+ const destPath = path.join(dest, entry.name);
91
+
92
+ if (entry.isDirectory()) {
93
+ copyFolderRecursive(srcPath, destPath);
94
+ } else {
95
+ fs.copyFileSync(srcPath, destPath);
96
+ }
97
+ }
98
+ }
99
+
100
+ function countItems(dir) {
101
+ let count = { files: 0, dirs: 0 };
102
+
103
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
104
+ for (const entry of entries) {
105
+ if (entry.isDirectory()) {
106
+ count.dirs++;
107
+ const subCount = countItems(path.join(dir, entry.name));
108
+ count.files += subCount.files;
109
+ count.dirs += subCount.dirs;
110
+ } else {
111
+ count.files++;
112
+ }
113
+ }
114
+
115
+ return count;
116
+ }
117
+
118
+ function initCommand(options) {
119
+ const targetDir = options.path || process.cwd();
120
+ const agentDir = path.join(targetDir, '.agent');
121
+ const quiet = options.quiet;
122
+
123
+ if (!quiet) {
124
+ log.title('🚀 Musa Agent Kit - Installing...');
125
+ }
126
+
127
+ // Check if .agent exists
128
+ if (fs.existsSync(agentDir)) {
129
+ if (!options.force) {
130
+ log.warn('.agent folder already exists!');
131
+ log.info('Use --force to overwrite');
132
+ process.exit(1);
133
+ }
134
+ if (!quiet) log.info('Removing existing .agent folder...');
135
+ fs.rmSync(agentDir, { recursive: true, force: true });
136
+ }
137
+
138
+ // Find source .agent folder
139
+ const packageRoot = path.resolve(__dirname, '..');
140
+ const sourceAgent = path.join(packageRoot, '.agent');
141
+
142
+ if (!fs.existsSync(sourceAgent)) {
143
+ log.error('Source .agent folder not found in package!');
144
+ process.exit(1);
145
+ }
146
+
147
+ // Copy
148
+ if (!quiet) log.info('Copying .agent folder...');
149
+ copyFolderRecursive(sourceAgent, agentDir);
150
+
151
+ // Summary
152
+ const counts = countItems(agentDir);
153
+
154
+ if (!quiet) {
155
+ log.success('Installation complete!');
156
+ console.log(`
157
+ ${colors.bright}📦 Installed:${colors.reset}
158
+ ${colors.cyan}${counts.dirs}${colors.reset} folders
159
+ ${colors.cyan}${counts.files}${colors.reset} files
160
+
161
+ ${colors.bright}📁 Location:${colors.reset} ${agentDir}
162
+
163
+ ${colors.bright}🎯 Quick Start:${colors.reset}
164
+ 1. Open your project in Cursor/VS Code
165
+ 2. Use slash commands: /brainstorm, /create, /debug
166
+ 3. Mention agents: "Use security-auditor to review auth"
167
+
168
+ ${colors.bright}📚 Documentation:${colors.reset}
169
+ See .agent/ARCHITECTURE.md for full guide
170
+ `);
171
+ }
172
+ }
173
+
174
+ function setupCodexCommand(options) {
175
+ const codexPromptDir = path.join(os.homedir(), '.codex', 'prompts');
176
+ const agentDir = path.join(process.cwd(), '.agent');
177
+ const workflowDir = path.join(agentDir, 'workflows');
178
+ const prefix = options.prefix || 'kit-';
179
+
180
+ log.title('🔗 Musa Agent Kit - Syncing with Codex CLI');
181
+
182
+ if (!fs.existsSync(agentDir)) {
183
+ log.error('.agent folder not found. Please run "init" first.');
184
+ process.exit(1);
185
+ }
186
+
187
+ if (!fs.existsSync(codexPromptDir)) {
188
+ log.info('Creating Codex prompt directory...');
189
+ fs.mkdirSync(codexPromptDir, { recursive: true });
190
+ }
191
+
192
+ const workflows = fs.readdirSync(workflowDir).filter(f => f.endsWith('.md'));
193
+
194
+ log.info(`Found ${workflows.length} workflows. Linking to ${codexPromptDir}...`);
195
+
196
+ let successCount = 0;
197
+ for (const wf of workflows) {
198
+ const src = path.join(workflowDir, wf);
199
+ const destName = `${prefix}${wf}`;
200
+ const dest = path.join(codexPromptDir, destName);
201
+
202
+ try {
203
+ if (fs.existsSync(dest)) {
204
+ if (options.force) {
205
+ fs.unlinkSync(dest);
206
+ } else {
207
+ continue;
208
+ }
209
+ }
210
+
211
+ // Use absolute path for symlink
212
+ fs.symlinkSync(src, dest, 'file');
213
+ successCount++;
214
+ } catch (err) {
215
+ // If symlink fails (e.g. on Windows without admin), copy instead
216
+ try {
217
+ fs.copyFileSync(src, dest);
218
+ successCount++;
219
+ } catch (copyErr) {
220
+ log.error(`Failed to sync ${wf}: ${copyErr.message}`);
221
+ }
222
+ }
223
+ }
224
+
225
+ log.success(`Successfully synced ${successCount} slash commands to Codex CLI!`);
226
+ log.info(`You can now use: /${prefix}${workflows[0].replace('.md', '')} in Codex CLI.`);
227
+ }
228
+
229
+ function statusCommand() {
230
+ const agentDir = path.join(process.cwd(), '.agent');
231
+
232
+ log.title('📊 Musa Agent Kit - Status');
233
+
234
+ if (!fs.existsSync(agentDir)) {
235
+ log.warn('.agent folder not found');
236
+ log.info(`Run: npx ${PACKAGE_NAME} init`);
237
+ return;
238
+ }
239
+
240
+ const counts = countItems(agentDir);
241
+ log.success('.agent folder found');
242
+ console.log(`
243
+ ${colors.bright}📦 Contents:${colors.reset}
244
+ ${colors.cyan}${counts.dirs}${colors.reset} folders
245
+ ${colors.cyan}${counts.files}${colors.reset} files
246
+
247
+ ${colors.bright}📁 Components:${colors.reset}`);
248
+
249
+ const components = ['agents', 'skills', 'workflows', 'rules'];
250
+ for (const comp of components) {
251
+ const compDir = path.join(agentDir, comp);
252
+ if (fs.existsSync(compDir)) {
253
+ const items = fs.readdirSync(compDir);
254
+ console.log(` ${colors.green}✔${colors.reset} ${comp}: ${items.length} items`);
255
+ } else {
256
+ console.log(` ${colors.yellow}○${colors.reset} ${comp}: not found`);
257
+ }
258
+ }
259
+ }
260
+
261
+ function updateCommand(options) {
262
+ log.title('🔄 Musa Agent Kit - Updating...');
263
+
264
+ // Re-run init with force
265
+ initCommand({ ...options, force: true });
266
+
267
+ log.success('Update complete!');
268
+ }
269
+
270
+ // ============ NEW COMMANDS ============
271
+
272
+ function codexCommand(options) {
273
+ const targetDir = options.path || process.cwd();
274
+ const template = options.template || 'default';
275
+
276
+ log.title('📝 Musa Agent Kit - Generating AGENTS.md for Codex CLI');
277
+
278
+ const packageRoot = path.resolve(__dirname, '..');
279
+ const templatesDir = path.join(packageRoot, '.agent', 'templates');
280
+
281
+ // Determine template file
282
+ let templateFile;
283
+ switch (template) {
284
+ case 'web':
285
+ templateFile = 'AGENTS.web.md';
286
+ break;
287
+ case 'mobile':
288
+ templateFile = 'AGENTS.mobile.md';
289
+ break;
290
+ case 'backend':
291
+ templateFile = 'AGENTS.backend.md';
292
+ break;
293
+ default:
294
+ templateFile = 'AGENTS.md';
295
+ }
296
+
297
+ const templatePath = path.join(templatesDir, templateFile);
298
+ const destPath = path.join(targetDir, 'AGENTS.md');
299
+
300
+ if (!fs.existsSync(templatePath)) {
301
+ log.error(`Template not found: ${templateFile}`);
302
+ log.info('Available templates: default, web, mobile, backend');
303
+ process.exit(1);
304
+ }
305
+
306
+ if (fs.existsSync(destPath) && !options.force) {
307
+ log.warn('AGENTS.md already exists!');
308
+ log.info('Use --force to overwrite');
309
+ process.exit(1);
310
+ }
311
+
312
+ fs.copyFileSync(templatePath, destPath);
313
+
314
+ log.success(`AGENTS.md created with "${template}" template!`);
315
+ log.info('Edit the file to customize for your project.');
316
+ console.log(`
317
+ ${colors.bright}📄 File created:${colors.reset} ${destPath}
318
+
319
+ ${colors.bright}🎯 Next steps:${colors.reset}
320
+ 1. Edit AGENTS.md with your project details
321
+ 2. Replace [PROJECT_NAME] placeholders
322
+ 3. Update tech stack section
323
+ 4. Codex CLI will now use this config!
324
+ `);
325
+ }
326
+
327
+ function agentsCommand() {
328
+ const agentDir = path.join(process.cwd(), '.agent', 'agents');
329
+
330
+ log.title('🤖 Available Agents');
331
+
332
+ if (!fs.existsSync(agentDir)) {
333
+ log.warn('.agent/agents folder not found. Run "init" first.');
334
+ return;
335
+ }
336
+
337
+ const agents = fs.readdirSync(agentDir).filter(f => f.endsWith('.md'));
338
+
339
+ console.log(`${colors.bright}Found ${agents.length} agents:${colors.reset}\n`);
340
+
341
+ for (const agent of agents) {
342
+ const name = agent.replace('.md', '');
343
+ const content = fs.readFileSync(path.join(agentDir, agent), 'utf-8');
344
+
345
+ // Extract description from frontmatter
346
+ const descMatch = content.match(/description:\s*(.+)/);
347
+ const desc = descMatch ? descMatch[1].substring(0, 60) + '...' : 'No description';
348
+
349
+ console.log(` ${colors.cyan}@${name}${colors.reset}`);
350
+ console.log(` ${colors.yellow}${desc}${colors.reset}\n`);
351
+ }
352
+ }
353
+
354
+ function skillsCommand() {
355
+ const skillsDir = path.join(process.cwd(), '.agent', 'skills');
356
+
357
+ log.title('🧠 Available Skills');
358
+
359
+ if (!fs.existsSync(skillsDir)) {
360
+ log.warn('.agent/skills folder not found. Run "init" first.');
361
+ return;
362
+ }
363
+
364
+ const skills = fs.readdirSync(skillsDir, { withFileTypes: true })
365
+ .filter(d => d.isDirectory());
366
+
367
+ console.log(`${colors.bright}Found ${skills.length} skills:${colors.reset}\n`);
368
+
369
+ const categories = {
370
+ frontend: [],
371
+ backend: [],
372
+ security: [],
373
+ design: [],
374
+ debug: [],
375
+ other: []
376
+ };
377
+
378
+ for (const skill of skills) {
379
+ const skillPath = path.join(skillsDir, skill.name, 'SKILL.md');
380
+ if (fs.existsSync(skillPath)) {
381
+ const content = fs.readFileSync(skillPath, 'utf-8');
382
+ const descMatch = content.match(/description:\s*(.+)/);
383
+ const desc = descMatch ? descMatch[1].substring(0, 50) : '';
384
+
385
+ // Categorize
386
+ if (['react', 'next', 'tailwind', 'frontend'].some(k => skill.name.includes(k))) {
387
+ categories.frontend.push({ name: skill.name, desc });
388
+ } else if (['api', 'node', 'prisma', 'database', 'backend'].some(k => skill.name.includes(k))) {
389
+ categories.backend.push({ name: skill.name, desc });
390
+ } else if (['security', 'vulnerability', 'red-team'].some(k => skill.name.includes(k))) {
391
+ categories.security.push({ name: skill.name, desc });
392
+ } else if (['ui', 'design', 'mobile'].some(k => skill.name.includes(k))) {
393
+ categories.design.push({ name: skill.name, desc });
394
+ } else if (['debug', 'problem'].some(k => skill.name.includes(k))) {
395
+ categories.debug.push({ name: skill.name, desc });
396
+ } else {
397
+ categories.other.push({ name: skill.name, desc });
398
+ }
399
+ }
400
+ }
401
+
402
+ for (const [category, items] of Object.entries(categories)) {
403
+ if (items.length > 0) {
404
+ console.log(`${colors.bright}${category.toUpperCase()}${colors.reset} (${items.length})`);
405
+ for (const item of items) {
406
+ console.log(` ${colors.cyan}${item.name}${colors.reset}`);
407
+ }
408
+ console.log('');
409
+ }
410
+ }
411
+ }
412
+
413
+ function workflowsCommand() {
414
+ const workflowsDir = path.join(process.cwd(), '.agent', 'workflows');
415
+
416
+ log.title('⚡ Available Workflows (Slash Commands)');
417
+
418
+ if (!fs.existsSync(workflowsDir)) {
419
+ log.warn('.agent/workflows folder not found. Run "init" first.');
420
+ return;
421
+ }
422
+
423
+ const workflows = fs.readdirSync(workflowsDir).filter(f => f.endsWith('.md'));
424
+
425
+ console.log(`${colors.bright}Found ${workflows.length} workflows:${colors.reset}\n`);
426
+
427
+ for (const wf of workflows) {
428
+ const name = wf.replace('.md', '');
429
+ const content = fs.readFileSync(path.join(workflowsDir, wf), 'utf-8');
430
+
431
+ const descMatch = content.match(/description:\s*(.+)/);
432
+ const desc = descMatch ? descMatch[1] : 'No description';
433
+
434
+ console.log(` ${colors.green}/${name}${colors.reset}`);
435
+ console.log(` ${desc}\n`);
436
+ }
437
+ }
438
+
439
+ function doctorCommand() {
440
+ log.title('🩺 Agent Kit - Health Check');
441
+
442
+ const cwd = process.cwd();
443
+ const checks = [];
444
+
445
+ // Check 1: .agent folder
446
+ const agentDir = path.join(cwd, '.agent');
447
+ if (fs.existsSync(agentDir)) {
448
+ checks.push({ name: '.agent folder', status: '✅', message: 'Found' });
449
+ } else {
450
+ checks.push({ name: '.agent folder', status: '❌', message: 'Not found - run "init"' });
451
+ }
452
+
453
+ // Check 2: AGENTS.md
454
+ const agentsMd = path.join(cwd, 'AGENTS.md');
455
+ if (fs.existsSync(agentsMd)) {
456
+ checks.push({ name: 'AGENTS.md', status: '✅', message: 'Found (Codex CLI ready)' });
457
+ } else {
458
+ checks.push({ name: 'AGENTS.md', status: '⚠️', message: 'Not found - run "codex"' });
459
+ }
460
+
461
+ // Check 3: .codex folder
462
+ const codexDir = path.join(cwd, '.codex');
463
+ if (fs.existsSync(codexDir)) {
464
+ checks.push({ name: '.codex folder', status: '✅', message: 'Found' });
465
+ } else {
466
+ checks.push({ name: '.codex folder', status: '⚠️', message: 'Optional - not found' });
467
+ }
468
+
469
+ // Check 4: Agents count
470
+ if (fs.existsSync(path.join(agentDir, 'agents'))) {
471
+ const count = fs.readdirSync(path.join(agentDir, 'agents')).length;
472
+ checks.push({ name: 'Agents', status: '✅', message: `${count} available` });
473
+ }
474
+
475
+ // Check 5: Skills count
476
+ if (fs.existsSync(path.join(agentDir, 'skills'))) {
477
+ const count = fs.readdirSync(path.join(agentDir, 'skills')).length;
478
+ checks.push({ name: 'Skills', status: '✅', message: `${count} available` });
479
+ }
480
+
481
+ // Check 6: Workflows count
482
+ if (fs.existsSync(path.join(agentDir, 'workflows'))) {
483
+ const count = fs.readdirSync(path.join(agentDir, 'workflows')).length;
484
+ checks.push({ name: 'Workflows', status: '✅', message: `${count} available` });
485
+ }
486
+
487
+ // Check 7: Codex CLI global prompts
488
+ const codexPromptDir = path.join(os.homedir(), '.codex', 'prompts');
489
+ if (fs.existsSync(codexPromptDir)) {
490
+ const prompts = fs.readdirSync(codexPromptDir).filter(f => f.startsWith('kit-'));
491
+ if (prompts.length > 0) {
492
+ checks.push({ name: 'Codex slash commands', status: '✅', message: `${prompts.length} synced` });
493
+ } else {
494
+ checks.push({ name: 'Codex slash commands', status: '⚠️', message: 'Not synced - run "setup-codex"' });
495
+ }
496
+ } else {
497
+ checks.push({ name: 'Codex prompts dir', status: '⚠️', message: 'Not found' });
498
+ }
499
+
500
+ // Display results
501
+ console.log(`${colors.bright}Diagnostic Results:${colors.reset}\n`);
502
+
503
+ for (const check of checks) {
504
+ console.log(` ${check.status} ${colors.cyan}${check.name}${colors.reset}: ${check.message}`);
505
+ }
506
+
507
+ const hasErrors = checks.some(c => c.status === '❌');
508
+ const hasWarnings = checks.some(c => c.status === '⚠️');
509
+
510
+ console.log('');
511
+ if (hasErrors) {
512
+ log.error('Some critical checks failed. Run suggested commands to fix.');
513
+ } else if (hasWarnings) {
514
+ log.warn('Some optional configurations missing. Consider running suggested commands.');
515
+ } else {
516
+ log.success('All checks passed! Agent Kit is ready.');
517
+ }
518
+ }
519
+
520
+ // ============================================================================
521
+ // MCP Command
522
+ // ============================================================================
523
+
524
+ function mcpCommand(subArgs, options) {
525
+ const subCommand = subArgs[0];
526
+ const agentDir = path.join(process.cwd(), '.agent');
527
+ const mcpDir = path.join(agentDir, 'mcp');
528
+ const serversDir = path.join(mcpDir, 'servers');
529
+
530
+ if (!fs.existsSync(agentDir)) {
531
+ log.error('.agent folder not found. Run: npx @musashishao/agent-kit init');
532
+ process.exit(1);
533
+ }
534
+
535
+ switch (subCommand) {
536
+ case 'setup':
537
+ mcpSetup(options);
538
+ break;
539
+ case 'list':
540
+ mcpList();
541
+ break;
542
+ case 'build':
543
+ mcpBuild();
544
+ break;
545
+ case 'status':
546
+ mcpStatus();
547
+ break;
548
+ case 'create':
549
+ mcpCreate(subArgs.slice(1), options);
550
+ break;
551
+ case 'templates':
552
+ mcpTemplates();
553
+ break;
554
+ case 'search':
555
+ mcpSearch(subArgs.slice(1));
556
+ break;
557
+ case 'install':
558
+ mcpInstall(subArgs.slice(1), options);
559
+ break;
560
+ case 'featured':
561
+ mcpFeatured();
562
+ break;
563
+ default:
564
+ console.log(`
565
+ ${colors.bright}${colors.cyan}🔌 Agent Kit MCP${colors.reset}
566
+
567
+ ${colors.bright}Subcommands:${colors.reset}
568
+ ${colors.cyan}mcp setup${colors.reset} Configure MCP servers for your AI client
569
+ ${colors.cyan}mcp list${colors.reset} List available MCP servers
570
+ ${colors.cyan}mcp build${colors.reset} Build all MCP servers
571
+ ${colors.cyan}mcp status${colors.reset} Check MCP server status
572
+ ${colors.cyan}mcp create${colors.reset} Create new MCP server from template
573
+ ${colors.cyan}mcp templates${colors.reset} List available templates
574
+ ${colors.cyan}mcp search${colors.reset} Search MCP servers on npm
575
+ ${colors.cyan}mcp install${colors.reset} Install MCP server from npm
576
+ ${colors.cyan}mcp featured${colors.reset} Show featured MCP servers
577
+
578
+ ${colors.bright}Options:${colors.reset}
579
+ --client <name> AI client: claude, cursor (for setup)
580
+ --type <template> Template type: api, database, web-scraper, custom
581
+ --force Overwrite existing
582
+
583
+ ${colors.bright}Examples:${colors.reset}
584
+ npx @musashishao/agent-kit mcp setup --client claude
585
+ npx @musashishao/agent-kit mcp create my-api --type api
586
+ npx @musashishao/agent-kit mcp search github
587
+ npx @musashishao/agent-kit mcp install @anthropic/mcp-server-github
588
+ npx @musashishao/agent-kit mcp featured
589
+ `);
590
+ }
591
+ }
592
+
593
+ function mcpSetup(options) {
594
+ log.title('🔌 MCP Server Setup');
595
+
596
+ const agentDir = path.join(process.cwd(), '.agent');
597
+ const mcpDir = path.join(agentDir, 'mcp');
598
+ const serversDir = path.join(mcpDir, 'servers');
599
+
600
+ if (!fs.existsSync(serversDir)) {
601
+ log.error('MCP servers not found. Make sure Agent Kit is up to date.');
602
+ process.exit(1);
603
+ }
604
+
605
+ const clientIndex = process.argv.indexOf('--client');
606
+ const client = clientIndex !== -1 ? process.argv[clientIndex + 1] : 'claude';
607
+
608
+ const servers = fs.readdirSync(serversDir).filter(f =>
609
+ fs.statSync(path.join(serversDir, f)).isDirectory()
610
+ );
611
+
612
+ log.info(`Found ${servers.length} MCP servers`);
613
+
614
+ // Generate config based on client
615
+ const projectRoot = process.cwd();
616
+
617
+ if (client === 'claude') {
618
+ const claudeConfigPath = path.join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
619
+
620
+ let existingConfig = {};
621
+ if (fs.existsSync(claudeConfigPath)) {
622
+ try {
623
+ existingConfig = JSON.parse(fs.readFileSync(claudeConfigPath, 'utf-8'));
624
+ } catch {
625
+ existingConfig = {};
626
+ }
627
+ }
628
+
629
+ if (!existingConfig.mcpServers) {
630
+ existingConfig.mcpServers = {};
631
+ }
632
+
633
+ // Add each server
634
+ for (const server of servers) {
635
+ const serverPath = path.join(serversDir, server, 'dist', 'index.js');
636
+ existingConfig.mcpServers[server] = {
637
+ command: 'node',
638
+ args: [serverPath],
639
+ cwd: projectRoot
640
+ };
641
+ log.success(`Added ${server} to Claude config`);
642
+ }
643
+
644
+ // Write config
645
+ const configDir = path.dirname(claudeConfigPath);
646
+ if (!fs.existsSync(configDir)) {
647
+ fs.mkdirSync(configDir, { recursive: true });
648
+ }
649
+
650
+ fs.writeFileSync(claudeConfigPath, JSON.stringify(existingConfig, null, 2));
651
+ log.success(`Claude Desktop config updated: ${claudeConfigPath}`);
652
+
653
+ console.log(`
654
+ ${colors.yellow}⚠️ Important:${colors.reset}
655
+ 1. Build MCP servers first: ${colors.cyan}npx @musashishao/agent-kit mcp build${colors.reset}
656
+ 2. Restart Claude Desktop to apply changes
657
+ `);
658
+
659
+ } else if (client === 'cursor') {
660
+ const cursorDir = path.join(projectRoot, '.cursor');
661
+ const cursorConfigPath = path.join(cursorDir, 'mcp.json');
662
+
663
+ if (!fs.existsSync(cursorDir)) {
664
+ fs.mkdirSync(cursorDir, { recursive: true });
665
+ }
666
+
667
+ const config = { mcpServers: {} };
668
+
669
+ for (const server of servers) {
670
+ const serverPath = path.join(serversDir, server, 'dist', 'index.js');
671
+ config.mcpServers[server] = {
672
+ command: 'node',
673
+ args: [serverPath]
674
+ };
675
+ log.success(`Added ${server}`);
676
+ }
677
+
678
+ fs.writeFileSync(cursorConfigPath, JSON.stringify(config, null, 2));
679
+ log.success(`Cursor config created: ${cursorConfigPath}`);
680
+
681
+ } else {
682
+ log.error(`Unknown client: ${client}. Use 'claude' or 'cursor'`);
683
+ process.exit(1);
684
+ }
685
+ }
686
+
687
+ function mcpList() {
688
+ log.title('🔌 Available MCP Servers');
689
+
690
+ const serversDir = path.join(process.cwd(), '.agent', 'mcp', 'servers');
691
+
692
+ if (!fs.existsSync(serversDir)) {
693
+ log.warn('No MCP servers found');
694
+ return;
695
+ }
696
+
697
+ const servers = fs.readdirSync(serversDir).filter(f =>
698
+ fs.statSync(path.join(serversDir, f)).isDirectory()
699
+ );
700
+
701
+ console.log(`Found ${servers.length} servers:\n`);
702
+
703
+ for (const server of servers) {
704
+ const packagePath = path.join(serversDir, server, 'package.json');
705
+ let description = 'No description';
706
+
707
+ if (fs.existsSync(packagePath)) {
708
+ try {
709
+ const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf-8'));
710
+ description = pkg.description || description;
711
+ } catch {}
712
+ }
713
+
714
+ const distExists = fs.existsSync(path.join(serversDir, server, 'dist'));
715
+ const status = distExists ? `${colors.green}✓ Built${colors.reset}` : `${colors.yellow}○ Not built${colors.reset}`;
716
+
717
+ console.log(` ${colors.cyan}${server}${colors.reset} ${status}`);
718
+ console.log(` ${description}\n`);
719
+ }
720
+ }
721
+
722
+ function mcpBuild() {
723
+ log.title('🔨 Building MCP Servers');
724
+
725
+ const serversDir = path.join(process.cwd(), '.agent', 'mcp', 'servers');
726
+
727
+ if (!fs.existsSync(serversDir)) {
728
+ log.error('No MCP servers found');
729
+ process.exit(1);
730
+ }
731
+
732
+ const servers = fs.readdirSync(serversDir).filter(f =>
733
+ fs.statSync(path.join(serversDir, f)).isDirectory()
734
+ );
735
+
736
+ let successCount = 0;
737
+
738
+ for (const server of servers) {
739
+ const serverPath = path.join(serversDir, server);
740
+ const packagePath = path.join(serverPath, 'package.json');
741
+
742
+ if (!fs.existsSync(packagePath)) {
743
+ log.warn(`Skipping ${server}: no package.json`);
744
+ continue;
745
+ }
746
+
747
+ log.info(`Building ${server}...`);
748
+
749
+ try {
750
+ // Install dependencies
751
+ execSync('npm install', {
752
+ cwd: serverPath,
753
+ stdio: 'pipe',
754
+ timeout: 120000
755
+ });
756
+
757
+ // Build
758
+ execSync('npm run build', {
759
+ cwd: serverPath,
760
+ stdio: 'pipe',
761
+ timeout: 60000
762
+ });
763
+
764
+ log.success(`Built ${server}`);
765
+ successCount++;
766
+ } catch (error) {
767
+ log.error(`Failed to build ${server}: ${error.message}`);
768
+ }
769
+ }
770
+
771
+ console.log('');
772
+ if (successCount === servers.length) {
773
+ log.success(`All ${successCount} servers built successfully!`);
774
+ console.log(`\n${colors.bright}Next:${colors.reset} Run ${colors.cyan}npx @musashishao/agent-kit mcp setup --client claude${colors.reset}`);
775
+ } else {
776
+ log.warn(`Built ${successCount}/${servers.length} servers`);
777
+ }
778
+ }
779
+
780
+ function mcpStatus() {
781
+ log.title('🔌 MCP Status');
782
+
783
+ const serversDir = path.join(process.cwd(), '.agent', 'mcp', 'servers');
784
+
785
+ if (!fs.existsSync(serversDir)) {
786
+ log.warn('MCP not configured');
787
+ return;
788
+ }
789
+
790
+ const servers = fs.readdirSync(serversDir).filter(f =>
791
+ fs.statSync(path.join(serversDir, f)).isDirectory()
792
+ );
793
+
794
+ console.log(`\n${colors.bright}Servers:${colors.reset}`);
795
+ for (const server of servers) {
796
+ const distExists = fs.existsSync(path.join(serversDir, server, 'dist'));
797
+ const status = distExists ? `${colors.green}✓${colors.reset}` : `${colors.red}✗${colors.reset}`;
798
+ console.log(` ${status} ${server}`);
799
+ }
800
+
801
+ // Check Claude config
802
+ const claudeConfigPath = path.join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
803
+ const claudeConfigured = fs.existsSync(claudeConfigPath);
804
+
805
+ // Check Cursor config
806
+ const cursorConfigPath = path.join(process.cwd(), '.cursor', 'mcp.json');
807
+ const cursorConfigured = fs.existsSync(cursorConfigPath);
808
+
809
+ console.log(`\n${colors.bright}Clients:${colors.reset}`);
810
+ console.log(` ${claudeConfigured ? `${colors.green}✓${colors.reset}` : `${colors.yellow}○${colors.reset}`} Claude Desktop`);
811
+ console.log(` ${cursorConfigured ? `${colors.green}✓${colors.reset}` : `${colors.yellow}○${colors.reset}`} Cursor`);
812
+ }
813
+
814
+ // ============================================================================
815
+ // MCP Create Command
816
+ // ============================================================================
817
+
818
+ function mcpCreate(createArgs, options) {
819
+ const serverName = createArgs[0];
820
+
821
+ if (!serverName) {
822
+ log.error('Please provide a server name: mcp create <name> --type <template>');
823
+ process.exit(1);
824
+ }
825
+
826
+ // Get template type
827
+ const typeIndex = process.argv.indexOf('--type');
828
+ const templateType = typeIndex !== -1 ? process.argv[typeIndex + 1] : 'custom';
829
+
830
+ const validTemplates = ['api', 'database', 'web-scraper', 'custom'];
831
+ if (!validTemplates.includes(templateType)) {
832
+ log.error(`Invalid template type: ${templateType}`);
833
+ log.info(`Valid types: ${validTemplates.join(', ')}`);
834
+ process.exit(1);
835
+ }
836
+
837
+ log.title(`🔌 Creating MCP Server: ${serverName}`);
838
+ log.info(`Template: ${templateType}`);
839
+
840
+ const agentDir = path.join(process.cwd(), '.agent');
841
+ const mcpDir = path.join(agentDir, 'mcp');
842
+ const templatesDir = path.join(mcpDir, 'templates');
843
+ const serversDir = path.join(mcpDir, 'servers');
844
+ const targetDir = path.join(serversDir, serverName);
845
+
846
+ // Check if server already exists
847
+ if (fs.existsSync(targetDir)) {
848
+ if (!options.force) {
849
+ log.error(`Server '${serverName}' already exists. Use --force to overwrite.`);
850
+ process.exit(1);
851
+ }
852
+ fs.rmSync(targetDir, { recursive: true, force: true });
853
+ }
854
+
855
+ // Create target directory
856
+ fs.mkdirSync(path.join(targetDir, 'src'), { recursive: true });
857
+
858
+ // Copy and process template files
859
+ const templateDir = path.join(templatesDir, templateType);
860
+ const basePackage = path.join(templatesDir, 'base-package.json.template');
861
+ const baseTsconfig = path.join(templatesDir, 'base-tsconfig.json');
862
+
863
+ // Process package.json
864
+ if (fs.existsSync(basePackage)) {
865
+ let packageContent = fs.readFileSync(basePackage, 'utf-8');
866
+ packageContent = packageContent
867
+ .replace(/\{\{SERVER_NAME\}\}/g, serverName)
868
+ .replace(/\{\{DESCRIPTION\}\}/g, `${templateType} integration`);
869
+
870
+ // Add extra dependencies based on template
871
+ const pkg = JSON.parse(packageContent);
872
+ if (templateType === 'database') {
873
+ pkg.dependencies['better-sqlite3'] = '^11.0.0';
874
+ pkg.devDependencies['@types/better-sqlite3'] = '^7.6.0';
875
+ }
876
+
877
+ fs.writeFileSync(path.join(targetDir, 'package.json'), JSON.stringify(pkg, null, 2));
878
+ log.success('Created package.json');
879
+ }
880
+
881
+ // Copy tsconfig
882
+ if (fs.existsSync(baseTsconfig)) {
883
+ fs.copyFileSync(baseTsconfig, path.join(targetDir, 'tsconfig.json'));
884
+ log.success('Created tsconfig.json');
885
+ }
886
+
887
+ // Process main template file
888
+ const templateSrc = path.join(templateDir, 'src', 'index.ts.template');
889
+ if (fs.existsSync(templateSrc)) {
890
+ let srcContent = fs.readFileSync(templateSrc, 'utf-8');
891
+ srcContent = srcContent.replace(/\{\{SERVER_NAME\}\}/g, serverName);
892
+ fs.writeFileSync(path.join(targetDir, 'src', 'index.ts'), srcContent);
893
+ log.success('Created src/index.ts');
894
+ }
895
+
896
+ // Copy README if exists
897
+ const templateReadme = path.join(templateDir, 'README.md.template');
898
+ if (fs.existsSync(templateReadme)) {
899
+ let readmeContent = fs.readFileSync(templateReadme, 'utf-8');
900
+ readmeContent = readmeContent.replace(/\{\{SERVER_NAME\}\}/g, serverName);
901
+ fs.writeFileSync(path.join(targetDir, 'README.md'), readmeContent);
902
+ log.success('Created README.md');
903
+ }
904
+
905
+ console.log(`
906
+ ${colors.bright}${colors.green}✔ MCP Server created successfully!${colors.reset}
907
+
908
+ ${colors.bright}Location:${colors.reset} ${targetDir}
909
+
910
+ ${colors.bright}Next steps:${colors.reset}
911
+ 1. ${colors.cyan}cd ${targetDir}${colors.reset}
912
+ 2. ${colors.cyan}npm install${colors.reset}
913
+ 3. Edit ${colors.cyan}src/index.ts${colors.reset} to customize your server
914
+ 4. ${colors.cyan}npm run build${colors.reset}
915
+ 5. ${colors.cyan}npx @musashishao/agent-kit mcp setup --client claude${colors.reset}
916
+ `);
917
+ }
918
+
919
+ function mcpTemplates() {
920
+ log.title('🔌 Available MCP Templates');
921
+
922
+ const templates = [
923
+ {
924
+ name: 'api',
925
+ description: 'REST API integration',
926
+ tools: ['api_get', 'api_post', 'api_list_endpoints'],
927
+ useCase: 'Connect to external REST APIs',
928
+ },
929
+ {
930
+ name: 'database',
931
+ description: 'SQLite database connector',
932
+ tools: ['db_query', 'db_schema', 'db_tables', 'db_describe'],
933
+ useCase: 'Query and analyze databases',
934
+ },
935
+ {
936
+ name: 'web-scraper',
937
+ description: 'Web page scraper',
938
+ tools: ['scrape_url', 'extract_links', 'extract_metadata'],
939
+ useCase: 'Extract data from websites',
940
+ },
941
+ {
942
+ name: 'custom',
943
+ description: 'Minimal template',
944
+ tools: ['hello', 'calculate'],
945
+ useCase: 'Build from scratch',
946
+ },
947
+ ];
948
+
949
+ for (const t of templates) {
950
+ console.log(`
951
+ ${colors.cyan}${colors.bright}${t.name}${colors.reset}
952
+ ${t.description}
953
+ ${colors.yellow}Tools:${colors.reset} ${t.tools.join(', ')}
954
+ ${colors.yellow}Use case:${colors.reset} ${t.useCase}`);
955
+ }
956
+
957
+ console.log(`
958
+
959
+ ${colors.bright}Usage:${colors.reset}
960
+ npx @musashishao/agent-kit mcp create <server-name> --type <template>
961
+
962
+ ${colors.bright}Example:${colors.reset}
963
+ npx @musashishao/agent-kit mcp create github-api --type api
964
+ `);
965
+ }
966
+
967
+ // ============================================================================
968
+ // MCP Registry Commands
969
+ // ============================================================================
970
+
971
+ async function mcpSearch(searchArgs) {
972
+ const query = searchArgs.join(' ');
973
+
974
+ if (!query) {
975
+ log.error('Please provide a search query: mcp search <query>');
976
+ process.exit(1);
977
+ }
978
+
979
+ log.title(`🔍 Searching MCP servers: "${query}"`);
980
+
981
+ try {
982
+ // Search npm registry
983
+ const https = require('https');
984
+
985
+ const searchUrl = `https://registry.npmjs.org/-/v1/search?text=mcp+${encodeURIComponent(query)}&size=15`;
986
+
987
+ const data = await new Promise((resolve, reject) => {
988
+ https.get(searchUrl, (res) => {
989
+ let body = '';
990
+ res.on('data', chunk => body += chunk);
991
+ res.on('end', () => {
992
+ try {
993
+ resolve(JSON.parse(body));
994
+ } catch (e) {
995
+ reject(new Error('Failed to parse response'));
996
+ }
997
+ });
998
+ }).on('error', reject);
999
+ });
1000
+
1001
+ if (!data.objects || data.objects.length === 0) {
1002
+ log.warn('No MCP servers found matching your query');
1003
+ return;
1004
+ }
1005
+
1006
+ console.log(`\nFound ${data.objects.length} packages:\n`);
1007
+
1008
+ for (const pkg of data.objects) {
1009
+ const name = pkg.package.name;
1010
+ const desc = pkg.package.description || 'No description';
1011
+ const version = pkg.package.version;
1012
+
1013
+ console.log(` ${colors.cyan}${name}${colors.reset} ${colors.yellow}v${version}${colors.reset}`);
1014
+ console.log(` ${desc.slice(0, 80)}${desc.length > 80 ? '...' : ''}\n`);
1015
+ }
1016
+
1017
+ console.log(`${colors.bright}Install with:${colors.reset}`);
1018
+ console.log(` npx @musashishao/agent-kit mcp install <package-name>\n`);
1019
+
1020
+ } catch (error) {
1021
+ log.error(`Search failed: ${error.message}`);
1022
+ }
1023
+ }
1024
+
1025
+ async function mcpInstall(installArgs, options) {
1026
+ const packageName = installArgs[0];
1027
+
1028
+ if (!packageName) {
1029
+ log.error('Please provide a package name: mcp install <package>');
1030
+ process.exit(1);
1031
+ }
1032
+
1033
+ log.title(`📦 Installing MCP Server: ${packageName}`);
1034
+
1035
+ const agentDir = path.join(process.cwd(), '.agent');
1036
+ const mcpDir = path.join(agentDir, 'mcp');
1037
+ const externalDir = path.join(mcpDir, 'external');
1038
+
1039
+ // Create external directory if needed
1040
+ if (!fs.existsSync(externalDir)) {
1041
+ fs.mkdirSync(externalDir, { recursive: true });
1042
+ }
1043
+
1044
+ try {
1045
+ // Install package globally or in external dir
1046
+ log.info(`Installing ${packageName}...`);
1047
+
1048
+ execSync(`npm install ${packageName}`, {
1049
+ cwd: externalDir,
1050
+ stdio: 'pipe',
1051
+ timeout: 120000
1052
+ });
1053
+
1054
+ log.success(`Installed ${packageName}`);
1055
+
1056
+ // Try to find the package and get its binary
1057
+ const packagePath = path.join(externalDir, 'node_modules', packageName);
1058
+ let binPath = null;
1059
+
1060
+ if (fs.existsSync(path.join(packagePath, 'package.json'))) {
1061
+ const pkg = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json'), 'utf-8'));
1062
+
1063
+ if (pkg.bin) {
1064
+ const binName = typeof pkg.bin === 'string' ? packageName : Object.keys(pkg.bin)[0];
1065
+ const binFile = typeof pkg.bin === 'string' ? pkg.bin : pkg.bin[binName];
1066
+ binPath = path.join(packagePath, binFile);
1067
+ } else if (pkg.main) {
1068
+ binPath = path.join(packagePath, pkg.main);
1069
+ }
1070
+ }
1071
+
1072
+ // Save to installed registry
1073
+ const registryPath = path.join(mcpDir, 'config', 'registry.json');
1074
+ let registry = { installed: [] };
1075
+
1076
+ if (fs.existsSync(registryPath)) {
1077
+ try {
1078
+ registry = JSON.parse(fs.readFileSync(registryPath, 'utf-8'));
1079
+ } catch {}
1080
+ }
1081
+
1082
+ if (!registry.installed) registry.installed = [];
1083
+
1084
+ // Add to installed list
1085
+ const existing = registry.installed.findIndex(i => i.name === packageName);
1086
+ const installInfo = {
1087
+ name: packageName,
1088
+ path: binPath || packagePath,
1089
+ installedAt: new Date().toISOString()
1090
+ };
1091
+
1092
+ if (existing >= 0) {
1093
+ registry.installed[existing] = installInfo;
1094
+ } else {
1095
+ registry.installed.push(installInfo);
1096
+ }
1097
+
1098
+ fs.writeFileSync(registryPath, JSON.stringify(registry, null, 2));
1099
+
1100
+ console.log(`
1101
+ ${colors.bright}${colors.green}✔ Installation complete!${colors.reset}
1102
+
1103
+ ${colors.bright}Package:${colors.reset} ${packageName}
1104
+ ${colors.bright}Location:${colors.reset} ${externalDir}/node_modules/${packageName}
1105
+
1106
+ ${colors.bright}Next steps:${colors.reset}
1107
+ 1. Run ${colors.cyan}npx @musashishao/agent-kit mcp setup --client claude${colors.reset}
1108
+ 2. Restart Claude Desktop
1109
+ `);
1110
+
1111
+ } catch (error) {
1112
+ log.error(`Installation failed: ${error.message}`);
1113
+ process.exit(1);
1114
+ }
1115
+ }
1116
+
1117
+ function mcpFeatured() {
1118
+ log.title('⭐ Featured MCP Servers');
1119
+
1120
+ const featured = [
1121
+ {
1122
+ name: '@anthropic/mcp-server-filesystem',
1123
+ description: 'Secure file system access for AI',
1124
+ category: 'File Systems',
1125
+ official: true
1126
+ },
1127
+ {
1128
+ name: '@anthropic/mcp-server-sqlite',
1129
+ description: 'SQLite database integration',
1130
+ category: 'Databases',
1131
+ official: true
1132
+ },
1133
+ {
1134
+ name: '@anthropic/mcp-server-github',
1135
+ description: 'GitHub API - repos, issues, PRs',
1136
+ category: 'Developer Tools',
1137
+ official: true
1138
+ },
1139
+ {
1140
+ name: '@anthropic/mcp-server-memory',
1141
+ description: 'Persistent memory/knowledge graph',
1142
+ category: 'Knowledge',
1143
+ official: true
1144
+ },
1145
+ {
1146
+ name: 'playwright-mcp',
1147
+ description: 'Browser automation with Playwright',
1148
+ category: 'Browser Automation',
1149
+ official: false
1150
+ },
1151
+ {
1152
+ name: 'mcp-server-fetch',
1153
+ description: 'HTTP requests and web fetching',
1154
+ category: 'Web',
1155
+ official: false
1156
+ },
1157
+ {
1158
+ name: '@anthropic/mcp-server-postgres',
1159
+ description: 'PostgreSQL database integration',
1160
+ category: 'Databases',
1161
+ official: true
1162
+ },
1163
+ {
1164
+ name: 'mcp-server-slack',
1165
+ description: 'Slack workspace integration',
1166
+ category: 'Communication',
1167
+ official: false
1168
+ }
1169
+ ];
1170
+
1171
+ console.log('\n');
1172
+
1173
+ for (const server of featured) {
1174
+ const badge = server.official ? `${colors.green}[Official]${colors.reset}` : '';
1175
+ console.log(` ${colors.cyan}${colors.bright}${server.name}${colors.reset} ${badge}`);
1176
+ console.log(` ${server.description}`);
1177
+ console.log(` ${colors.yellow}Category:${colors.reset} ${server.category}\n`);
1178
+ }
1179
+
1180
+ console.log(`
1181
+ ${colors.bright}Install with:${colors.reset}
1182
+ npx @musashishao/agent-kit mcp install <package-name>
1183
+
1184
+ ${colors.bright}Example:${colors.reset}
1185
+ npx @musashishao/agent-kit mcp install @anthropic/mcp-server-github
1186
+
1187
+ ${colors.bright}More servers:${colors.reset}
1188
+ https://github.com/punkpeye/awesome-mcp-servers
1189
+ `);
1190
+ }
1191
+
1192
+ // Parse arguments
1193
+ const args = process.argv.slice(2);
1194
+ const command = args[0];
1195
+
1196
+ const options = {
1197
+ force: args.includes('--force'),
1198
+ quiet: args.includes('--quiet'),
1199
+ path: null,
1200
+ prefix: null,
1201
+ template: null
1202
+ };
1203
+
1204
+ // Parse --path
1205
+ const pathIndex = args.indexOf('--path');
1206
+ if (pathIndex !== -1 && args[pathIndex + 1]) {
1207
+ options.path = path.resolve(args[pathIndex + 1]);
1208
+ }
1209
+
1210
+ // Parse --prefix
1211
+ const prefixIndex = args.indexOf('--prefix');
1212
+ if (prefixIndex !== -1 && args[prefixIndex + 1]) {
1213
+ options.prefix = args[prefixIndex + 1];
1214
+ }
1215
+
1216
+ // Parse --template
1217
+ const templateIndex = args.indexOf('--template');
1218
+ if (templateIndex !== -1 && args[templateIndex + 1]) {
1219
+ options.template = args[templateIndex + 1];
1220
+ }
1221
+
1222
+ // Execute command
1223
+ switch (command) {
1224
+ case 'init':
1225
+ initCommand(options);
1226
+ break;
1227
+ case 'setup-codex':
1228
+ setupCodexCommand(options);
1229
+ break;
1230
+ case 'codex':
1231
+ codexCommand(options);
1232
+ break;
1233
+ case 'mcp':
1234
+ mcpCommand(args.slice(1), options);
1235
+ break;
1236
+ case 'agents':
1237
+ agentsCommand();
1238
+ break;
1239
+ case 'skills':
1240
+ skillsCommand();
1241
+ break;
1242
+ case 'workflows':
1243
+ workflowsCommand();
1244
+ break;
1245
+ case 'doctor':
1246
+ doctorCommand();
1247
+ break;
1248
+ case 'update':
1249
+ updateCommand(options);
1250
+ break;
1251
+ case 'status':
1252
+ statusCommand();
1253
+ break;
1254
+ case '--version':
1255
+ case '-v':
1256
+ showVersion();
1257
+ break;
1258
+ case '--help':
1259
+ case '-h':
1260
+ case undefined:
1261
+ showHelp();
1262
+ break;
1263
+ default:
1264
+ log.error(`Unknown command: ${command}`);
1265
+ showHelp();
1266
+ process.exit(1);
1267
+ }