@iqai/adk-cli
Version:
CLI tool for creating, running, and testing ADK-TS agents
372 lines (370 loc) โข 16.4 kB
JavaScript
;
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