create-adk-agent 0.0.2 โ†’ 0.0.9

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 (40) hide show
  1. package/README.md +30 -202
  2. package/bin/create-adk-agent.js +361 -35
  3. package/dist/generators/init/files/.env.example.template +16 -0
  4. package/dist/generators/init/files/.eslintrc.json.template +20 -0
  5. package/dist/generators/init/files/.gitignore.template +27 -0
  6. package/dist/generators/init/files/.prettierrc.template +7 -0
  7. package/dist/generators/init/files/README.md.template +243 -0
  8. package/dist/generators/init/files/jest.config.ts.template +7 -0
  9. package/dist/generators/init/files/package.json.template +41 -0
  10. package/dist/generators/init/files/src/agents/basic/agent.ts.template +24 -0
  11. package/dist/generators/init/files/src/agents/multi-tool/agent.ts.template +36 -0
  12. package/dist/generators/init/files/src/agents/streaming/agent.ts.template +36 -0
  13. package/dist/generators/init/files/src/agents/team/farewell-agent.ts.template +43 -0
  14. package/dist/generators/init/files/src/agents/team/greeting-agent.ts.template +43 -0
  15. package/dist/generators/init/files/src/agents/team/root-agent.ts.template +18 -0
  16. package/dist/generators/init/files/src/agents/workflow/agent.ts.template +69 -0
  17. package/dist/generators/init/files/src/index.ts.template +61 -0
  18. package/dist/generators/init/files/tests/agents.test.ts.template +80 -0
  19. package/dist/generators/init/files/tsconfig.json.template +20 -0
  20. package/dist/generators/init/files/vite.config.ts.template +36 -0
  21. package/dist/generators/init/generator.js +3 -0
  22. package/dist/generators/init/generator.js.map +1 -1
  23. package/dist/generators/init/schema.json +124 -0
  24. package/package.json +20 -4
  25. package/src/generators/init/files/README.md.template +3 -2
  26. package/src/generators/init/files/package.json.template +8 -6
  27. package/src/generators/init/files/src/agents/basic/agent.ts.template +9 -19
  28. package/src/generators/init/files/src/agents/multi-tool/agent.ts.template +15 -62
  29. package/src/generators/init/files/vite.config.ts.template +36 -0
  30. package/templates/basic/.env.example +16 -0
  31. package/templates/basic/.eslintrc.json +13 -0
  32. package/templates/basic/.prettierrc +5 -0
  33. package/templates/basic/README.md +49 -0
  34. package/templates/basic/_gitignore +8 -0
  35. package/templates/basic/jest.config.ts +8 -0
  36. package/templates/basic/package.json +43 -0
  37. package/templates/basic/src/index.ts +59 -0
  38. package/templates/basic/tests/agents.test.ts +19 -0
  39. package/templates/basic/tsconfig.json +21 -0
  40. package/templates/multi-tool/src/index.ts +60 -0
package/README.md CHANGED
@@ -1,241 +1,69 @@
1
1
  # create-adk-agent
2
2
 
3
- > **The fastest way to start building with Google's Agent Development Kit (ADK)**
3
+ > Scaffold production-ready [Google ADK](https://google.github.io/adk-docs/) TypeScript projects in seconds
4
4
 
5
- Scaffold production-ready ADK TypeScript projects in seconds with best practices, multiple templates, and zero configuration.
6
-
7
- **What is ADK?** The [Agent Development Kit](https://google.github.io/adk-docs/) is Google's framework for building AI agents. This tool makes it easy to get started.
8
-
9
- ## ๐Ÿš€ Quick Start
5
+ ## Quick Start
10
6
 
11
7
  ```bash
12
8
  npx create-adk-agent my-agent
13
9
  ```
14
10
 
15
- That's it! You'll get a fully configured ADK project with:
16
- - โœ… TypeScript configured for ADK
17
- - โœ… Environment setup with API key validation
18
- - โœ… Working agent examples from official docs
19
- - โœ… Hot reload development with tsx
20
- - โœ… Testing setup with Jest
21
- - โœ… All the tooling (ESLint, Prettier, etc.)
22
-
23
- ## ๐Ÿ’ก Why Use This?
24
-
25
- Instead of manually setting up TypeScript, configuring ESM, managing API keys, and copying examples from docs, `create-adk-agent` does it all for you in one command.
26
-
27
- **Perfect for:**
28
- - ๐ŸŽ“ Learning ADK quickly with working examples
29
- - ๐Ÿš€ Starting new ADK projects without boilerplate hassle
30
- - ๐Ÿ“ฆ Getting ADK best practices out of the box
31
- - ๐Ÿ”„ Experimenting with different agent patterns
32
-
33
- ## โœจ What You Get
34
-
35
- ## โœจ What You Get
36
-
37
- - ๐Ÿค– **5 Agent Templates** - Pre-built examples from [official ADK docs](https://google.github.io/adk-docs/) (basic, multi-tool, team, streaming, workflow)
38
- - ๐Ÿ”Œ **Multi-Model Ready** - Pre-configured for Gemini, OpenAI, and Anthropic
39
- - โšก **Hot Reload** - Instant TypeScript execution with tsx (no build step needed)
40
- - ๐Ÿ” **Security Built-in** - Proper `.env` handling with validation and git-ignore
41
- - ๐Ÿงช **Testing Included** - Jest configured and ready to go
42
- - ๐Ÿ“ฆ **Best Practices** - TypeScript, ESLint, Prettier, Zod validation
43
-
44
- ## ๐Ÿ“š Agent Templates
45
-
46
- All templates are based on [official ADK documentation examples](https://google.github.io/adk-docs/):
47
-
48
- ### Basic Agent
49
-
50
- Simple agent with time tool - perfect for learning ADK basics.
51
-
52
- ### Multi-Tool Agent (Default)
53
-
54
- Agent with multiple tools (time, weather, calculator) demonstrating tool composition.
55
-
56
- ### Team Agent
11
+ Creates a TypeScript project pre-configured for building AI agents with Google's Agent Development Kit.
57
12
 
58
- Multi-agent system with coordination, delegation, and sub-agents (greeting + farewell).
13
+ ## What You Get
59
14
 
60
- ### Streaming Agent
61
-
62
- Demonstrates real-time streaming responses using ADK Live API.
63
-
64
- ### Workflow Agent
65
-
66
- Sequential workflow patterns with validation, transformation, and saving steps.
67
-
68
- ## ๐ŸŽฏ Usage
15
+ - โœ… Working agent examples from [ADK docs](https://google.github.io/adk-docs/get-started/typescript/)
16
+ - โœ… TypeScript configured (ES2022, NodeNext, ESM)
17
+ - โœ… Hot reload with tsx (instant execution)
18
+ - โœ… Multi-model support (Gemini, OpenAI, Anthropic)
19
+ - โœ… Environment setup with API key validation
20
+ - โœ… Testing with Jest, linting with ESLint
69
21
 
70
- ### Simple (Interactive)
22
+ ## Usage
71
23
 
72
- Just run the command and answer a few questions:
24
+ **Interactive:**
73
25
 
74
26
  ```bash
75
27
  npx create-adk-agent my-agent
76
28
  ```
77
29
 
78
- You'll choose:
79
- - Which agent templates to include
80
- - Your preferred model provider (Gemini, OpenAI, or Anthropic)
81
- - Whether to install dependencies now
82
- - Whether to initialize git
83
-
84
- ### Advanced (Non-Interactive)
85
-
86
- Skip prompts by providing options:
30
+ **Non-interactive:**
87
31
 
88
32
  ```bash
89
33
  npx create-adk-agent my-agent \
90
- --templates=basic,multi-tool \
34
+ --template=basic \
91
35
  --modelProvider=gemini \
92
- --model=gemini-3.0-flash \
93
- --description="My custom agent" \
94
- --installDependencies \
95
- --no-interactive
36
+ --model=gemini-2.5-flash
96
37
  ```
97
38
 
98
- ### Options
99
-
100
- | Option | Type | Description | Default |
101
- | ----------------------- | --------------------------------- | -------------------------- | ---------------------- |
102
- | `name` | string | Project name (required) | - |
103
- | `--templates` | string[] | Agent templates to include | `['multi-tool']` |
104
- | `--modelProvider` | gemini\|openai\|anthropic\|custom | LLM provider | `gemini` |
105
- | `--model` | string | Specific model to use | Provider's first model |
106
- | `--description` | string | Project description | `My ADK Agent` |
107
- | `--directory` | string | Target directory | Same as name |
108
- | `--installDependencies` | boolean | Run npm install | Prompt |
109
- | `--initGit` | boolean | Initialize git repo | Prompt |
110
- | `--no-interactive` | boolean | Skip prompts | `false` |
111
-
112
- ## ๐Ÿค– Supported Models
113
-
114
- ### Google Gemini (Direct)
115
-
116
- - gemini-3.0-flash
117
- - gemini-3.0-pro
118
- - gemini-2.5-flash
119
- - gemini-2.5-pro
120
-
121
- ### OpenAI (via LiteLLM)
122
-
123
- - gpt-5
124
- - gpt-5-mini
125
- - gpt-4o
126
- - gpt-4o-mini
127
-
128
- ### Anthropic (via LiteLLM)
129
-
130
- - claude-4.5-sonnet
131
- - claude-4-sonnet
132
- - claude-4-opus
133
- - claude-3-5-sonnet
134
-
135
- **Note:** You can change to any model after project generation. The list above is for initial setup convenience.
136
-
137
- ## ๐ŸŽฌ Getting Started Workflow
39
+ ## After Generation
138
40
 
139
41
  ```bash
140
- # 1. Create your project (takes ~10 seconds)
141
- npx create-adk-agent my-agent
142
-
143
- # 2. Navigate to project
144
42
  cd my-agent
145
43
 
146
- # 3. Add your API key
44
+ # Add your API key
147
45
  cp .env.example .env
148
- # Edit .env and add your API key (get it from links in the file)
46
+ # Edit .env with your API key
149
47
 
150
- # 4. Start coding! (hot reload enabled)
48
+ # Start development
151
49
  npm run dev
152
50
 
153
- # 5. Or use ADK DevTools
154
- npm run adk:web # Beautiful web UI
51
+ # Use ADK DevTools
52
+ npm run adk:web # Interactive web UI
155
53
  npm run adk:run # CLI runner
156
54
  ```
157
55
 
158
- **That's it!** You're now building with ADK. No complex setup, no configuration headaches.
159
-
160
- ## ๐Ÿ”— Learn More About ADK
161
-
162
- ```
163
- my-agent/
164
- โ”œโ”€โ”€ src/
165
- โ”‚ โ”œโ”€โ”€ agents/
166
- โ”‚ โ”‚ โ”œโ”€โ”€ basic/ # Basic agent (if selected)
167
- โ”‚ โ”‚ โ”œโ”€โ”€ multi-tool/ # Multi-tool agent (if selected)
168
- โ”‚ โ”‚ โ”œโ”€โ”€ team/ # Team agents (if selected)
169
- โ”‚ โ”‚ โ”œโ”€โ”€ streaming/ # Streaming agent (if selected)
170
- โ”‚ โ”‚ โ””โ”€โ”€ workflow/ # Workflow agent (if selected)
171
- โ”‚ โ””โ”€โ”€ index.ts # Entry point with env validation
172
- โ”œโ”€โ”€ tests/
173
- โ”‚ โ””โ”€โ”€ agents.test.ts # Jest tests
174
- โ”œโ”€โ”€ .env.example # Environment template (commit this)
175
- โ”œโ”€โ”€ .env # Your API keys (DO NOT COMMIT)
176
- โ”œโ”€โ”€ .gitignore # Includes .env patterns
177
- โ”œโ”€โ”€ package.json # With tsx, ADK, and dev tools
178
- โ”œโ”€โ”€ tsconfig.json # Configured for ESM + NodeNext
179
- โ””โ”€โ”€ README.md # Project-specific documentation
180
- ```
181
-
182
- ## ๐Ÿ” Security
56
+ ## Templates
183
57
 
184
- **โš ๏ธ Generated projects include:**
185
-
186
- - `.env` in `.gitignore` by default
187
- - API key validation on startup
188
- - Clear warnings about committing secrets
189
- - `.env.example` template for sharing
190
-
191
- ## ๐Ÿ› ๏ธ Development Workflow
192
-
193
- After generating your project:
194
-
195
- ```bash
196
- cd my-agent
197
-
198
- # 1. Set up your API key
199
- cp .env.example .env
200
- # Edit .env and add your API key
58
+ - **basic** - Single agent with one tool ([docs example](https://google.github.io/adk-docs/get-started/typescript/#define-the-agent-code))
59
+ - **multi-tool** - Agent with multiple tools (default)
201
60
 
202
- # 2. Install dependencies (if not done during generation)
203
- npm install
61
+ ## Learn More
204
62
 
205
- # 3. Start development with hot reload
206
- npm run dev
207
-
208
- # 4. Run tests
209
- npm test
210
-
211
- # 5. Use ADK DevTools
212
- npm run adk:web # Web UI
213
- npm run adk:run # CLI runner
214
- ```
215
-
216
- ## ๐Ÿ“š Documentation
217
-
218
- - [ADK Documentation](https://google.github.io/adk-docs/)
219
- - [TypeScript Quick Start](https://google.github.io/adk-docs/get-started/typescript/)
220
- - [Agent Tutorial](https://google.github.io/adk-docs/tutorial/agent/)
221
-
222
- ## ๐Ÿค Contributing
223
-
224
- Contributions welcome! This is an Nx workspace project.
225
-
226
- ### Development
227
-
228
- ```bash
229
- # Build the generator
230
- nx build create-adk-agent
231
-
232
- # Test locally
233
- nx g @adk-ts-new/create-adk-agent:init test-project
234
-
235
- # Run tests
236
- nx test create-adk-agent
237
- ```
63
+ - **[ADK Documentation](https://google.github.io/adk-docs/)** - Official ADK guide
64
+ - **[TypeScript Quickstart](https://google.github.io/adk-docs/get-started/typescript/)** - Getting started
65
+ - **[Building Agents](https://google.github.io/adk-docs/tutorials/)** - Agent tutorials
238
66
 
239
- ## ๐Ÿ“„ License
67
+ ## License
240
68
 
241
- MIT ยฉ Maina Wycliffe
69
+ MIT
@@ -1,38 +1,364 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { execSync } from 'child_process';
4
- import { fileURLToPath } from 'url';
5
- import { dirname, resolve } from 'path';
6
-
7
- const __filename = fileURLToPath(import.meta.url);
8
- const __dirname = dirname(__filename);
9
-
10
- // Get the arguments passed to the script (excluding node and script path)
11
- const args = process.argv.slice(2);
12
-
13
- // Check if a project name was provided
14
- if (args.length === 0) {
15
- console.error('โŒ Error: Please provide a project name');
16
- console.error('Usage: npx create-adk-agent <project-name> [options]');
17
- console.error('');
18
- console.error('Example:');
19
- console.error(' npx create-adk-agent my-agent');
20
- console.error(' npx create-adk-agent my-agent --templates=basic,multi-tool --no-interactive');
21
- process.exit(1);
22
- }
23
-
24
- // Build the nx command
25
- const generatorPath = resolve(__dirname, '..');
26
- const command = `npx --yes nx g ${generatorPath}:init ${args.join(' ')}`;
27
-
28
- console.log('๐Ÿš€ Creating your ADK agent project...');
29
- console.log('');
30
-
31
- try {
32
- // Execute the nx generator command
33
- execSync(command, { stdio: 'inherit', cwd: process.cwd() });
34
- } catch (error) {
35
- console.error('');
36
- console.error('โŒ Failed to create project');
37
- process.exit(1);
3
+ // @ts-check
4
+ import { blue, cyan, green, red, reset, yellow } from 'kolorist';
5
+ import minimist from 'minimist';
6
+ import fs from 'node:fs';
7
+ import path from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
9
+ import prompts from 'prompts';
10
+
11
+ const argv = minimist(process.argv.slice(2), { string: ['_'] });
12
+ const cwd = process.cwd();
13
+
14
+ // Template configurations
15
+ const TEMPLATES = [
16
+ {
17
+ name: 'basic',
18
+ display: 'Basic Agent',
19
+ description: 'Single agent with one tool (time example)',
20
+ color: green,
21
+ },
22
+ {
23
+ name: 'multi-tool',
24
+ display: 'Multi-Tool Agent',
25
+ description: 'Agent with multiple tools (recommended)',
26
+ color: blue,
27
+ },
28
+ {
29
+ name: 'streaming',
30
+ display: 'Streaming Agent',
31
+ description: 'Agent with Live API streaming support',
32
+ color: cyan,
33
+ },
34
+ {
35
+ name: 'team',
36
+ display: 'Multi-Agent Team',
37
+ description: 'Multiple agents working together',
38
+ color: yellow,
39
+ },
40
+ {
41
+ name: 'workflow',
42
+ display: 'Workflow Agent',
43
+ description: 'Sequential and parallel execution patterns',
44
+ color: yellow,
45
+ },
46
+ ];
47
+
48
+ // Model provider configurations
49
+ const MODEL_PROVIDERS = {
50
+ gemini: {
51
+ name: 'Google Gemini',
52
+ models: [
53
+ 'gemini-2.0-flash',
54
+ 'gemini-2.0-flash-thinking-exp-01-21',
55
+ 'gemini-1.5-pro',
56
+ ],
57
+ apiKeyVar: 'GEMINI_API_KEY',
58
+ importStatement: "import { LlmAgent, FunctionTool } from '@google/adk';",
59
+ modelConfig: (model) => `'${model}'`,
60
+ },
61
+ openai: {
62
+ name: 'OpenAI',
63
+ models: ['openai/gpt-4o', 'openai/gpt-4o-mini', 'openai/gpt-4-turbo'],
64
+ apiKeyVar: 'OPENAI_API_KEY',
65
+ importStatement:
66
+ "import { LlmAgent, FunctionTool, LiteLlm } from '@google/adk';",
67
+ modelConfig: (model) => `new LiteLlm({ model: '${model}' })`,
68
+ },
69
+ anthropic: {
70
+ name: 'Anthropic (Claude)',
71
+ models: [
72
+ 'anthropic/claude-3-5-sonnet',
73
+ 'anthropic/claude-3-opus',
74
+ 'anthropic/claude-3-haiku',
75
+ ],
76
+ apiKeyVar: 'ANTHROPIC_API_KEY',
77
+ importStatement:
78
+ "import { LlmAgent, FunctionTool, LiteLlm } from '@google/adk';",
79
+ modelConfig: (model) => `new LiteLlm({ model: '${model}' })`,
80
+ },
81
+ };
82
+
83
+ const renameFiles = {
84
+ _gitignore: '.gitignore',
85
+ };
86
+
87
+ function formatTargetDir(targetDir) {
88
+ return targetDir?.trim().replace(/\/+$/g, '');
89
+ }
90
+
91
+ function isValidPackageName(projectName) {
92
+ return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(
93
+ projectName,
94
+ );
95
+ }
96
+
97
+ function toValidPackageName(projectName) {
98
+ return projectName
99
+ .trim()
100
+ .toLowerCase()
101
+ .replace(/\s+/g, '-')
102
+ .replace(/^[._]/, '')
103
+ .replace(/[^a-z0-9-~]+/g, '-');
104
+ }
105
+
106
+ function copy(src, dest) {
107
+ const stat = fs.statSync(src);
108
+ if (stat.isDirectory()) {
109
+ copyDir(src, dest);
110
+ } else {
111
+ fs.copyFileSync(src, dest);
112
+ }
113
+ }
114
+
115
+ function copyDir(srcDir, destDir) {
116
+ fs.mkdirSync(destDir, { recursive: true });
117
+ for (const file of fs.readdirSync(srcDir)) {
118
+ const srcFile = path.resolve(srcDir, file);
119
+ const destFile = path.resolve(destDir, file);
120
+ copy(srcFile, destFile);
121
+ }
122
+ }
123
+
124
+ function isEmpty(pathToCheck) {
125
+ const files = fs.readdirSync(pathToCheck);
126
+ return files.length === 0 || (files.length === 1 && files[0] === '.git');
127
+ }
128
+
129
+ function emptyDir(dir) {
130
+ if (!fs.existsSync(dir)) {
131
+ return;
132
+ }
133
+ for (const file of fs.readdirSync(dir)) {
134
+ fs.rmSync(path.resolve(dir, file), { recursive: true, force: true });
135
+ }
136
+ }
137
+
138
+ function replacePlaceholders(root, files, config) {
139
+ for (const file of Array.isArray(files) ? files : [files]) {
140
+ const filePath = path.join(root, file);
141
+ if (!fs.existsSync(filePath)) continue;
142
+
143
+ const fileContent = fs.readFileSync(filePath, 'utf-8');
144
+ const newFileContent = Object.keys(config).reduce(
145
+ (content, placeholder) =>
146
+ content.replace(new RegExp(placeholder, 'g'), config[placeholder]),
147
+ fileContent,
148
+ );
149
+ fs.writeFileSync(filePath, newFileContent);
150
+ }
151
+ }
152
+
153
+ async function init() {
154
+ let targetDir = formatTargetDir(argv._[0]);
155
+ let template = argv.template || argv.t;
156
+ let modelProvider = argv.modelProvider || argv.mp;
157
+ let model = argv.model || argv.m;
158
+ let description = argv.description || argv.d;
159
+
160
+ const defaultTargetDir = 'my-adk-agent';
161
+ const getProjectName = () =>
162
+ targetDir === '.' ? path.basename(path.resolve()) : targetDir;
163
+
164
+ let result = {};
165
+
166
+ try {
167
+ result = await prompts(
168
+ [
169
+ {
170
+ type: targetDir ? null : 'text',
171
+ name: 'projectName',
172
+ message: reset('Project name:'),
173
+ initial: defaultTargetDir,
174
+ onState: (state) => {
175
+ targetDir = formatTargetDir(state.value) || defaultTargetDir;
176
+ },
177
+ },
178
+ {
179
+ type: () =>
180
+ !fs.existsSync(targetDir) || isEmpty(targetDir) ? null : 'confirm',
181
+ name: 'overwrite',
182
+ message: () =>
183
+ (targetDir === '.'
184
+ ? 'Current directory'
185
+ : `Target directory "${targetDir}"`) +
186
+ ` is not empty. Remove existing files and continue?`,
187
+ },
188
+ {
189
+ type: (_, { overwrite } = {}) => {
190
+ if (overwrite === false) {
191
+ throw new Error(red('โœ–') + ' Operation cancelled');
192
+ }
193
+ return null;
194
+ },
195
+ name: 'overwriteChecker',
196
+ },
197
+ {
198
+ type: () => (isValidPackageName(getProjectName()) ? null : 'text'),
199
+ name: 'packageName',
200
+ message: reset('Package name:'),
201
+ initial: () => toValidPackageName(getProjectName()),
202
+ validate: (dir) =>
203
+ isValidPackageName(dir) || 'Invalid package.json name',
204
+ },
205
+ {
206
+ type: description ? null : 'text',
207
+ name: 'description',
208
+ message: reset('Project description:'),
209
+ initial: 'My ADK Agent',
210
+ },
211
+ {
212
+ type: template ? null : 'select',
213
+ name: 'template',
214
+ message: reset('Select a template:'),
215
+ choices: TEMPLATES.map((t) => ({
216
+ title: `${t.color(t.display)} - ${t.description}`,
217
+ value: t.name,
218
+ })),
219
+ },
220
+ {
221
+ type: modelProvider ? null : 'select',
222
+ name: 'modelProvider',
223
+ message: reset('Select LLM provider:'),
224
+ choices: Object.entries(MODEL_PROVIDERS).map(([key, value]) => ({
225
+ title: value.name,
226
+ value: key,
227
+ })),
228
+ },
229
+ {
230
+ type: (prev, values) => {
231
+ const provider = modelProvider || values.modelProvider;
232
+ return model || !provider ? null : 'select';
233
+ },
234
+ name: 'model',
235
+ message: reset('Select model:'),
236
+ choices: (prev, values) => {
237
+ const provider = modelProvider || values.modelProvider;
238
+ return MODEL_PROVIDERS[provider].models.map((m) => ({
239
+ title: m,
240
+ value: m,
241
+ }));
242
+ },
243
+ },
244
+ ],
245
+ {
246
+ onCancel: () => {
247
+ throw new Error(red('โœ–') + ' Operation cancelled');
248
+ },
249
+ },
250
+ );
251
+ } catch (cancelled) {
252
+ console.log(cancelled.message);
253
+ return;
254
+ }
255
+
256
+ // Extract values from prompts
257
+ const {
258
+ overwrite,
259
+ packageName,
260
+ description: promptDescription,
261
+ template: promptTemplate,
262
+ modelProvider: promptModelProvider,
263
+ model: promptModel,
264
+ } = result;
265
+
266
+ // Use CLI args or prompt values
267
+ template = template || promptTemplate || 'basic';
268
+ modelProvider = modelProvider || promptModelProvider || 'gemini';
269
+ model = model || promptModel || MODEL_PROVIDERS[modelProvider].models[0];
270
+ description = description || promptDescription || 'My ADK Agent';
271
+
272
+ const root = path.join(cwd, targetDir);
273
+
274
+ if (overwrite) {
275
+ emptyDir(root);
276
+ } else if (!fs.existsSync(root)) {
277
+ fs.mkdirSync(root, { recursive: true });
278
+ }
279
+
280
+ console.log(`\n${green('โœ“')} Scaffolding project in ${root}...\n`);
281
+
282
+ const templateDir = path.resolve(
283
+ fileURLToPath(import.meta.url),
284
+ '..',
285
+ '..',
286
+ 'templates',
287
+ template,
288
+ );
289
+
290
+ if (!fs.existsSync(templateDir)) {
291
+ console.error(red(`โœ– Error: Template "${template}" not found!`));
292
+ process.exit(1);
293
+ }
294
+
295
+ const write = (file, content) => {
296
+ const targetPath = renameFiles[file]
297
+ ? path.join(root, renameFiles[file])
298
+ : path.join(root, file);
299
+
300
+ if (content) {
301
+ fs.writeFileSync(targetPath, content);
302
+ } else {
303
+ copy(path.join(templateDir, file), targetPath);
304
+ }
305
+ };
306
+
307
+ // Copy all template files
308
+ const files = fs.readdirSync(templateDir);
309
+ for (const file of files.filter((f) => f !== 'package.json')) {
310
+ write(file);
311
+ }
312
+
313
+ // Handle package.json separately
314
+ const pkg = JSON.parse(
315
+ fs.readFileSync(path.join(templateDir, 'package.json'), 'utf-8'),
316
+ );
317
+ pkg.name = packageName || getProjectName();
318
+ pkg.description = description;
319
+
320
+ write('package.json', JSON.stringify(pkg, null, 2));
321
+
322
+ // Replace placeholders
323
+ const providerConfig = MODEL_PROVIDERS[modelProvider];
324
+ const modelConfig = providerConfig.modelConfig(model);
325
+
326
+ replacePlaceholders(root, 'README.md', {
327
+ __PROJECT_NAME__: pkg.name,
328
+ __DESCRIPTION__: description,
329
+ });
330
+
331
+ replacePlaceholders(root, 'src/index.ts', {
332
+ __MODEL_CONFIG__: modelConfig,
333
+ });
334
+
335
+ // Update imports if needed (for LiteLLM)
336
+ if (modelProvider !== 'gemini') {
337
+ replacePlaceholders(root, 'src/index.ts', {
338
+ "import { LlmAgent, FunctionTool } from '@google/adk';":
339
+ providerConfig.importStatement,
340
+ });
341
+ }
342
+
343
+ console.log(`${green('โœ“')} Project created successfully!\n`);
344
+ console.log(`${cyan('Next steps:')}\n`);
345
+
346
+ if (root !== cwd) {
347
+ console.log(` cd ${path.relative(cwd, root)}`);
348
+ }
349
+
350
+ console.log(` npm install`);
351
+ console.log(` cp .env.example .env`);
352
+ console.log(` ${yellow('# Edit .env and add your API key')}`);
353
+ console.log(` npm run dev\n`);
354
+
355
+ console.log(`${cyan('Configuration:')}`);
356
+ console.log(` Template: ${green(template)}`);
357
+ console.log(` Provider: ${green(providerConfig.name)}`);
358
+ console.log(` Model: ${green(model)}`);
359
+ console.log(` API Key: ${yellow(providerConfig.apiKeyVar)}\n`);
38
360
  }
361
+
362
+ init().catch((e) => {
363
+ console.error(e);
364
+ });
@@ -0,0 +1,16 @@
1
+ # Google Gemini API Key
2
+ # Get your key from: https://aistudio.google.com/apikey
3
+ GEMINI_API_KEY=your_google_api_key_here
4
+
5
+ # OR use Vertex AI (for Google Cloud)
6
+ # GOOGLE_GENAI_USE_VERTEXAI=true
7
+ # GOOGLE_CLOUD_PROJECT=your-project-id
8
+ # GOOGLE_CLOUD_LOCATION=us-central1
9
+
10
+ # OpenAI API Key (if using OpenAI models)
11
+ # Get your key from: https://platform.openai.com/api-keys
12
+ # OPENAI_API_KEY=your_openai_api_key_here
13
+
14
+ # Anthropic API Key (if using Claude models)
15
+ # Get your key from: https://console.anthropic.com/settings/keys
16
+ # ANTHROPIC_API_KEY=your_anthropic_api_key_here