UNPKG

@iqai/adk-cli

Version:

CLI tool for creating, running, and testing ADK-TS agents

372 lines (370 loc) โ€ข 16.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.NewCommand = void 0; const node_fs_1 = require("node:fs"); const node_path_1 = require("node:path"); const prompts_1 = require("@clack/prompts"); const chalk_1 = __importDefault(require("chalk")); const dedent_1 = __importDefault(require("dedent")); const giget_1 = require("giget"); const nest_commander_1 = require("nest-commander"); const templates = [ { value: "simple-agent", label: "๐Ÿค– Simple Agent", hint: "Basic agent with chat capabilities", source: "github:IQAIcom/adk-ts/apps/starter-templates/simple-agent", }, { value: "discord-bot", label: "๐ŸŽฎ Discord Bot", hint: "Agent integrated with Discord", source: "github:IQAIcom/adk-ts/apps/starter-templates/discord-bot", }, { value: "telegram-bot", label: "๐Ÿ“ฑ Telegram Bot", hint: "Agent integrated with Telegram", source: "github:IQAIcom/adk-ts/apps/starter-templates/telegram-bot", }, { value: "hono-server", label: "๐Ÿš€ Hono Server", hint: "Web server with agent endpoints", source: "github:IQAIcom/adk-ts/apps/starter-templates/hono-server", }, { value: "mcp-starter", label: "๐Ÿ”Œ MCP Integration", hint: "Model Context Protocol server", source: "github:IQAIcom/adk-ts/apps/starter-templates/mcp-starter", }, { value: "shade-agent", label: "๐ŸŒ“ Near Shade Agent", hint: "Starter that uses Near Shade Agent", source: "github:IQAIcom/adk-ts/apps/starter-templates/shade-agent", }, { value: "next-js-starter", label: "โšก Next.js Starter", hint: "Full-stack agent app using Next.js and Tailwind", source: "github:IQAIcom/adk-ts/apps/starter-templates/next-js-starter", }, ]; const packageManagers = [ { name: "npm", command: "npm", args: ["install"], label: "๐Ÿ“ฆ npm" }, { name: "pnpm", command: "pnpm", args: ["install"], label: "โšก pnpm" }, { name: "yarn", command: "yarn", args: ["install"], label: "๐Ÿงถ yarn" }, { name: "bun", command: "bun", args: ["install"], label: "๐Ÿž bun" }, ]; async function detectAvailablePackageManagers() { const { spawn } = await Promise.resolve().then(() => __importStar(require("node:child_process"))); const available = []; for (const pm of packageManagers) { try { await new Promise((resolve) => { const child = spawn(pm.command, ["--version"], { stdio: "pipe" }); child.on("close", (code) => { if (code === 0) available.push(pm); resolve(); }); child.on("error", () => resolve()); }); } catch { // ignore } } return available.length > 0 ? available : [packageManagers[0]]; } let NewCommand = class NewCommand extends nest_commander_1.CommandRunner { async run(passedParams, options) { const projectNameArg = passedParams?.[0]; console.clear(); (0, prompts_1.intro)(chalk_1.default.magentaBright("๐Ÿง  Create new ADK-TS project")); let finalProjectName = projectNameArg; if (!finalProjectName) { const response = await (0, prompts_1.text)({ message: "What is your project name?", placeholder: "my-adk-project", validate: (value) => { if (!value) return "Project name is required"; if (value.includes(" ")) return "Project name cannot contain spaces"; if ((0, node_fs_1.existsSync)(value)) return `Directory "${value}" already exists`; return undefined; }, }); if (typeof response === "symbol") { (0, prompts_1.outro)("Operation cancelled"); process.exit(0); } finalProjectName = response; } let selectedTemplate = options?.template; if (!selectedTemplate || !templates.find((t) => t.value === selectedTemplate)) { const framework = await (0, prompts_1.select)({ message: "Which template would you like to use?", options: templates.map((t) => ({ value: t.value, label: t.label, hint: t.hint, })), }); if (typeof framework === "symbol") { (0, prompts_1.outro)("Operation cancelled"); process.exit(0); } selectedTemplate = framework; } const template = templates.find((t) => t.value === selectedTemplate); if (!template) { (0, prompts_1.outro)("Invalid template selected"); process.exit(1); } if ((0, node_fs_1.existsSync)(finalProjectName)) { (0, prompts_1.outro)(chalk_1.default.red(`Directory "${finalProjectName}" already exists`)); process.exit(1); } const s = (0, prompts_1.spinner)(); s.start("Downloading template..."); try { await (0, giget_1.downloadTemplate)(template.source, { dir: finalProjectName, registry: "gh", }); s.stop("Template downloaded!"); } catch (error) { s.stop("Failed to download template"); (0, prompts_1.outro)(chalk_1.default.red(`Error: ${error}`)); process.exit(1); } const availablePackageManagers = await detectAvailablePackageManagers(); let selectedPackageManager; if (availablePackageManagers.length === 1) { selectedPackageManager = availablePackageManagers[0]; } else { const packageManagerChoice = await (0, prompts_1.select)({ message: "Which package manager would you like to use?", options: availablePackageManagers.map((pm) => ({ value: pm.name, label: pm.label, })), }); if (typeof packageManagerChoice === "symbol") { (0, prompts_1.outro)("Operation cancelled"); process.exit(0); } selectedPackageManager = availablePackageManagers.find((pm) => pm.name === packageManagerChoice); } const shouldInstall = await (0, prompts_1.confirm)({ message: "Install dependencies?", initialValue: true, }); if (typeof shouldInstall === "symbol") { (0, prompts_1.outro)("Operation cancelled"); process.exit(0); } if (shouldInstall) { const s2 = (0, prompts_1.spinner)(); s2.start(`Installing dependencies with ${selectedPackageManager.name}...`); const { spawn } = await Promise.resolve().then(() => __importStar(require("node:child_process"))); const projectPath = (0, node_path_1.join)(process.cwd(), finalProjectName); try { await new Promise((resolve, reject) => { const child = spawn(selectedPackageManager.command, selectedPackageManager.args, { cwd: projectPath, stdio: "pipe", }); child.on("close", (code) => { if (code === 0) resolve(); else reject(new Error(`Package installation failed with code ${code}`)); }); child.on("error", reject); }); s2.stop("Dependencies installed!"); } catch (_error) { s2.stop("Failed to install dependencies"); console.log(chalk_1.default.yellow("\nYou can install dependencies manually by running:")); console.log(chalk_1.default.cyan(`cd ${finalProjectName} && ${selectedPackageManager.command} ${selectedPackageManager.args.join(" ")}`)); } } const shouldSetupMcpDocs = await (0, prompts_1.confirm)({ message: "Set up ADK-TS docs MCP server for your IDE?", initialValue: true, }); if (typeof shouldSetupMcpDocs === "symbol") { (0, prompts_1.outro)("Operation cancelled"); process.exit(0); } if (shouldSetupMcpDocs) { const ideChoice = await (0, prompts_1.select)({ message: "Which IDE or environment are you using?", options: [ { value: "cursor", label: "Cursor / VS Code (Cursor extension)", hint: ".cursor/mcp.json in this project", }, { value: "claude", label: "Claude Code / Claude Desktop", hint: "Uses `claude mcp add` command", }, { value: "windsurf", label: "Windsurf", hint: "~/.codeium/windsurf/mcp_config.json", }, { value: "other", label: "Other IDE / environment", hint: "Shows generic MCP setup instructions", }, ], }); if (typeof ideChoice === "symbol") { (0, prompts_1.outro)("Operation cancelled"); process.exit(0); } const s3 = (0, prompts_1.spinner)(); s3.start("Configuring MCP docs server..."); const projectPath = (0, node_path_1.join)(process.cwd(), finalProjectName); const cursorDir = (0, node_path_1.join)(projectPath, ".cursor"); const isWindows = process.platform === "win32"; try { if (ideChoice === "cursor") { if (!(0, node_fs_1.existsSync)(cursorDir)) { (0, node_fs_1.mkdirSync)(cursorDir, { recursive: true }); } const mcpConfigPath = (0, node_path_1.join)(cursorDir, "mcp.json"); const mcpConfig = { mcpServers: { "adk-docs": isWindows ? { command: "cmd", args: ["/c", "npx", "-y", "@iqai/mcp-docs"], } : { command: "npx", args: ["-y", "@iqai/mcp-docs"], }, }, }; (0, node_fs_1.writeFileSync)(mcpConfigPath, `${JSON.stringify(mcpConfig, null, 2)}\n`); s3.stop("MCP docs server configured for Cursor!"); } else if (ideChoice === "claude") { s3.stop("MCP docs server instructions for Claude:"); console.log(chalk_1.default.cyan("\nRun this in your terminal to add the MCP server to Claude:")); console.log(chalk_1.default.cyan("claude mcp add adk-docs -- npx -y @iqai/mcp-docs")); } else if (ideChoice === "windsurf") { s3.stop("MCP docs server instructions for Windsurf:"); console.log(chalk_1.default.cyan("\nAdd this to your ~/.codeium/windsurf/mcp_config.json file:")); console.log(chalk_1.default.cyan(JSON.stringify({ mcpServers: { "adk-docs": { command: "npx", args: ["-y", "@iqai/mcp-docs"], }, }, }, null, 2))); } else { s3.stop("MCP docs server generic instructions:"); console.log(chalk_1.default.cyan('\nConfigure an MCP server named "adk-docs" in your IDE pointing to:')); console.log(chalk_1.default.cyan("command: npx, args: [-y, @iqai/mcp-docs] (or the Windows equivalent)")); } } catch (_error) { s3.stop("Failed to configure MCP docs server"); console.log(chalk_1.default.yellow("\nYou can configure it manually by following the instructions in the @iqai/mcp-docs README.")); } } (0, prompts_1.outro)(chalk_1.default.green((0, dedent_1.default) ` ๐ŸŽ‰ Project created successfully! Next steps: ${chalk_1.default.cyan(`cd ${finalProjectName}`)} ${shouldInstall ? "" : chalk_1.default.cyan(`${selectedPackageManager.command} ${selectedPackageManager.args.join(" ")}`)} ${chalk_1.default.cyan("npm run dev")} or ${chalk_1.default.cyan("yarn dev")} or ${chalk_1.default.cyan("pnpm dev")} Happy coding! ๐Ÿš€ `)); } parseTemplate(val) { return val; } }; exports.NewCommand = NewCommand; __decorate([ (0, nest_commander_1.Option)({ flags: "-t, --template <template>", description: "Template to use (simple-agent, discord-bot, telegram-bot, hono-server, mcp-starter, shade-agent)", }), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", String) ], NewCommand.prototype, "parseTemplate", null); exports.NewCommand = NewCommand = __decorate([ (0, nest_commander_1.Command)({ name: "new", description: "Create a new ADK-TS project", arguments: "[project-name]", }) ], NewCommand); //# sourceMappingURL=new.command.js.map