copilotkit 0.0.50 → 0.0.52-0

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.
@@ -1,299 +1,29 @@
1
1
  // src/commands/create.ts
2
2
  import { Flags, Args } from "@oclif/core";
3
- import inquirer2 from "inquirer";
4
- import chalk3 from "chalk";
3
+ import inquirer from "inquirer";
4
+ import chalk2 from "chalk";
5
5
  import fs from "fs-extra";
6
6
  import path from "path";
7
7
  import { promisify } from "util";
8
8
  import { pipeline } from "stream";
9
9
  import { createWriteStream } from "fs";
10
10
  import { extract } from "tar";
11
- import ora2 from "ora";
12
-
13
- // src/services/auth.service.ts
14
- import Conf2 from "conf";
15
- import cors from "cors";
16
- import express from "express";
17
- import crypto2 from "node:crypto";
18
- import open from "open";
19
- import getPort from "get-port";
20
11
  import ora from "ora";
21
- import chalk from "chalk";
22
- import inquirer from "inquirer";
23
-
24
- // src/utils/trpc.ts
25
- import { createTRPCClient as trpcClient, httpBatchLink } from "@trpc/client";
26
- import superjson from "superjson";
27
- var COPILOT_CLOUD_BASE_URL = process.env.COPILOT_CLOUD_BASE_URL || "https://cloud.copilotkit.ai";
28
- function createTRPCClient(cliToken) {
29
- return trpcClient({
30
- links: [
31
- httpBatchLink({
32
- url: `${COPILOT_CLOUD_BASE_URL}/api/trpc-cli`,
33
- transformer: superjson,
34
- headers: () => {
35
- return {
36
- "x-trpc-source": "cli",
37
- "x-cli-token": cliToken
38
- };
39
- }
40
- })
41
- ]
42
- });
43
- }
44
-
45
- // src/services/analytics.service.ts
46
- import { Analytics } from "@segment/analytics-node";
47
- import { PostHog } from "posthog-node";
48
- import Conf from "conf";
49
- var AnalyticsService = class {
50
- constructor(authData) {
51
- this.authData = authData;
52
- if (process.env.SEGMENT_DISABLED === "true") {
53
- return;
54
- }
55
- const segmentWriteKey = process.env.SEGMENT_WRITE_KEY || "9Pv6QyExYef2P4hPz4gks6QAvNMi2AOf";
56
- this.globalProperties = {
57
- service: "cli"
58
- };
59
- if (this.authData?.userId) {
60
- this.userId = this.authData.userId;
61
- }
62
- if (this.authData?.email) {
63
- this.email = this.authData.email;
64
- this.globalProperties.email = this.authData.email;
65
- }
66
- if (this.authData?.organizationId) {
67
- this.organizationId = this.authData.organizationId;
68
- }
69
- this.segment = new Analytics({
70
- writeKey: segmentWriteKey,
71
- disable: process.env.SEGMENT_DISABLE === "true"
72
- });
73
- if (process.env.POSTHOG_DISABLED !== "true") {
74
- const posthogKey = process.env.POSTHOG_KEY || "phc_XZdymVYjrph9Mi0xZYGNyCKexxgblXRR1jMENCtdz5Q";
75
- const posthogHost = process.env.POSTHOG_HOST || "https://eu.i.posthog.com";
76
- this.posthog = new PostHog(posthogKey, {
77
- host: posthogHost
78
- });
79
- }
80
- const config = new Conf({ projectName: "CopilotKitCLI" });
81
- if (!config.get("anonymousId")) {
82
- config.set("anonymousId", crypto.randomUUID());
83
- }
84
- }
85
- segment;
86
- posthog;
87
- globalProperties = {};
88
- userId;
89
- email;
90
- organizationId;
91
- config = new Conf({ projectName: "CopilotKitCLI" });
92
- getAnonymousId() {
93
- const anonymousId = this.config.get("anonymousId");
94
- if (!anonymousId) {
95
- const anonymousId2 = crypto.randomUUID();
96
- this.config.set("anonymousId", anonymousId2);
97
- return anonymousId2;
98
- }
99
- return anonymousId;
100
- }
101
- track(event) {
102
- if (!this.segment) {
103
- return Promise.resolve();
104
- }
105
- const payload = {
106
- userId: this.userId ? this.userId : void 0,
107
- email: this.email ? this.email : void 0,
108
- anonymousId: this.getAnonymousId(),
109
- event: event.event,
110
- properties: {
111
- ...this.globalProperties,
112
- ...event.properties,
113
- $groups: this.organizationId ? {
114
- segment_group: this.organizationId
115
- } : void 0,
116
- eventProperties: {
117
- ...event.properties,
118
- ...this.globalProperties
119
- }
120
- }
121
- };
122
- return new Promise((resolve, reject) => {
123
- this.segment.track(payload, (err) => {
124
- if (err) {
125
- resolve();
126
- }
127
- resolve();
128
- });
129
- });
130
- }
131
- /**
132
- * Check if a feature flag is enabled
133
- */
134
- async isFeatureEnabled(flagKey) {
135
- if (!this.posthog) {
136
- return false;
137
- }
138
- try {
139
- const distinctId = this.userId || this.getAnonymousId();
140
- const flag = await this.posthog.isFeatureEnabled(flagKey, distinctId);
141
- return Boolean(flag);
142
- } catch (error) {
143
- console.warn(`Failed to check feature flag ${flagKey}:`, error);
144
- return false;
145
- }
146
- }
147
- /**
148
- * Get feature flag payload
149
- */
150
- async getFeatureFlagPayload(flagKey) {
151
- if (!this.posthog) {
152
- return null;
153
- }
154
- try {
155
- const distinctId = this.userId || this.getAnonymousId();
156
- const payload = await this.posthog.getFeatureFlagPayload(flagKey, distinctId);
157
- return payload;
158
- } catch (error) {
159
- console.warn(`Failed to get feature flag payload ${flagKey}:`, error);
160
- return null;
161
- }
162
- }
163
- /**
164
- * Shutdown analytics services
165
- */
166
- async shutdown() {
167
- if (this.posthog) {
168
- await this.posthog.shutdown();
169
- }
170
- }
171
- };
172
-
173
- // src/services/auth.service.ts
174
- var AuthService = class {
175
- config = new Conf2({ projectName: "CopilotKitCLI" });
176
- COPILOT_CLOUD_BASE_URL = process.env.COPILOT_CLOUD_BASE_URL || "https://cloud.copilotkit.ai";
177
- getToken() {
178
- return this.config.get("cliToken");
179
- }
180
- getCLIToken() {
181
- const cliToken = this.config.get("cliToken");
182
- return cliToken;
183
- }
184
- async logout(cmd) {
185
- this.config.delete("cliToken");
186
- }
187
- async requireLogin(cmd, context) {
188
- let cliToken = this.getCLIToken();
189
- if (!cliToken) {
190
- try {
191
- let shouldLogin = true;
192
- if (context !== "cloud-features") {
193
- const response = await inquirer.prompt([
194
- {
195
- name: "shouldLogin",
196
- type: "confirm",
197
- message: "\u{1FA81} You are not yet authenticated. Authenticate with Copilot Cloud? (press Enter to confirm)",
198
- default: true
199
- }
200
- ]);
201
- shouldLogin = response.shouldLogin;
202
- }
203
- if (shouldLogin) {
204
- if (context === "cloud-features") {
205
- cmd.log(chalk.cyan("\n\u{1F680} Setting up Copilot Cloud authentication...\n"));
206
- }
207
- const loginResult = await this.login({ exitAfterLogin: false });
208
- cliToken = loginResult.cliToken;
209
- return loginResult;
210
- } else {
211
- cmd.error("Authentication required to proceed.");
212
- }
213
- } catch (error) {
214
- if (error instanceof Error && error.name === "ExitPromptError") {
215
- cmd.error(chalk.yellow("\nAuthentication cancelled"));
216
- }
217
- throw error;
218
- }
219
- }
220
- let me;
221
- const trpcClient2 = createTRPCClient(cliToken);
222
- try {
223
- me = await trpcClient2.me.query();
224
- } catch (error) {
225
- cmd.log(chalk.yellow("Your authentication has expired. Re-authenticating..."));
226
- try {
227
- const loginResult = await this.login({ exitAfterLogin: false });
228
- return loginResult;
229
- } catch (loginError) {
230
- cmd.log(chalk.red("Could not authenticate with Copilot Cloud. Please run: npx copilotkit@latest login"));
231
- process.exit(1);
232
- }
233
- }
234
- if (!me.organization || !me.user) {
235
- cmd.error("Authentication required to proceed.");
236
- }
237
- return { cliToken, user: me.user, organization: me.organization };
238
- }
239
- async login({ exitAfterLogin } = { exitAfterLogin: true }) {
240
- const spinner = ora("\u{1FA81} Opening browser for authentication...").start();
241
- let analytics;
242
- analytics = new AnalyticsService();
243
- const app = express();
244
- app.use(cors());
245
- app.use(express.urlencoded({ extended: true }));
246
- app.use(express.json());
247
- const port = await getPort();
248
- const state = crypto2.randomBytes(16).toString("hex");
249
- return new Promise(async (resolve) => {
250
- const server = app.listen(port, () => {
251
- });
252
- await analytics.track({
253
- event: "cli.login.initiated",
254
- properties: {}
255
- });
256
- spinner.text = "\u{1FA81} Waiting for browser authentication to complete...";
257
- app.post("/callback", async (req, res) => {
258
- const { cliToken, user, organization } = req.body;
259
- analytics = new AnalyticsService({ userId: user.id, organizationId: organization.id, email: user.email });
260
- await analytics.track({
261
- event: "cli.login.success",
262
- properties: {
263
- organizationId: organization.id,
264
- userId: user.id,
265
- email: user.email
266
- }
267
- });
268
- if (state !== req.query.state) {
269
- res.status(401).json({ message: "Invalid state" });
270
- spinner.fail("Invalid state");
271
- return;
272
- }
273
- this.config.set("cliToken", cliToken);
274
- res.status(200).json({ message: "Callback called" });
275
- spinner.succeed(`\u{1FA81} Successfully logged in as ${chalk.hex("#7553fc")(user.email)}`);
276
- if (exitAfterLogin) {
277
- process.exit(0);
278
- } else {
279
- server.close();
280
- resolve({ cliToken, user, organization });
281
- }
282
- });
283
- open(`${this.COPILOT_CLOUD_BASE_URL}/cli-auth?callbackUrl=http://localhost:${port}/callback&state=${state}`);
284
- });
285
- }
286
- };
287
12
 
288
13
  // src/commands/base-command.ts
289
14
  import { Command } from "@oclif/core";
290
15
  import Sentry, { consoleIntegration } from "@sentry/node";
291
16
 
292
17
  // src/utils/version.ts
293
- var LIB_VERSION = "0.0.50";
18
+ var LIB_VERSION = "0.0.52-0";
19
+
20
+ // src/utils/trpc.ts
21
+ import { createTRPCClient as trpcClient, httpBatchLink } from "@trpc/client";
22
+ import superjson from "superjson";
23
+ var COPILOT_CLOUD_BASE_URL = process.env.COPILOT_CLOUD_BASE_URL || "https://cloud.copilotkit.ai";
294
24
 
295
25
  // src/commands/base-command.ts
296
- import chalk2 from "chalk";
26
+ import chalk from "chalk";
297
27
  var BaseCommand = class extends Command {
298
28
  async init() {
299
29
  await this.checkCLIVersion();
@@ -309,12 +39,13 @@ var BaseCommand = class extends Command {
309
39
  });
310
40
  }
311
41
  async catch(err) {
312
- if (process.env.SENTRY_DISABLED === "true") {
313
- super.catch(err);
314
- return;
42
+ if (process.env.SENTRY_DISABLED !== "true") {
43
+ Sentry.captureException(err);
315
44
  }
316
- Sentry.captureException(err);
317
- super.catch(err);
45
+ const message = err?.message ?? "Unknown error";
46
+ this.log("\n" + chalk.red(message) + "\n");
47
+ const exitCode = err?.oclif?.exit ?? 1;
48
+ this.exit(exitCode);
318
49
  }
319
50
  async finally() {
320
51
  if (process.env.SENTRY_DISABLED === "true") {
@@ -333,7 +64,7 @@ var BaseCommand = class extends Command {
333
64
  }
334
65
  }
335
66
  async gracefulError(message) {
336
- this.log("\n" + chalk2.red(message));
67
+ this.log("\n" + chalk.red(message));
337
68
  process.exit(1);
338
69
  }
339
70
  };
@@ -341,14 +72,14 @@ var BaseCommand = class extends Command {
341
72
  // src/commands/create.ts
342
73
  var streamPipeline = promisify(pipeline);
343
74
  var theme = {
344
- primary: chalk3.magenta,
345
- secondary: chalk3.gray,
346
- tertiary: chalk3.gray,
347
- error: chalk3.red,
348
- command: chalk3.blue,
349
- success: chalk3.green,
350
- warning: chalk3.yellow,
351
- divider: chalk3.gray("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"),
75
+ primary: chalk2.magenta,
76
+ secondary: chalk2.gray,
77
+ tertiary: chalk2.gray,
78
+ error: chalk2.red,
79
+ command: chalk2.blue,
80
+ success: chalk2.green,
81
+ warning: chalk2.yellow,
82
+ divider: chalk2.gray("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"),
352
83
  bottomPadding: ""
353
84
  };
354
85
  var TEMPLATE_REPOS = {
@@ -359,7 +90,8 @@ var TEMPLATE_REPOS = {
359
90
  llamaindex: "copilotkit/with-llamaindex",
360
91
  agno: "copilotkit/with-agno",
361
92
  "pydantic-ai": "copilotkit/with-pydantic-ai",
362
- ag2: "ag2ai/ag2-copilotkit-starter"
93
+ ag2: "ag2ai/ag2-copilotkit-starter",
94
+ adk: "copilotkit/with-adk"
363
95
  };
364
96
  var FRAMEWORK_DOCUMENTATION = {
365
97
  "langgraph-py": "https://langchain-ai.github.io/langgraph/concepts/why-langgraph",
@@ -369,7 +101,8 @@ var FRAMEWORK_DOCUMENTATION = {
369
101
  "pydantic-ai": "https://ai.pydantic.dev/ag-ui/",
370
102
  llamaindex: "https://docs.llamaindex.ai/en/stable",
371
103
  agno: "https://docs.agno.com/",
372
- ag2: "https://docs.ag2.ai/latest/docs/user-guide/basic-concepts/overview"
104
+ ag2: "https://docs.ag2.ai/latest/docs/user-guide/basic-concepts/overview",
105
+ adk: "https://google.github.io/adk-docs/"
373
106
  };
374
107
  var FRAMEWORK_EMOJI = {
375
108
  "langgraph-js": "\u{1F99C}",
@@ -379,7 +112,8 @@ var FRAMEWORK_EMOJI = {
379
112
  "pydantic-ai": "\u{1F53C}",
380
113
  llamaindex: "\u{1F999}",
381
114
  ag2: "\u{1F916}",
382
- agno: "\u{1F170}\uFE0F"
115
+ agno: "\u{1F170}\uFE0F",
116
+ adk: "\u{1F916}"
383
117
  };
384
118
  var KITE = `
385
119
  \u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF
@@ -399,15 +133,7 @@ var KITE = `
399
133
  \u28F7\u28FE\u28FF\u28E4\u28FE\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF
400
134
  `;
401
135
  var Create = class _Create extends BaseCommand {
402
- constructor(argv, config, authService = new AuthService()) {
403
- super(argv, config);
404
- this.authService = authService;
405
- }
406
- trpcClient = null;
407
- analytics = null;
408
- startTime = Date.now();
409
- analyticsQueue = [];
410
- static description = "Create a new CopilotKit project with Next.js and Cloud setup";
136
+ static description = "Create a new CopilotKit project";
411
137
  static examples = [
412
138
  "$ copilotkit create my-app",
413
139
  "$ copilotkit create my-app --framework langgraph-js",
@@ -433,7 +159,7 @@ var Create = class _Create extends BaseCommand {
433
159
  required: false
434
160
  }),
435
161
  project: Flags.string({
436
- description: "project ID (can be found in the Copilot Cloud dashboard)"
162
+ description: "project ID (deprecated, kept for backwards compatibility)"
437
163
  })
438
164
  };
439
165
  static args = {
@@ -442,135 +168,82 @@ var Create = class _Create extends BaseCommand {
442
168
  required: false
443
169
  })
444
170
  };
171
+ constructor(argv, config) {
172
+ super(argv, config);
173
+ }
445
174
  async run() {
446
175
  const { args, flags } = await this.parse(_Create);
447
- try {
448
- this.analytics = new AnalyticsService();
449
- if (!flags["no-banner"]) {
450
- this.log(theme.primary(KITE));
451
- this.log(theme.primary("~ Welcome to CopilotKit! ~\n"));
452
- this.log(theme.divider);
453
- if ((!flags.name || flags.projectName) && !flags.framework) {
454
- this.log("\n" + theme.secondary("Just a few questions to get started!\n"));
455
- }
456
- }
457
- const projectName = flags.name || args.projectName || await this.promptProjectName();
458
- const agentFramework = flags.framework || await this.promptAgentFramework();
459
- this.queueAnalytics("cli.create.started", {
460
- framework_selected: agentFramework,
461
- project_name: projectName,
462
- flags_used: Object.keys(flags).filter((key) => flags[key] !== void 0 && key !== "help")
463
- });
464
- const projectDir = path.resolve(process.cwd(), projectName);
465
- if (fs.existsSync(projectDir)) {
466
- this.log(theme.error(`
467
- Directory "${projectName}" already exists.`));
468
- this.log(theme.secondary("\nYou can:"));
469
- this.log(theme.secondary(" 1. Choose a different project name"));
470
- this.log(theme.secondary(" 2. Remove the existing directory manually if you want to use this name\n"));
471
- this.exit(1);
472
- }
473
- this.log(chalk3.cyan("\n\u{1F511} Now get your API key"));
474
- this.log(chalk3.gray("Setting up your cloud account and retrieving your API key...\n"));
475
- let cloudSetupInfo = null;
476
- try {
477
- cloudSetupInfo = await this.setupCloudApiKey(flags);
478
- if (this.analytics && cloudSetupInfo.cliToken) {
479
- const trpcClient2 = createTRPCClient(cloudSetupInfo.cliToken);
480
- const me = await trpcClient2.me.query();
481
- if (me.user && me.organization) {
482
- this.analytics = new AnalyticsService({
483
- userId: me.user.id,
484
- organizationId: me.organization.id,
485
- email: me.user.email
486
- });
487
- }
488
- }
489
- this.queueAnalytics("cli.create.cloud_setup_completed", {
490
- framework: agentFramework,
491
- project_id: cloudSetupInfo.selectedProjectId,
492
- api_key_retrieved: !!cloudSetupInfo.apiKey
493
- });
494
- } catch (error) {
495
- this.queueAnalytics("cli.create.cloud_setup_failed", {
496
- framework: agentFramework,
497
- error: error.message
498
- });
499
- throw error;
176
+ if (!flags["no-banner"]) {
177
+ this.log(theme.primary(KITE));
178
+ this.log(theme.primary("~ Welcome to CopilotKit! ~\n"));
179
+ this.log(theme.divider);
180
+ if ((!flags.name || flags.projectName) && !flags.framework) {
181
+ this.log("\n" + theme.secondary("Just a few questions to get started!\n"));
500
182
  }
501
- const options = {
502
- projectName,
503
- agentFramework,
504
- apiKey: cloudSetupInfo?.apiKey,
505
- projectId: cloudSetupInfo?.selectedProjectId
506
- };
507
- const spinner = ora2({
508
- text: theme.secondary.bold("Creating your project..."),
509
- color: "cyan",
510
- spinner: "dots"
511
- }).start();
512
- try {
513
- await fs.ensureDir(projectDir);
514
- spinner.text = theme.secondary.bold("Downloading template...");
515
- await this.downloadTemplate(projectDir, options.agentFramework);
516
- if (options.apiKey) {
517
- spinner.text = theme.secondary.bold("Configuring API key...");
518
- await this.configureApiKey(projectDir, options.apiKey);
519
- }
520
- spinner.succeed(theme.secondary.bold(`Project "${projectName}" created successfully!`));
521
- this.queueAnalytics("cli.create.project_created", {
522
- framework: agentFramework,
523
- project_name: projectName,
524
- has_api_key: !!options.apiKey,
525
- duration_ms: Date.now() - this.startTime
526
- });
527
- this.log("\n" + theme.divider);
528
- this.log(
529
- "\n" + theme.secondary.bold(
530
- `\u{1FA81}\u{1F91D}${FRAMEWORK_EMOJI[options.agentFramework]} All set!
531
-
532
- Your project is ready with Copilot Cloud configured.`
533
- )
534
- );
535
- this.log("\n" + theme.secondary("Next steps:"));
536
- this.log(theme.secondary(` \u2022 ${theme.command(`cd ${projectName}`)}`));
537
- this.log(theme.secondary(" \u2022 Follow the setup instructions in the README.md"));
538
- this.log("\n" + theme.secondary("Documentation:"));
539
- this.log(theme.secondary(" \u2022 ") + theme.command("https://docs.copilotkit.ai"));
540
- this.log(theme.secondary(" \u2022 ") + theme.command(FRAMEWORK_DOCUMENTATION[options.agentFramework]));
541
- this.log(theme.bottomPadding);
542
- this.queueAnalytics("cli.create.completed", {
543
- framework: agentFramework,
544
- project_name: projectName,
545
- cloud_setup_completed: !!cloudSetupInfo,
546
- api_key_configured: !!options.apiKey,
547
- duration_ms: Date.now() - this.startTime
548
- });
549
- await this.flushAnalytics();
550
- } catch (error) {
551
- spinner.fail(theme.error(`Failed to create project: ${error.message}`));
552
- this.queueAnalytics("cli.create.failed", {
553
- framework: agentFramework,
554
- project_name: projectName,
555
- error: error.message,
556
- step: "project_creation",
557
- duration_ms: Date.now() - this.startTime
558
- });
559
- await this.flushAnalytics();
183
+ }
184
+ const projectNameInput = flags.name || args.projectName || await this.promptProjectName();
185
+ const projectName = projectNameInput.trim();
186
+ const usingCurrentDir = projectName === "." || projectName === "./";
187
+ const agentFramework = flags.framework || await this.promptAgentFramework();
188
+ const projectDir = usingCurrentDir ? process.cwd() : path.resolve(process.cwd(), projectName);
189
+ if (usingCurrentDir) {
190
+ const allowedEntries = /* @__PURE__ */ new Set([".git", ".gitignore", ".DS_Store"]);
191
+ const existingEntries = await fs.readdir(projectDir);
192
+ const blockingEntries = existingEntries.filter((entry) => !allowedEntries.has(entry));
193
+ if (blockingEntries.length > 0) {
194
+ this.log(theme.error("\nCurrent directory is not empty."));
195
+ this.log(theme.secondary("\nPlease run create in an empty directory or specify a new project name."));
560
196
  this.exit(1);
561
197
  }
198
+ } else if (await fs.pathExists(projectDir)) {
199
+ this.log(theme.error(`
200
+ Directory "${projectName}" already exists.`));
201
+ this.log(theme.secondary("\nYou can:"));
202
+ this.log(theme.secondary(" 1. Choose a different project name"));
203
+ this.log(theme.secondary(" 2. Remove the existing directory manually if you want to use this name\n"));
204
+ this.exit(1);
205
+ }
206
+ const options = {
207
+ projectName,
208
+ agentFramework
209
+ };
210
+ const spinner = ora({
211
+ text: theme.secondary.bold("Creating your project..."),
212
+ color: "cyan",
213
+ spinner: "dots"
214
+ }).start();
215
+ try {
216
+ await fs.ensureDir(projectDir);
217
+ spinner.text = theme.secondary.bold("Downloading template...");
218
+ await this.downloadTemplate(projectDir, options.agentFramework);
219
+ const displayName = usingCurrentDir ? "current directory" : `"${projectName}"`;
220
+ spinner.succeed(theme.secondary.bold(`Project ${displayName} created successfully!`));
562
221
  } catch (error) {
563
- this.queueAnalytics("cli.create.failed", {
564
- error: error.message,
565
- step: "initialization",
566
- duration_ms: Date.now() - this.startTime
567
- });
568
- await this.flushAnalytics();
569
- this.gracefulError(error.message);
222
+ spinner.fail(theme.error(`Failed to create project: ${error.message}`));
223
+ this.exit(1);
224
+ }
225
+ this.log("\n" + theme.divider);
226
+ this.log(
227
+ "\n" + theme.secondary.bold(
228
+ `\u{1FA81}\u{1F91D}${FRAMEWORK_EMOJI[options.agentFramework]} All set!
229
+
230
+ Your project is ready to explore CopilotKit locally.`
231
+ )
232
+ );
233
+ this.log("\n" + theme.secondary("Next steps:"));
234
+ if (usingCurrentDir) {
235
+ this.log(theme.secondary(" \u2022 You are already inside your new project directory"));
236
+ } else {
237
+ this.log(theme.secondary(` \u2022 ${theme.command(`cd ${projectName}`)}`));
570
238
  }
239
+ this.log(theme.secondary(" \u2022 Follow the setup instructions in the README.md"));
240
+ this.log("\n" + theme.secondary("Documentation:"));
241
+ this.log(theme.secondary(" \u2022 ") + theme.command("https://docs.copilotkit.ai"));
242
+ this.log(theme.secondary(" \u2022 ") + theme.command(FRAMEWORK_DOCUMENTATION[options.agentFramework]));
243
+ this.log(theme.bottomPadding);
571
244
  }
572
245
  async promptProjectName() {
573
- const { projectName } = await inquirer2.prompt([
246
+ const { projectName } = await inquirer.prompt([
574
247
  {
575
248
  type: "input",
576
249
  name: "projectName",
@@ -590,7 +263,7 @@ Your project is ready with Copilot Cloud configured.`
590
263
  return projectName;
591
264
  }
592
265
  async promptAgentFramework() {
593
- const { framework } = await inquirer2.prompt([
266
+ const { framework } = await inquirer.prompt([
594
267
  {
595
268
  type: "list",
596
269
  name: "framework",
@@ -600,6 +273,7 @@ Your project is ready with Copilot Cloud configured.`
600
273
  { name: `${FRAMEWORK_EMOJI["langgraph-js"]} LangGraph (JavaScript)`, value: "langgraph-js" },
601
274
  { name: `${FRAMEWORK_EMOJI.mastra} Mastra`, value: "mastra" },
602
275
  { name: `${FRAMEWORK_EMOJI["pydantic-ai"]} Pydantic AI`, value: "pydantic-ai" },
276
+ { name: `${FRAMEWORK_EMOJI.adk} ADK`, value: "adk" },
603
277
  { name: `${FRAMEWORK_EMOJI.flows} CrewAI Flows`, value: "flows" },
604
278
  { name: `${FRAMEWORK_EMOJI.llamaindex} LlamaIndex`, value: "llamaindex" },
605
279
  { name: `${FRAMEWORK_EMOJI.agno} Agno`, value: "agno" },
@@ -629,100 +303,6 @@ Your project is ready with Copilot Cloud configured.`
629
303
  throw new Error(`Failed to download template: ${error.message}`);
630
304
  }
631
305
  }
632
- /**
633
- * Queue an analytics event to be sent later (non-blocking)
634
- */
635
- queueAnalytics(event, properties) {
636
- this.analyticsQueue.push({ event, properties });
637
- }
638
- /**
639
- * Send all queued analytics events in fire-and-forget manner
640
- */
641
- async flushAnalytics() {
642
- if (!this.analytics || this.analyticsQueue.length === 0) {
643
- return;
644
- }
645
- const promises = this.analyticsQueue.map(
646
- ({ event, properties }) => this.analytics.track({ event, properties }).catch(() => {
647
- })
648
- );
649
- Promise.all(promises).catch(() => {
650
- });
651
- if (this.analytics) {
652
- this.analytics.shutdown().catch(() => {
653
- });
654
- }
655
- }
656
- async setupCloudApiKey(flags) {
657
- const { cliToken, organization } = await this.authService.requireLogin(this, "cloud-features");
658
- this.trpcClient = createTRPCClient(cliToken);
659
- const availableProjects = await this.trpcClient.listOrgProjects.query({ orgId: organization.id });
660
- let selectedProjectId;
661
- if (flags.project) {
662
- if (!availableProjects.some((project) => project.id === flags.project)) {
663
- this.log(chalk3.red(`\u{1F4C1} Project with ID ${flags.project} not found`));
664
- process.exit(1);
665
- }
666
- selectedProjectId = flags.project;
667
- this.log(chalk3.green(`\u{1F4C1} Selected project ${selectedProjectId}`));
668
- } else if (availableProjects.length === 1) {
669
- selectedProjectId = availableProjects[0].id;
670
- this.log(chalk3.green(`\u{1F4C1} Auto-selected project ${selectedProjectId}`));
671
- } else {
672
- const { projectId } = await inquirer2.prompt([
673
- {
674
- name: "projectId",
675
- type: "list",
676
- message: "\u{1F4C1} Choose a project:",
677
- choices: availableProjects.map((project) => ({
678
- value: project.id,
679
- name: `${project.name} (ID: ${project.id})`
680
- }))
681
- }
682
- ]);
683
- selectedProjectId = projectId;
684
- }
685
- const spinner = ora2({
686
- text: "Retrieving your API key...",
687
- color: "cyan"
688
- }).start();
689
- try {
690
- const copilotCloudPublicApiKey = await this.trpcClient.getCopilotCloudPublicApiKey.query({
691
- projectId: selectedProjectId
692
- });
693
- if (!copilotCloudPublicApiKey?.key) {
694
- spinner.fail("Failed to retrieve API key");
695
- throw new Error("No API key found for the selected project");
696
- }
697
- spinner.succeed("\u2705 API key retrieved successfully");
698
- return {
699
- cliToken,
700
- organization,
701
- selectedProjectId,
702
- apiKey: copilotCloudPublicApiKey.key
703
- };
704
- } catch (error) {
705
- spinner.fail("Failed to retrieve API key");
706
- throw error;
707
- }
708
- }
709
- async configureApiKey(projectDir, apiKey) {
710
- const envPath = path.join(projectDir, ".env.local");
711
- const envExamplePath = path.join(projectDir, ".env.example");
712
- try {
713
- let envContent = "";
714
- if (await fs.pathExists(envExamplePath)) {
715
- envContent = await fs.readFile(envExamplePath, "utf8");
716
- envContent = envContent.replace(/COPILOT_CLOUD_PUBLIC_API_KEY=.*/g, `COPILOT_CLOUD_PUBLIC_API_KEY=${apiKey}`);
717
- } else {
718
- envContent = `COPILOT_CLOUD_PUBLIC_API_KEY=${apiKey}
719
- `;
720
- }
721
- await fs.writeFile(envPath, envContent);
722
- } catch (error) {
723
- console.warn("Warning: Could not configure API key in .env.local file");
724
- }
725
- }
726
306
  };
727
307
  export {
728
308
  Create as default