Skip to content

Commit 33b530c

Browse files
committed
feat(cli): add better templates for all integrations in next.js client
Signed-off-by: Tyler Slaton <[email protected]>
1 parent 20e8f1f commit 33b530c

File tree

3 files changed

+103
-116
lines changed

3 files changed

+103
-116
lines changed

typescript-sdk/packages/cli/README.md

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,48 @@
22

33
CLI tool for scaffolding **Agent-User Interaction (AG-UI) Protocol** applications.
44

5-
`create-ag-ui-app` provides an interactive setup wizard to quickly bootstrap AG-UI projects with your preferred client framework and agent backend. Choose from CopilotKit/Next.js for web apps or CLI clients for terminal-based interactions.
5+
`create-ag-ui-app` provides an interactive setup wizard to quickly bootstrap AG-UI projects with your preferred client framework and agent backend.
66

7-
## Installation
7+
Choose from CopilotKit/Next.js for web apps or CLI clients for terminal-based interactions.
8+
9+
## Usage
810

911
```bash
10-
npm create ag-ui-app@latest
11-
pnpm create ag-ui-app@latest
12-
yarn create ag-ui-app
12+
npx create-ag-ui-app@latest
13+
pnpx create-ag-ui-app@latest
14+
bunx create-ag-ui-app@latest
1315
```
1416

1517
## Features
1618

1719
- 🎯 **Interactive setup** – Guided prompts for client and framework selection
1820
- 🌐 **Multiple clients** – CopilotKit/Next.js web apps and CLI clients
19-
- 🔧 **Framework integration** – Built-in support for LangGraph, CrewAI, Mastra, AG2, and more
21+
- 🔧 **Framework integration** – Built-in support for LangGraph, CrewAI, Mastra, Agno, LlamaIndex, and more
2022
- 📦 **Zero config** – Automatically sets up dependencies and project structure
2123
-**Quick start** – Get from idea to running app in minutes
2224

2325
## Quick example
2426

2527
```bash
2628
# Interactive setup
27-
npm create ag-ui-app@latest
29+
npx create-ag-ui-app@latest
2830

2931
# With framework flags
30-
npm create ag-ui-app@latest -- --langgraph
31-
npm create ag-ui-app@latest -- --mastra
32+
npx create-ag-ui-app@latest --langgraph-py
33+
npx create-ag-ui-app@latest --mastra
34+
35+
# See all options
36+
npx create-ag-ui-app@latest --help
3237
```
3338

3439
## Documentation
3540

3641
- Concepts & architecture: [`docs/concepts`](https://docs.ag-ui.com/concepts/architecture)
37-
- Full API reference: [`docs/quickstart`](https://docs.ag-ui.com/quickstart/introduction)
42+
- Full API reference: [`docs/events`](https://docs.ag-ui.com/concepts/events)
3843

3944
## Contributing
4045

41-
Bug reports and pull requests are welcome! Please read our [contributing guide](https://docs.ag-ui.com/development/contributing) first.
46+
Bug reports and pull requests are welcome! Please read our [contributing guide](https://github.com/ag-ui-protocol/ag-ui/blob/main/CONTRIBUTING.md) first.
4247

4348
## License
4449

typescript-sdk/packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "create-ag-ui-app",
33
"author": "Markus Ecker <[email protected]>",
4-
"version": "0.0.35",
4+
"version": "0.0.36",
55
"private": false,
66
"publishConfig": {
77
"access": "public"

typescript-sdk/packages/cli/src/index.ts

Lines changed: 86 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,35 @@ ${RESET}
2626
console.log(banner);
2727
}
2828

29+
const description = `
30+
Quickly scaffold AG-UI enabled applications for your favorite agent frameworks.
31+
`
32+
2933
async function createProject() {
3034
displayBanner();
3135

3236
console.log("\n~ Let's get started building an AG-UI powered user interactive agent ~");
3337
console.log(" Read more about AG-UI at https://ag-ui.com\n");
34-
console.log("");
35-
console.log("To build an AG-UI app, you need to select a client.");
36-
console.log("");
38+
39+
const options = program.opts();
40+
const isFrameworkDefined = [
41+
"langgraphPy",
42+
"langgraphJs",
43+
"crewaiFlows",
44+
"mastra",
45+
"ag2",
46+
"llamaindex",
47+
"agno"
48+
].some(flag => options[flag]);
49+
50+
if (isFrameworkDefined) {
51+
await handleCopilotKitNextJs();
52+
return;
53+
} else {
54+
console.log("");
55+
console.log("To build an AG-UI app, you need to select a client.");
56+
console.log("");
57+
}
3758

3859
const answers = await inquirer.prompt([
3960
{
@@ -43,118 +64,75 @@ async function createProject() {
4364
choices: [
4465
"CopilotKit/Next.js",
4566
"CLI client",
46-
new inquirer.Separator("Other clients coming soon (SMS, Whatsapp, Slack ...)"),
67+
new inquirer.Separator(" Other clients coming soon (SMS, Whatsapp, Slack ...)"),
4768
],
4869
},
4970
]);
5071

51-
console.log(`\nSelected client: ${answers.client}`);
52-
console.log("Initializing your project...\n");
53-
54-
// Handle CLI client option
55-
if (answers.client === "CLI client") {
56-
await handleCliClient();
57-
return;
72+
switch (answers.client) {
73+
case "CopilotKit/Next.js":
74+
await handleCopilotKitNextJs();
75+
break;
76+
case "CLI client":
77+
await handleCliClient();
78+
break;
79+
default:
80+
break;
5881
}
82+
}
5983

60-
// Continue with existing CopilotKit/Next.js logic
61-
const packageJsonPath = path.join(process.cwd(), "package.json");
62-
const packageJsonExists = fs.existsSync(packageJsonPath);
63-
64-
let projectDir = process.cwd();
65-
66-
if (!packageJsonExists) {
67-
console.log("📦 No package.json found, creating a new Next.js app...\n");
68-
69-
const projectName = await inquirer.prompt([
70-
{
71-
type: "input",
72-
name: "name",
73-
message: "What would you like to name your project?",
74-
default: "my-ag-ui-app",
75-
validate: (input) => {
76-
if (!input.trim()) {
77-
return "Project name cannot be empty";
78-
}
79-
if (!/^[a-zA-Z0-9-_]+$/.test(input)) {
80-
return "Project name can only contain letters, numbers, hyphens, and underscores";
81-
}
82-
return true;
83-
},
84-
},
85-
]);
86-
87-
projectDir = path.join(process.cwd(), projectName.name);
88-
89-
console.log(`Creating Next.js app: ${projectName.name}\n`);
90-
91-
const createNextApp = spawn(
92-
"npx",
93-
[
94-
"create-next-app@latest",
95-
projectName.name,
96-
"--typescript",
97-
"--tailwind",
98-
"--eslint",
99-
"--app",
100-
"--src-dir",
101-
"--import-alias",
102-
"@/*",
103-
"--no-turbopack",
104-
],
105-
{
106-
stdio: "inherit",
107-
shell: true,
108-
},
109-
);
110-
111-
await new Promise<void>((resolve, reject) => {
112-
createNextApp.on("close", (code) => {
113-
if (code === 0) {
114-
console.log("\n✅ Next.js app created successfully!");
115-
resolve();
116-
} else {
117-
console.log("\n❌ Failed to create Next.js app");
118-
reject(new Error(`create-next-app exited with code ${code}`));
119-
}
120-
});
121-
});
122-
123-
// Change to the new project directory
124-
try {
125-
process.chdir(projectDir);
126-
} catch (error) {
127-
console.log("❌ Error changing directory:", error);
128-
process.exit(1);
129-
}
130-
}
131-
132-
// Run copilotkit init with framework flags
133-
console.log("\n🚀 Running CopilotKit initialization...\n");
134-
84+
async function handleCopilotKitNextJs() {
13585
const options = program.opts();
136-
const frameworkArgs = [];
86+
const frameworkArgs: string[] = [];
13787

138-
if (options.langgraph) {
139-
frameworkArgs.push("-m", "LangGraph");
140-
} else if (options.crewiAiCrews) {
141-
frameworkArgs.push("-m", "CrewAI", "--crew-type", "Crews");
88+
const projectName = await inquirer.prompt([
89+
{
90+
type: "input",
91+
name: "name",
92+
message: "What would you like to name your project?",
93+
default: "my-ag-ui-app",
94+
validate: (input) => {
95+
if (!input.trim()) {
96+
return "Project name cannot be empty";
97+
}
98+
if (!/^[a-zA-Z0-9-_]+$/.test(input)) {
99+
return "Project name can only contain letters, numbers, hyphens, and underscores";
100+
}
101+
return true;
102+
},
103+
},
104+
]);
105+
106+
// Translate options to CopilotKit framework flags
107+
if (options.langgraphPy) {
108+
frameworkArgs.push("-f", "langgraph-py");
109+
} else if (options.langgraphJs) {
110+
frameworkArgs.push("-f", "langgraph-js");
142111
} else if (options.crewiAiFlows) {
143-
frameworkArgs.push("-m", "CrewAI", "--crew-type", "Flows");
112+
frameworkArgs.push("-f", "flows");
144113
} else if (options.mastra) {
145-
frameworkArgs.push("-m", "Mastra");
114+
frameworkArgs.push("-f", "mastra");
146115
} else if (options.ag2) {
147-
frameworkArgs.push("-m", "AG2");
116+
frameworkArgs.push("-f", "ag2");
148117
} else if (options.llamaindex) {
149-
frameworkArgs.push("-m", "LlamaIndex");
118+
frameworkArgs.push("-f", "llamaindex");
150119
} else if (options.agno) {
151-
frameworkArgs.push("-m", "Agno");
120+
frameworkArgs.push("-f", "agno");
152121
}
153122

154-
const copilotkit = spawn("npx", ["copilotkit", "init", ...frameworkArgs], {
155-
stdio: "inherit",
156-
shell: true,
157-
});
123+
const copilotkit = spawn("npx",
124+
[
125+
"copilotkit@latest",
126+
"create",
127+
"--no-banner",
128+
"-n", projectName.name,
129+
...frameworkArgs,
130+
],
131+
{
132+
stdio: "inherit",
133+
shell: true,
134+
},
135+
);
158136

159137
copilotkit.on("close", (code) => {
160138
if (code !== 0) {
@@ -220,13 +198,17 @@ async function handleCliClient() {
220198
}
221199
}
222200

223-
program.name("create-ag-ui-app").description("AG-UI CLI").version("0.0.1-alpha.1");
201+
// Metadata
202+
program
203+
.name("create-ag-ui-app")
204+
.description(description)
205+
.version("0.0.35");
224206

225207
// Add framework flags
226208
program
227-
.option("--langgraph", "Use the LangGraph framework")
228-
.option("--crewi-ai-crews", "Use the CrewAI framework with Crews")
229-
.option("--crewi-ai-flows", "Use the CrewAI framework with Flows")
209+
.option("--langgraph-py", "Use the LangGraph framework with Python")
210+
.option("--langgraph-js", "Use the LangGraph framework with JavaScript")
211+
.option("--crewai-flows", "Use the CrewAI framework with Flows")
230212
.option("--mastra", "Use the Mastra framework")
231213
.option("--ag2", "Use the AG2 framework")
232214
.option("--llamaindex", "Use the LlamaIndex framework")

0 commit comments

Comments
 (0)