create-adk-project
Version:
CLI tool to create ADK TypeScript projects with different frameworks
226 lines (221 loc) • 8.24 kB
JavaScript
// src/index.ts
import { existsSync } from "fs";
import { join } from "path";
import { confirm, intro, outro, select, spinner, text } from "@clack/prompts";
import chalk from "chalk";
import dedent from "dedent";
import { downloadTemplate } from "giget";
// src/starters.ts
var starters = [
{
value: "simple-agent",
label: "\u{1F916} Simple Agent",
hint: "Basic agent starter template",
template: "github:IQAIcom/adk-ts/apps/starter-templates/simple-agent",
isLocal: false
},
{
value: "hono-server",
label: "\u{1F310} Hono Server",
hint: "Web server with AI agent using Hono framework",
template: "github:IQAIcom/adk-ts/apps/starter-templates/hono-server",
isLocal: false
},
{
value: "telegram-bot",
label: "\u{1F4E8} Telegram Bot",
hint: "AI-powered Telegram bot template",
template: "github:IQAIcom/adk-ts/apps/starter-templates/telegram-bot",
isLocal: false
},
{
value: "discord-bot",
label: "\u{1F4AC} Discord Bot",
hint: "AI-powered Discord bot template",
template: "github:IQAIcom/adk-ts/apps/starter-templates/discord-bot",
isLocal: false
},
{
value: "mcp-starter",
label: "\u{1F50C} MCP Server",
hint: "Model Context Protocol server template",
template: "github:IQAIcom/adk-ts/apps/starter-templates/mcp-starter",
isLocal: false
}
];
// src/index.ts
var packageManagers = [
{ name: "npm", command: "npm", args: ["install"], label: "\u{1F4E6} npm" },
{ name: "pnpm", command: "pnpm", args: ["install"], label: "\u26A1 pnpm" },
{ name: "yarn", command: "yarn", args: ["install"], label: "\u{1F9F6} yarn" },
{ name: "bun", command: "bun", args: ["install"], label: "\u{1F35E} bun" }
];
async function detectAvailablePackageManagers() {
const { spawn } = await import("child_process");
const available = [];
for (const pm of packageManagers) {
try {
await new Promise((resolve, reject) => {
const child = spawn(pm.command, ["--version"], {
stdio: "pipe"
});
child.on("close", (code) => {
if (code === 0) {
available.push(pm);
}
resolve();
});
child.on("error", () => resolve());
});
} catch {
}
}
return available.length > 0 ? available : [packageManagers[0]];
}
async function main() {
console.clear();
console.log(
chalk.magentaBright(dedent`
╔══════════════════════════════════════════════════════╗
║ ║
║ █████╗ ██████╗ ██╗ ██╗ ████████╗███████╗ ║
║ ██╔══██╗██╔══██╗██║ ██╔╝ ╚══██╔══╝██╔════╝ ║
║ ███████║██║ ██║█████╔╝ ██║ ███████╗ ║
║ ██╔══██║██║ ██║██╔═██╗ ██║ ╚════██║ ║
║ ██║ ██║██████╔╝██║ ██╗ ██║ ███████║ ║
║ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ║
║ ║
╚══════════════════════════════════════════════════════╝
`)
);
intro(chalk.bgMagenta.bold(" \u2728 Let's build something amazing! "));
const projectName = await 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 (existsSync(value)) return `Directory "${value}" already exists`;
return void 0;
}
});
if (typeof projectName === "symbol") {
outro("Operation cancelled");
process.exit(0);
}
const framework = await select({
message: "Which template would you like to use?",
options: starters
});
if (typeof framework === "symbol") {
outro("Operation cancelled");
process.exit(0);
}
const selectedStarter = starters.find((s2) => s2.value === framework);
if (!selectedStarter) {
outro("Invalid starter selected");
process.exit(1);
}
const installDeps = await confirm({
message: "Install dependencies?",
initialValue: true
});
if (typeof installDeps === "symbol") {
outro("Operation cancelled");
process.exit(0);
}
let selectedPackageManager;
if (installDeps) {
const availablePackageManagers = await detectAvailablePackageManagers();
if (availablePackageManagers.length > 1) {
const pmChoice = await select({
message: "Which package manager would you like to use?",
options: availablePackageManagers.map((pm) => ({
value: pm.name,
label: pm.label,
hint: `Use ${pm.command} for dependency management`
}))
});
if (typeof pmChoice === "symbol") {
outro("Operation cancelled");
process.exit(0);
}
selectedPackageManager = availablePackageManagers.find(
(pm) => pm.name === pmChoice
);
} else {
selectedPackageManager = availablePackageManagers[0];
}
}
const s = spinner();
try {
s.start("Creating project...");
const templatePath = selectedStarter.template;
const targetDir = join(process.cwd(), projectName);
await downloadTemplate(templatePath, {
dir: targetDir,
offline: false,
preferOffline: false
});
s.stop("Project created successfully!");
if (installDeps && selectedPackageManager) {
s.start(`Installing dependencies with ${selectedPackageManager.name}...`);
const { spawn } = await import("child_process");
await new Promise((resolve, reject) => {
const child = spawn(
selectedPackageManager.command,
selectedPackageManager.args,
{
cwd: targetDir,
stdio: "pipe"
}
);
child.on("close", (code) => {
if (code === 0) {
resolve();
} else {
reject(
new Error(
`${selectedPackageManager.command} ${selectedPackageManager.args.join(" ")} failed with code ${code}`
)
);
}
});
child.on("error", reject);
});
s.stop("Dependencies installed!");
}
const envFile = ".env";
console.log(
chalk.green(
`${chalk.bold.yellow("\u{1F389} SUCCESS!")} Your ADK project has been created!`
)
);
const runCommand = selectedPackageManager?.name === "npm" ? "npm run dev" : selectedPackageManager?.name === "yarn" ? "yarn dev" : selectedPackageManager?.name === "pnpm" ? "pnpm dev" : selectedPackageManager?.name === "bun" ? "bun run dev" : "npm run dev";
const installCommand = selectedPackageManager?.name === "yarn" ? "yarn" : selectedPackageManager ? `${selectedPackageManager.command} ${selectedPackageManager.args.join(" ")}` : "npm install";
const steps = [
chalk.bold(`cd ${projectName}`),
...!installDeps ? [chalk.bold(installCommand)] : [],
`${chalk.bold(`cp .env.example ${envFile}`)} ${chalk.gray(`# Add your API keys to the ${envFile} file`)}`,
chalk.bold(runCommand)
];
const nextSteps = steps.map((step, index) => `${index + 1}. ${step}`);
outro(
chalk.cyan(
dedent`
${chalk.bold("\u{1F680} Next steps:")}
${nextSteps.join("\n ")}
${chalk.bold.green("\u{1F916} Your AI agent is ready to go!")}
${chalk.gray("Documentation: https://adk.iqai.com")}
`
)
);
} catch (error) {
s.stop("Failed to create project");
console.error(chalk.red("Error:"), error);
process.exit(1);
}
}
main().catch(console.error);
//# sourceMappingURL=index.js.map