copilotkit 0.0.47 → 0.0.49
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.
- package/dist/commands/base-command.js +1 -1
- package/dist/commands/base-command.js.map +1 -1
- package/dist/commands/create.js +12 -14
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/dev.js +10 -4
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +626 -200
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.js +10 -4
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +10 -4
- package/dist/commands/logout.js.map +1 -1
- package/dist/services/auth.service.js +9 -3
- package/dist/services/auth.service.js.map +1 -1
- package/dist/utils/version.d.ts +1 -1
- package/dist/utils/version.js +1 -1
- package/dist/utils/version.js.map +1 -1
- package/oclif.manifest.json +4 -3
- package/package.json +1 -1
package/dist/commands/init.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// src/commands/init.ts
|
|
2
|
-
import { Flags as
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
2
|
+
import { Flags as Flags3 } from "@oclif/core";
|
|
3
|
+
import inquirer4 from "inquirer";
|
|
4
|
+
import path7 from "path";
|
|
5
|
+
import fs7 from "fs";
|
|
6
6
|
|
|
7
7
|
// src/services/auth.service.ts
|
|
8
8
|
import Conf2 from "conf";
|
|
@@ -196,7 +196,7 @@ var AuthService = class {
|
|
|
196
196
|
}
|
|
197
197
|
if (shouldLogin) {
|
|
198
198
|
if (context === "cloud-features") {
|
|
199
|
-
cmd.log(chalk.cyan("\n\u{1F680} Setting up Copilot Cloud authentication
|
|
199
|
+
cmd.log(chalk.cyan("\n\u{1F680} Setting up Copilot Cloud authentication...\n"));
|
|
200
200
|
}
|
|
201
201
|
const loginResult = await this.login({ exitAfterLogin: false });
|
|
202
202
|
cliToken = loginResult.cliToken;
|
|
@@ -216,8 +216,14 @@ var AuthService = class {
|
|
|
216
216
|
try {
|
|
217
217
|
me = await trpcClient2.me.query();
|
|
218
218
|
} catch (error) {
|
|
219
|
-
cmd.log(chalk.
|
|
220
|
-
|
|
219
|
+
cmd.log(chalk.yellow("Your authentication has expired. Re-authenticating..."));
|
|
220
|
+
try {
|
|
221
|
+
const loginResult = await this.login({ exitAfterLogin: false });
|
|
222
|
+
return loginResult;
|
|
223
|
+
} catch (loginError) {
|
|
224
|
+
cmd.log(chalk.red("Could not authenticate with Copilot Cloud. Please run: npx copilotkit@latest login"));
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
221
227
|
}
|
|
222
228
|
if (!me.organization || !me.user) {
|
|
223
229
|
cmd.error("Authentication required to proceed.");
|
|
@@ -278,7 +284,7 @@ import { Command } from "@oclif/core";
|
|
|
278
284
|
import Sentry, { consoleIntegration } from "@sentry/node";
|
|
279
285
|
|
|
280
286
|
// src/utils/version.ts
|
|
281
|
-
var LIB_VERSION = "0.0.
|
|
287
|
+
var LIB_VERSION = "0.0.49";
|
|
282
288
|
|
|
283
289
|
// src/commands/base-command.ts
|
|
284
290
|
import chalk2 from "chalk";
|
|
@@ -326,9 +332,406 @@ var BaseCommand = class extends Command {
|
|
|
326
332
|
}
|
|
327
333
|
};
|
|
328
334
|
|
|
335
|
+
// src/commands/create.ts
|
|
336
|
+
import { Flags, Args } from "@oclif/core";
|
|
337
|
+
import inquirer2 from "inquirer";
|
|
338
|
+
import chalk3 from "chalk";
|
|
339
|
+
import fs from "fs-extra";
|
|
340
|
+
import path from "path";
|
|
341
|
+
import { promisify } from "util";
|
|
342
|
+
import { pipeline } from "stream";
|
|
343
|
+
import { createWriteStream } from "fs";
|
|
344
|
+
import { extract } from "tar";
|
|
345
|
+
import ora2 from "ora";
|
|
346
|
+
var streamPipeline = promisify(pipeline);
|
|
347
|
+
var theme = {
|
|
348
|
+
primary: chalk3.magenta,
|
|
349
|
+
secondary: chalk3.gray,
|
|
350
|
+
tertiary: chalk3.gray,
|
|
351
|
+
error: chalk3.red,
|
|
352
|
+
command: chalk3.blue,
|
|
353
|
+
success: chalk3.green,
|
|
354
|
+
warning: chalk3.yellow,
|
|
355
|
+
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"),
|
|
356
|
+
bottomPadding: ""
|
|
357
|
+
};
|
|
358
|
+
var TEMPLATE_REPOS = {
|
|
359
|
+
"langgraph-py": "copilotkit/with-langgraph-python",
|
|
360
|
+
"langgraph-js": "copilotkit/with-langgraph-js",
|
|
361
|
+
mastra: "copilotkit/with-mastra",
|
|
362
|
+
flows: "copilotkit/with-crewai-flows",
|
|
363
|
+
llamaindex: "copilotkit/with-llamaindex",
|
|
364
|
+
agno: "copilotkit/with-agno",
|
|
365
|
+
"pydantic-ai": "copilotkit/with-pydantic-ai",
|
|
366
|
+
ag2: "ag2ai/ag2-copilotkit-starter"
|
|
367
|
+
};
|
|
368
|
+
var FRAMEWORK_DOCUMENTATION = {
|
|
369
|
+
"langgraph-py": "https://langchain-ai.github.io/langgraph/concepts/why-langgraph",
|
|
370
|
+
"langgraph-js": "https://langchain-ai.github.io/langgraphjs",
|
|
371
|
+
flows: "https://docs.crewai.com/guides/flows/first-flow",
|
|
372
|
+
mastra: "https://mastra.ai/en/docs",
|
|
373
|
+
"pydantic-ai": "https://ai.pydantic.dev/ag-ui/",
|
|
374
|
+
llamaindex: "https://docs.llamaindex.ai/en/stable",
|
|
375
|
+
agno: "https://docs.agno.com/",
|
|
376
|
+
ag2: "https://docs.ag2.ai/latest/docs/user-guide/basic-concepts/overview"
|
|
377
|
+
};
|
|
378
|
+
var FRAMEWORK_EMOJI = {
|
|
379
|
+
"langgraph-js": "\u{1F99C}",
|
|
380
|
+
"langgraph-py": "\u{1F99C}",
|
|
381
|
+
flows: "\u{1F465}",
|
|
382
|
+
mastra: "\u{1F311}",
|
|
383
|
+
"pydantic-ai": "\u{1F53C}",
|
|
384
|
+
llamaindex: "\u{1F999}",
|
|
385
|
+
ag2: "\u{1F916}",
|
|
386
|
+
agno: "\u{1F170}\uFE0F"
|
|
387
|
+
};
|
|
388
|
+
var KITE = `
|
|
389
|
+
\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
|
|
390
|
+
\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u281F\u2819\u28FF\u285B\u283B\u283F\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF
|
|
391
|
+
\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u280B\u2800\u2800\u2808\u28BF\u2844\u2800\u2800\u2800\u2808\u2809\u2819\u28FB\u28FF\u28FF\u28FF
|
|
392
|
+
\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u281F\u2801\u2800\u2800\u2800\u2800\u2808\u28BF\u2844\u2800\u2880\u28E0\u28F4\u283E\u280B\u28B8\u28FF\u28FF
|
|
393
|
+
\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u285F\u2801\u2880\u28C0\u28C0\u28C0\u28C0\u28E4\u28E4\u287E\u28BF\u285F\u281B\u2809\u2800\u2800\u2800\u2800\u28FF\u28FF
|
|
394
|
+
\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u285B\u281B\u281B\u281B\u2809\u2809\u2809\u2801\u2800\u28A0\u287F\u28FF\u2840\u2800\u2800\u2800\u2800\u2800\u28FF\u28FF
|
|
395
|
+
\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28C6\u2800\u2800\u2800\u2800\u2800\u2800\u28F0\u285F\u2800\u2838\u28E7\u2800\u2800\u2800\u2800\u28A0\u28FF\u28FF
|
|
396
|
+
\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28F7\u28C4\u2800\u2800\u2880\u28FC\u280F\u2800\u2800\u2800\u28FF\u2840\u2800\u2800\u2800\u28B8\u28FF\u28FF
|
|
397
|
+
\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2802\u28E0\u287F\u2801\u2800\u2800\u2800\u2800\u28B8\u2847\u2800\u2800\u2800\u28FF\u28FF\u28FF
|
|
398
|
+
\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u281F\u28E1\u28FE\u28FF\u28C4\u2800\u2800\u2800\u2800\u2800\u28B8\u2847\u2800\u2800\u28B0\u28FF\u28FF\u28FF
|
|
399
|
+
\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u285F\u281B\u287F\u280B\u28E1\u28FE\u28FF\u28FF\u28FF\u28FF\u28E6\u2840\u2800\u2800\u2800\u28B8\u2847\u2800\u2800\u28FF\u28FF\u28FF\u28FF
|
|
400
|
+
\u28FF\u28FF\u28FF\u28FF\u287F\u283F\u28FF\u2837\u2802\u2840\u2818\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28F7\u2840\u2800\u2800\u28B8\u2847\u2800\u28FC\u28FF\u28FF\u28FF\u28FF
|
|
401
|
+
\u28FF\u28FF\u283B\u28BF\u2877\u2800\u2801\u2834\u28FF\u28F7\u28FE\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u2844\u2800\u28FE\u2807\u28F4\u28FF\u28FF\u28FF\u28FF\u28FF
|
|
402
|
+
\u287F\u281B\u2800\u2800\u28B4\u28FE\u28F7\u28F6\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF\u28E4\u28FF\u28FE\u28FF\u28FF\u28FF\u28FF\u28FF\u28FF
|
|
403
|
+
\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
|
|
404
|
+
`;
|
|
405
|
+
var Create = class _Create extends BaseCommand {
|
|
406
|
+
constructor(argv, config, authService = new AuthService()) {
|
|
407
|
+
super(argv, config);
|
|
408
|
+
this.authService = authService;
|
|
409
|
+
}
|
|
410
|
+
trpcClient = null;
|
|
411
|
+
analytics = null;
|
|
412
|
+
startTime = Date.now();
|
|
413
|
+
analyticsQueue = [];
|
|
414
|
+
static description = "Create a new CopilotKit project with Next.js and Cloud setup";
|
|
415
|
+
static examples = [
|
|
416
|
+
"$ copilotkit create my-app",
|
|
417
|
+
"$ copilotkit create my-app --framework langgraph-js",
|
|
418
|
+
"$ copilotkit create -n my-app -f langgraph-js"
|
|
419
|
+
];
|
|
420
|
+
static flags = {
|
|
421
|
+
...BaseCommand.flags,
|
|
422
|
+
framework: Flags.string({
|
|
423
|
+
char: "f",
|
|
424
|
+
description: "Agent framework to use",
|
|
425
|
+
options: Object.keys(TEMPLATE_REPOS),
|
|
426
|
+
required: false
|
|
427
|
+
}),
|
|
428
|
+
name: Flags.string({
|
|
429
|
+
char: "n",
|
|
430
|
+
description: "Name of the project",
|
|
431
|
+
required: false
|
|
432
|
+
}),
|
|
433
|
+
"no-banner": Flags.boolean({
|
|
434
|
+
char: "q",
|
|
435
|
+
description: "Removes the banner",
|
|
436
|
+
default: false,
|
|
437
|
+
required: false
|
|
438
|
+
}),
|
|
439
|
+
project: Flags.string({
|
|
440
|
+
description: "project ID (can be found in the Copilot Cloud dashboard)"
|
|
441
|
+
})
|
|
442
|
+
};
|
|
443
|
+
static args = {
|
|
444
|
+
projectName: Args.string({
|
|
445
|
+
description: "Name of the project",
|
|
446
|
+
required: false
|
|
447
|
+
})
|
|
448
|
+
};
|
|
449
|
+
async run() {
|
|
450
|
+
const { args, flags } = await this.parse(_Create);
|
|
451
|
+
try {
|
|
452
|
+
this.analytics = new AnalyticsService();
|
|
453
|
+
if (!flags["no-banner"]) {
|
|
454
|
+
this.log(theme.primary(KITE));
|
|
455
|
+
this.log(theme.primary("~ Welcome to CopilotKit! ~\n"));
|
|
456
|
+
this.log(theme.divider);
|
|
457
|
+
if ((!flags.name || flags.projectName) && !flags.framework) {
|
|
458
|
+
this.log("\n" + theme.secondary("Just a few questions to get started!\n"));
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
const projectName = flags.name || args.projectName || await this.promptProjectName();
|
|
462
|
+
const agentFramework = flags.framework || await this.promptAgentFramework();
|
|
463
|
+
this.queueAnalytics("cli.create.started", {
|
|
464
|
+
framework_selected: agentFramework,
|
|
465
|
+
project_name: projectName,
|
|
466
|
+
flags_used: Object.keys(flags).filter((key) => flags[key] !== void 0 && key !== "help")
|
|
467
|
+
});
|
|
468
|
+
const projectDir = path.resolve(process.cwd(), projectName);
|
|
469
|
+
if (fs.existsSync(projectDir)) {
|
|
470
|
+
this.log(theme.error(`
|
|
471
|
+
Directory "${projectName}" already exists.`));
|
|
472
|
+
this.log(theme.secondary("\nYou can:"));
|
|
473
|
+
this.log(theme.secondary(" 1. Choose a different project name"));
|
|
474
|
+
this.log(theme.secondary(" 2. Remove the existing directory manually if you want to use this name\n"));
|
|
475
|
+
this.exit(1);
|
|
476
|
+
}
|
|
477
|
+
this.log(chalk3.cyan("\n\u{1F511} Now get your API key"));
|
|
478
|
+
this.log(chalk3.gray("Setting up your cloud account and retrieving your API key...\n"));
|
|
479
|
+
let cloudSetupInfo = null;
|
|
480
|
+
try {
|
|
481
|
+
cloudSetupInfo = await this.setupCloudApiKey(flags);
|
|
482
|
+
if (this.analytics && cloudSetupInfo.cliToken) {
|
|
483
|
+
const trpcClient2 = createTRPCClient(cloudSetupInfo.cliToken);
|
|
484
|
+
const me = await trpcClient2.me.query();
|
|
485
|
+
if (me.user && me.organization) {
|
|
486
|
+
this.analytics = new AnalyticsService({
|
|
487
|
+
userId: me.user.id,
|
|
488
|
+
organizationId: me.organization.id,
|
|
489
|
+
email: me.user.email
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
this.queueAnalytics("cli.create.cloud_setup_completed", {
|
|
494
|
+
framework: agentFramework,
|
|
495
|
+
project_id: cloudSetupInfo.selectedProjectId,
|
|
496
|
+
api_key_retrieved: !!cloudSetupInfo.apiKey
|
|
497
|
+
});
|
|
498
|
+
} catch (error) {
|
|
499
|
+
this.queueAnalytics("cli.create.cloud_setup_failed", {
|
|
500
|
+
framework: agentFramework,
|
|
501
|
+
error: error.message
|
|
502
|
+
});
|
|
503
|
+
throw error;
|
|
504
|
+
}
|
|
505
|
+
const options = {
|
|
506
|
+
projectName,
|
|
507
|
+
agentFramework,
|
|
508
|
+
apiKey: cloudSetupInfo?.apiKey,
|
|
509
|
+
projectId: cloudSetupInfo?.selectedProjectId
|
|
510
|
+
};
|
|
511
|
+
const spinner = ora2({
|
|
512
|
+
text: theme.secondary.bold("Creating your project..."),
|
|
513
|
+
color: "cyan",
|
|
514
|
+
spinner: "dots"
|
|
515
|
+
}).start();
|
|
516
|
+
try {
|
|
517
|
+
await fs.ensureDir(projectDir);
|
|
518
|
+
spinner.text = theme.secondary.bold("Downloading template...");
|
|
519
|
+
await this.downloadTemplate(projectDir, options.agentFramework);
|
|
520
|
+
if (options.apiKey) {
|
|
521
|
+
spinner.text = theme.secondary.bold("Configuring API key...");
|
|
522
|
+
await this.configureApiKey(projectDir, options.apiKey);
|
|
523
|
+
}
|
|
524
|
+
spinner.succeed(theme.secondary.bold(`Project "${projectName}" created successfully!`));
|
|
525
|
+
this.queueAnalytics("cli.create.project_created", {
|
|
526
|
+
framework: agentFramework,
|
|
527
|
+
project_name: projectName,
|
|
528
|
+
has_api_key: !!options.apiKey,
|
|
529
|
+
duration_ms: Date.now() - this.startTime
|
|
530
|
+
});
|
|
531
|
+
this.log("\n" + theme.divider);
|
|
532
|
+
this.log(
|
|
533
|
+
"\n" + theme.secondary.bold(
|
|
534
|
+
`\u{1FA81}\u{1F91D}${FRAMEWORK_EMOJI[options.agentFramework]} All set!
|
|
535
|
+
|
|
536
|
+
Your project is ready with Copilot Cloud configured.`
|
|
537
|
+
)
|
|
538
|
+
);
|
|
539
|
+
this.log("\n" + theme.secondary("Next steps:"));
|
|
540
|
+
this.log(theme.secondary(` \u2022 ${theme.command(`cd ${projectName}`)}`));
|
|
541
|
+
this.log(theme.secondary(" \u2022 Follow the setup instructions in the README.md"));
|
|
542
|
+
this.log("\n" + theme.secondary("Documentation:"));
|
|
543
|
+
this.log(theme.secondary(" \u2022 ") + theme.command("https://docs.copilotkit.ai"));
|
|
544
|
+
this.log(theme.secondary(" \u2022 ") + theme.command(FRAMEWORK_DOCUMENTATION[options.agentFramework]));
|
|
545
|
+
this.log(theme.bottomPadding);
|
|
546
|
+
this.queueAnalytics("cli.create.completed", {
|
|
547
|
+
framework: agentFramework,
|
|
548
|
+
project_name: projectName,
|
|
549
|
+
cloud_setup_completed: !!cloudSetupInfo,
|
|
550
|
+
api_key_configured: !!options.apiKey,
|
|
551
|
+
duration_ms: Date.now() - this.startTime
|
|
552
|
+
});
|
|
553
|
+
await this.flushAnalytics();
|
|
554
|
+
} catch (error) {
|
|
555
|
+
spinner.fail(theme.error(`Failed to create project: ${error.message}`));
|
|
556
|
+
this.queueAnalytics("cli.create.failed", {
|
|
557
|
+
framework: agentFramework,
|
|
558
|
+
project_name: projectName,
|
|
559
|
+
error: error.message,
|
|
560
|
+
step: "project_creation",
|
|
561
|
+
duration_ms: Date.now() - this.startTime
|
|
562
|
+
});
|
|
563
|
+
await this.flushAnalytics();
|
|
564
|
+
this.exit(1);
|
|
565
|
+
}
|
|
566
|
+
} catch (error) {
|
|
567
|
+
this.queueAnalytics("cli.create.failed", {
|
|
568
|
+
error: error.message,
|
|
569
|
+
step: "initialization",
|
|
570
|
+
duration_ms: Date.now() - this.startTime
|
|
571
|
+
});
|
|
572
|
+
await this.flushAnalytics();
|
|
573
|
+
this.gracefulError(error.message);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
async promptProjectName() {
|
|
577
|
+
const { projectName } = await inquirer2.prompt([
|
|
578
|
+
{
|
|
579
|
+
type: "input",
|
|
580
|
+
name: "projectName",
|
|
581
|
+
message: theme.secondary("What is your project named?"),
|
|
582
|
+
validate: (input) => {
|
|
583
|
+
if (!input) return theme.error("Project name is required");
|
|
584
|
+
if (!/^[a-z0-9-]+$/.test(input)) {
|
|
585
|
+
return theme.error("Project name can only contain lowercase letters, numbers, and hyphens");
|
|
586
|
+
}
|
|
587
|
+
if (input.length > 30) {
|
|
588
|
+
return theme.error("Project name must be less than 30 characters");
|
|
589
|
+
}
|
|
590
|
+
return true;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
]);
|
|
594
|
+
return projectName;
|
|
595
|
+
}
|
|
596
|
+
async promptAgentFramework() {
|
|
597
|
+
const { framework } = await inquirer2.prompt([
|
|
598
|
+
{
|
|
599
|
+
type: "list",
|
|
600
|
+
name: "framework",
|
|
601
|
+
message: theme.secondary("Which agent framework would you like to use?"),
|
|
602
|
+
choices: [
|
|
603
|
+
{ name: `${FRAMEWORK_EMOJI["langgraph-py"]} LangGraph (Python)`, value: "langgraph-py" },
|
|
604
|
+
{ name: `${FRAMEWORK_EMOJI["langgraph-js"]} LangGraph (JavaScript)`, value: "langgraph-js" },
|
|
605
|
+
{ name: `${FRAMEWORK_EMOJI.mastra} Mastra`, value: "mastra" },
|
|
606
|
+
{ name: `${FRAMEWORK_EMOJI["pydantic-ai"]} Pydantic AI`, value: "pydantic-ai" },
|
|
607
|
+
{ name: `${FRAMEWORK_EMOJI.flows} CrewAI Flows`, value: "flows" },
|
|
608
|
+
{ name: `${FRAMEWORK_EMOJI.llamaindex} LlamaIndex`, value: "llamaindex" },
|
|
609
|
+
{ name: `${FRAMEWORK_EMOJI.agno} Agno`, value: "agno" },
|
|
610
|
+
{ name: `${FRAMEWORK_EMOJI.ag2} AG2`, value: "ag2" }
|
|
611
|
+
]
|
|
612
|
+
}
|
|
613
|
+
]);
|
|
614
|
+
return framework;
|
|
615
|
+
}
|
|
616
|
+
async downloadTemplate(projectDir, framework) {
|
|
617
|
+
const repo = TEMPLATE_REPOS[framework];
|
|
618
|
+
const url = `https://github.com/${repo}/archive/refs/heads/main.tar.gz`;
|
|
619
|
+
try {
|
|
620
|
+
const response = await fetch(url);
|
|
621
|
+
if (!response.ok) throw new Error(`Failed to download template: ${response.statusText}`);
|
|
622
|
+
const tempFile = path.join(projectDir, "template.tar.gz");
|
|
623
|
+
const fileStream = createWriteStream(tempFile);
|
|
624
|
+
if (!response.body) throw new Error("Failed to get response body");
|
|
625
|
+
await streamPipeline(response.body, fileStream);
|
|
626
|
+
await extract({
|
|
627
|
+
file: tempFile,
|
|
628
|
+
cwd: projectDir,
|
|
629
|
+
strip: 1
|
|
630
|
+
});
|
|
631
|
+
await fs.remove(tempFile);
|
|
632
|
+
} catch (error) {
|
|
633
|
+
throw new Error(`Failed to download template: ${error.message}`);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Queue an analytics event to be sent later (non-blocking)
|
|
638
|
+
*/
|
|
639
|
+
queueAnalytics(event, properties) {
|
|
640
|
+
this.analyticsQueue.push({ event, properties });
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Send all queued analytics events in fire-and-forget manner
|
|
644
|
+
*/
|
|
645
|
+
async flushAnalytics() {
|
|
646
|
+
if (!this.analytics || this.analyticsQueue.length === 0) {
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
const promises = this.analyticsQueue.map(
|
|
650
|
+
({ event, properties }) => this.analytics.track({ event, properties }).catch(() => {
|
|
651
|
+
})
|
|
652
|
+
);
|
|
653
|
+
Promise.all(promises).catch(() => {
|
|
654
|
+
});
|
|
655
|
+
if (this.analytics) {
|
|
656
|
+
this.analytics.shutdown().catch(() => {
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
async setupCloudApiKey(flags) {
|
|
661
|
+
const { cliToken, organization } = await this.authService.requireLogin(this, "cloud-features");
|
|
662
|
+
this.trpcClient = createTRPCClient(cliToken);
|
|
663
|
+
const availableProjects = await this.trpcClient.listOrgProjects.query({ orgId: organization.id });
|
|
664
|
+
let selectedProjectId;
|
|
665
|
+
if (flags.project) {
|
|
666
|
+
if (!availableProjects.some((project) => project.id === flags.project)) {
|
|
667
|
+
this.log(chalk3.red(`\u{1F4C1} Project with ID ${flags.project} not found`));
|
|
668
|
+
process.exit(1);
|
|
669
|
+
}
|
|
670
|
+
selectedProjectId = flags.project;
|
|
671
|
+
this.log(chalk3.green(`\u{1F4C1} Selected project ${selectedProjectId}`));
|
|
672
|
+
} else if (availableProjects.length === 1) {
|
|
673
|
+
selectedProjectId = availableProjects[0].id;
|
|
674
|
+
this.log(chalk3.green(`\u{1F4C1} Auto-selected project ${selectedProjectId}`));
|
|
675
|
+
} else {
|
|
676
|
+
const { projectId } = await inquirer2.prompt([
|
|
677
|
+
{
|
|
678
|
+
name: "projectId",
|
|
679
|
+
type: "list",
|
|
680
|
+
message: "\u{1F4C1} Choose a project:",
|
|
681
|
+
choices: availableProjects.map((project) => ({
|
|
682
|
+
value: project.id,
|
|
683
|
+
name: `${project.name} (ID: ${project.id})`
|
|
684
|
+
}))
|
|
685
|
+
}
|
|
686
|
+
]);
|
|
687
|
+
selectedProjectId = projectId;
|
|
688
|
+
}
|
|
689
|
+
const spinner = ora2({
|
|
690
|
+
text: "Retrieving your API key...",
|
|
691
|
+
color: "cyan"
|
|
692
|
+
}).start();
|
|
693
|
+
try {
|
|
694
|
+
const copilotCloudPublicApiKey = await this.trpcClient.getCopilotCloudPublicApiKey.query({
|
|
695
|
+
projectId: selectedProjectId
|
|
696
|
+
});
|
|
697
|
+
if (!copilotCloudPublicApiKey?.key) {
|
|
698
|
+
spinner.fail("Failed to retrieve API key");
|
|
699
|
+
throw new Error("No API key found for the selected project");
|
|
700
|
+
}
|
|
701
|
+
spinner.succeed("\u2705 API key retrieved successfully");
|
|
702
|
+
return {
|
|
703
|
+
cliToken,
|
|
704
|
+
organization,
|
|
705
|
+
selectedProjectId,
|
|
706
|
+
apiKey: copilotCloudPublicApiKey.key
|
|
707
|
+
};
|
|
708
|
+
} catch (error) {
|
|
709
|
+
spinner.fail("Failed to retrieve API key");
|
|
710
|
+
throw error;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
async configureApiKey(projectDir, apiKey) {
|
|
714
|
+
const envPath = path.join(projectDir, ".env.local");
|
|
715
|
+
const envExamplePath = path.join(projectDir, ".env.example");
|
|
716
|
+
try {
|
|
717
|
+
let envContent = "";
|
|
718
|
+
if (await fs.pathExists(envExamplePath)) {
|
|
719
|
+
envContent = await fs.readFile(envExamplePath, "utf8");
|
|
720
|
+
envContent = envContent.replace(/COPILOT_CLOUD_PUBLIC_API_KEY=.*/g, `COPILOT_CLOUD_PUBLIC_API_KEY=${apiKey}`);
|
|
721
|
+
} else {
|
|
722
|
+
envContent = `COPILOT_CLOUD_PUBLIC_API_KEY=${apiKey}
|
|
723
|
+
`;
|
|
724
|
+
}
|
|
725
|
+
await fs.writeFile(envPath, envContent);
|
|
726
|
+
} catch (error) {
|
|
727
|
+
console.warn("Warning: Could not configure API key in .env.local file");
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
|
|
329
732
|
// src/lib/init/types/questions.ts
|
|
330
733
|
import { z } from "zod";
|
|
331
|
-
import { Flags } from "@oclif/core";
|
|
734
|
+
import { Flags as Flags2 } from "@oclif/core";
|
|
332
735
|
|
|
333
736
|
// src/lib/init/utils.ts
|
|
334
737
|
var isLocalhost = (url) => {
|
|
@@ -437,24 +840,24 @@ var ConfigSchema = z.object({
|
|
|
437
840
|
}
|
|
438
841
|
);
|
|
439
842
|
var ConfigFlags = {
|
|
440
|
-
booth:
|
|
441
|
-
mode:
|
|
442
|
-
"copilotkit-version":
|
|
443
|
-
"use-copilot-cloud":
|
|
444
|
-
"langgraph-agent":
|
|
445
|
-
"crew-type":
|
|
446
|
-
"crew-name":
|
|
447
|
-
"crew-url":
|
|
448
|
-
"crew-bearer-token":
|
|
449
|
-
"langsmith-api-key":
|
|
450
|
-
"llm-token":
|
|
451
|
-
"setup-ide-docs":
|
|
452
|
-
"selected-ide":
|
|
843
|
+
booth: Flags2.boolean({ description: "Use CopilotKit in booth mode", default: false, char: "b" }),
|
|
844
|
+
mode: Flags2.string({ description: "How you will be interacting with AI", options: MODES, char: "m" }),
|
|
845
|
+
"copilotkit-version": Flags2.string({ description: "CopilotKit version to use (e.g. 1.7.0)" }),
|
|
846
|
+
"use-copilot-cloud": Flags2.string({ description: "Use Copilot Cloud for production-ready hosting", options: YES_NO }),
|
|
847
|
+
"langgraph-agent": Flags2.string({ description: "LangGraph agent template to use", options: LANGGRAPH_AGENTS }),
|
|
848
|
+
"crew-type": Flags2.string({ description: "CrewAI implementation type", options: CREW_TYPES }),
|
|
849
|
+
"crew-name": Flags2.string({ description: "Name for your CrewAI agent" }),
|
|
850
|
+
"crew-url": Flags2.string({ description: "URL endpoint for your CrewAI agent" }),
|
|
851
|
+
"crew-bearer-token": Flags2.string({ description: "Bearer token for CrewAI authentication" }),
|
|
852
|
+
"langsmith-api-key": Flags2.string({ description: "LangSmith API key for LangGraph observability" }),
|
|
853
|
+
"llm-token": Flags2.string({ description: "API key for your preferred LLM provider" }),
|
|
854
|
+
"setup-ide-docs": Flags2.string({ description: "Setup IDE documentation rules for AI assistance", options: YES_NO }),
|
|
855
|
+
"selected-ide": Flags2.string({
|
|
453
856
|
description: "IDE to configure with documentation rules",
|
|
454
857
|
options: ["cursor", "windsurf", "skip"]
|
|
455
858
|
}),
|
|
456
859
|
// NEW: A/B/C test flags
|
|
457
|
-
"deployment-choice":
|
|
860
|
+
"deployment-choice": Flags2.string({
|
|
458
861
|
description: "Choose between Copilot Cloud or Self-hosted deployment",
|
|
459
862
|
options: DEPLOYMENT_CHOICES
|
|
460
863
|
})
|
|
@@ -481,10 +884,10 @@ var templateMapping = {
|
|
|
481
884
|
};
|
|
482
885
|
|
|
483
886
|
// src/lib/init/ide-docs.ts
|
|
484
|
-
import
|
|
887
|
+
import path2 from "path";
|
|
485
888
|
import { existsSync } from "fs";
|
|
486
|
-
import * as
|
|
487
|
-
import
|
|
889
|
+
import * as fs2 from "fs/promises";
|
|
890
|
+
import chalk4 from "chalk";
|
|
488
891
|
var COPILOTKIT_DOC_RULE_TEMPLATE = `---
|
|
489
892
|
description: CopilotKit Documentation - Complete CopilotKit framework documentation for AI assistance
|
|
490
893
|
alwaysApply: false
|
|
@@ -522,7 +925,7 @@ var IDE_DOCS_CONFIGS = {
|
|
|
522
925
|
};
|
|
523
926
|
async function ensureDir(dirPath) {
|
|
524
927
|
try {
|
|
525
|
-
await
|
|
928
|
+
await fs2.mkdir(dirPath, { recursive: true });
|
|
526
929
|
} catch (error) {
|
|
527
930
|
if (!existsSync(dirPath)) {
|
|
528
931
|
throw error;
|
|
@@ -531,7 +934,7 @@ async function ensureDir(dirPath) {
|
|
|
531
934
|
}
|
|
532
935
|
async function pathExists(filePath) {
|
|
533
936
|
try {
|
|
534
|
-
await
|
|
937
|
+
await fs2.access(filePath);
|
|
535
938
|
return true;
|
|
536
939
|
} catch {
|
|
537
940
|
return false;
|
|
@@ -543,10 +946,10 @@ async function checkIDEInstallation(ide) {
|
|
|
543
946
|
let configPath;
|
|
544
947
|
switch (ide) {
|
|
545
948
|
case "cursor":
|
|
546
|
-
configPath =
|
|
949
|
+
configPath = path2.join(homeDir, ".cursor");
|
|
547
950
|
break;
|
|
548
951
|
case "windsurf":
|
|
549
|
-
configPath =
|
|
952
|
+
configPath = path2.join(homeDir, ".codeium", "windsurf");
|
|
550
953
|
break;
|
|
551
954
|
default:
|
|
552
955
|
return false;
|
|
@@ -568,30 +971,30 @@ async function detectInstalledIDEs() {
|
|
|
568
971
|
}
|
|
569
972
|
async function setupIDEDocs(ide, projectDir) {
|
|
570
973
|
const config = IDE_DOCS_CONFIGS[ide];
|
|
571
|
-
const rulesDir =
|
|
572
|
-
const ruleFilePath =
|
|
974
|
+
const rulesDir = path2.join(projectDir, config.rulesDir);
|
|
975
|
+
const ruleFilePath = path2.join(rulesDir, config.ruleFileName);
|
|
573
976
|
await ensureDir(rulesDir);
|
|
574
977
|
if (await pathExists(ruleFilePath)) {
|
|
575
|
-
console.log(
|
|
978
|
+
console.log(chalk4.yellow(`\u26A0\uFE0F CopilotKit documentation rule already exists for ${config.displayName}`));
|
|
576
979
|
return;
|
|
577
980
|
}
|
|
578
981
|
const ruleContent = config.createRuleContent();
|
|
579
|
-
await
|
|
982
|
+
await fs2.writeFile(ruleFilePath, ruleContent, "utf8");
|
|
580
983
|
}
|
|
581
984
|
function getIDEInstructions(ide) {
|
|
582
985
|
const config = IDE_DOCS_CONFIGS[ide];
|
|
583
986
|
const instructions = [
|
|
584
|
-
|
|
987
|
+
chalk4.cyan(`\u{1F4DA} CopilotKit documentation configured for ${config.displayName}!`),
|
|
585
988
|
"",
|
|
586
|
-
|
|
989
|
+
chalk4.bold("What this does:"),
|
|
587
990
|
" \u2022 Adds CopilotKit documentation context to your IDE AI assistant",
|
|
588
991
|
" \u2022 Provides accurate, up-to-date information about CopilotKit APIs",
|
|
589
992
|
" \u2022 Improves code suggestions and help responses",
|
|
590
993
|
"",
|
|
591
|
-
|
|
592
|
-
` \u2022 Rule file: ${
|
|
994
|
+
chalk4.bold("Location:"),
|
|
995
|
+
` \u2022 Rule file: ${chalk4.gray(path2.join(config.rulesDir, config.ruleFileName))}`,
|
|
593
996
|
"",
|
|
594
|
-
|
|
997
|
+
chalk4.bold("Usage:"),
|
|
595
998
|
" \u2022 Your IDE AI assistant now has access to CopilotKit documentation",
|
|
596
999
|
" \u2022 Ask questions about CopilotKit APIs, components, and patterns",
|
|
597
1000
|
" \u2022 The AI will reference official documentation for accurate answers"
|
|
@@ -599,7 +1002,7 @@ function getIDEInstructions(ide) {
|
|
|
599
1002
|
if (ide === "cursor") {
|
|
600
1003
|
instructions.push(
|
|
601
1004
|
"",
|
|
602
|
-
|
|
1005
|
+
chalk4.bold("Next steps for Cursor:"),
|
|
603
1006
|
" \u2022 Restart Cursor if currently open",
|
|
604
1007
|
" \u2022 The rule will be automatically available in your AI context",
|
|
605
1008
|
" \u2022 Start a new chat to use the documentation context"
|
|
@@ -607,7 +1010,7 @@ function getIDEInstructions(ide) {
|
|
|
607
1010
|
} else if (ide === "windsurf") {
|
|
608
1011
|
instructions.push(
|
|
609
1012
|
"",
|
|
610
|
-
|
|
1013
|
+
chalk4.bold("Next steps for Windsurf:"),
|
|
611
1014
|
" \u2022 Restart Windsurf if currently open",
|
|
612
1015
|
" \u2022 The rule will be automatically available in your AI context",
|
|
613
1016
|
" \u2022 Start a new chat to use the documentation context"
|
|
@@ -617,14 +1020,14 @@ function getIDEInstructions(ide) {
|
|
|
617
1020
|
}
|
|
618
1021
|
async function handleIDEDocsSetup(selectedIDE, projectDir, spinner) {
|
|
619
1022
|
try {
|
|
620
|
-
spinner.text =
|
|
1023
|
+
spinner.text = chalk4.cyan(`Setting up CopilotKit documentation for ${IDE_DOCS_CONFIGS[selectedIDE].displayName}...`);
|
|
621
1024
|
await setupIDEDocs(selectedIDE, projectDir);
|
|
622
|
-
spinner.succeed(
|
|
1025
|
+
spinner.succeed(chalk4.green(`CopilotKit documentation configured for ${IDE_DOCS_CONFIGS[selectedIDE].displayName}`));
|
|
623
1026
|
const instructions = getIDEInstructions(selectedIDE);
|
|
624
1027
|
console.log("\n" + instructions.join("\n"));
|
|
625
1028
|
} catch (error) {
|
|
626
1029
|
spinner.fail(
|
|
627
|
-
|
|
1030
|
+
chalk4.red(`Failed to setup IDE documentation: ${error instanceof Error ? error.message : "Unknown error"}`)
|
|
628
1031
|
);
|
|
629
1032
|
throw error;
|
|
630
1033
|
}
|
|
@@ -908,8 +1311,8 @@ async function scaffoldShadCN(flags, userAnswers) {
|
|
|
908
1311
|
}
|
|
909
1312
|
|
|
910
1313
|
// src/lib/init/scaffold/env.ts
|
|
911
|
-
import
|
|
912
|
-
import
|
|
1314
|
+
import path3 from "path";
|
|
1315
|
+
import fs3 from "fs";
|
|
913
1316
|
|
|
914
1317
|
// src/lib/init/scaffold/langgraph-assistants.ts
|
|
915
1318
|
async function getLangGraphAgents(url, langSmithApiKey) {
|
|
@@ -932,7 +1335,7 @@ async function getLangGraphAgents(url, langSmithApiKey) {
|
|
|
932
1335
|
}
|
|
933
1336
|
|
|
934
1337
|
// src/lib/init/scaffold/env.ts
|
|
935
|
-
import
|
|
1338
|
+
import inquirer3 from "inquirer";
|
|
936
1339
|
function needsCloudDeployment(userAnswers) {
|
|
937
1340
|
return userAnswers.deploymentChoice === "Copilot Cloud" || // Branch B choice
|
|
938
1341
|
userAnswers.useCopilotCloud === "Yes" || // Branch C choice
|
|
@@ -941,9 +1344,9 @@ function needsCloudDeployment(userAnswers) {
|
|
|
941
1344
|
}
|
|
942
1345
|
async function scaffoldEnv(flags, userAnswers) {
|
|
943
1346
|
try {
|
|
944
|
-
const envFile =
|
|
945
|
-
if (!
|
|
946
|
-
|
|
1347
|
+
const envFile = path3.join(process.cwd(), ".env");
|
|
1348
|
+
if (!fs3.existsSync(envFile)) {
|
|
1349
|
+
fs3.writeFileSync(envFile, "", "utf8");
|
|
947
1350
|
} else {
|
|
948
1351
|
}
|
|
949
1352
|
let newEnvValues = "";
|
|
@@ -990,7 +1393,7 @@ async function scaffoldEnv(flags, userAnswers) {
|
|
|
990
1393
|
);
|
|
991
1394
|
let langGraphAgent = "";
|
|
992
1395
|
if (langGraphAgents.length > 1) {
|
|
993
|
-
const { langGraphAgentChoice } = await
|
|
1396
|
+
const { langGraphAgentChoice } = await inquirer3.prompt([
|
|
994
1397
|
{
|
|
995
1398
|
type: "list",
|
|
996
1399
|
name: "langGraphAgentChoice",
|
|
@@ -1011,7 +1414,7 @@ async function scaffoldEnv(flags, userAnswers) {
|
|
|
1011
1414
|
`;
|
|
1012
1415
|
}
|
|
1013
1416
|
if (newEnvValues) {
|
|
1014
|
-
|
|
1417
|
+
fs3.appendFileSync(envFile, newEnvValues);
|
|
1015
1418
|
}
|
|
1016
1419
|
} catch (error) {
|
|
1017
1420
|
throw error;
|
|
@@ -1020,59 +1423,59 @@ async function scaffoldEnv(flags, userAnswers) {
|
|
|
1020
1423
|
|
|
1021
1424
|
// src/lib/init/scaffold/github.ts
|
|
1022
1425
|
import { execSync } from "child_process";
|
|
1023
|
-
import * as
|
|
1024
|
-
import * as
|
|
1426
|
+
import * as fs4 from "fs";
|
|
1427
|
+
import * as path4 from "path";
|
|
1025
1428
|
import * as os from "os";
|
|
1026
|
-
import
|
|
1429
|
+
import chalk5 from "chalk";
|
|
1027
1430
|
async function cloneGitHubSubdirectory(githubUrl, destinationPath, spinner) {
|
|
1028
1431
|
try {
|
|
1029
1432
|
const { owner, repo, branch, subdirectoryPath } = parseGitHubUrl(githubUrl);
|
|
1030
|
-
spinner.text =
|
|
1433
|
+
spinner.text = chalk5.cyan(`Cloning from ${owner}/${repo}...`);
|
|
1031
1434
|
return await sparseCheckout(owner, repo, branch, subdirectoryPath, destinationPath, spinner);
|
|
1032
1435
|
} catch (error) {
|
|
1033
|
-
spinner.text =
|
|
1436
|
+
spinner.text = chalk5.red(`Failed to clone from GitHub: ${error}`);
|
|
1034
1437
|
return false;
|
|
1035
1438
|
}
|
|
1036
1439
|
}
|
|
1037
1440
|
async function sparseCheckout(owner, repo, branch, subdirectoryPath, destinationPath, spinner) {
|
|
1038
|
-
const tempDir =
|
|
1441
|
+
const tempDir = fs4.mkdtempSync(path4.join(os.tmpdir(), "copilotkit-sparse-"));
|
|
1039
1442
|
try {
|
|
1040
|
-
spinner.text =
|
|
1443
|
+
spinner.text = chalk5.cyan("Creating temporary workspace...");
|
|
1041
1444
|
execSync("git init", { cwd: tempDir, stdio: "pipe" });
|
|
1042
|
-
spinner.text =
|
|
1445
|
+
spinner.text = chalk5.cyan("Connecting to repository...");
|
|
1043
1446
|
execSync(`git remote add origin https://github.com/${owner}/${repo}.git`, { cwd: tempDir, stdio: "pipe" });
|
|
1044
1447
|
execSync("git config core.sparseCheckout true", { cwd: tempDir, stdio: "pipe" });
|
|
1045
|
-
|
|
1046
|
-
spinner.text =
|
|
1448
|
+
fs4.writeFileSync(path4.join(tempDir, ".git/info/sparse-checkout"), subdirectoryPath);
|
|
1449
|
+
spinner.text = chalk5.cyan("Downloading agent files...");
|
|
1047
1450
|
execSync(`git pull origin ${branch} --depth=1`, { cwd: tempDir, stdio: "pipe" });
|
|
1048
|
-
const sourcePath =
|
|
1049
|
-
if (!
|
|
1451
|
+
const sourcePath = path4.join(tempDir, subdirectoryPath);
|
|
1452
|
+
if (!fs4.existsSync(sourcePath)) {
|
|
1050
1453
|
throw new Error(`Subdirectory '${subdirectoryPath}' not found in the repository.`);
|
|
1051
1454
|
}
|
|
1052
|
-
|
|
1053
|
-
spinner.text =
|
|
1455
|
+
fs4.mkdirSync(destinationPath, { recursive: true });
|
|
1456
|
+
spinner.text = chalk5.cyan("Installing agent files...");
|
|
1054
1457
|
await copyDirectoryAsync(sourcePath, destinationPath);
|
|
1055
1458
|
return true;
|
|
1056
1459
|
} finally {
|
|
1057
1460
|
try {
|
|
1058
|
-
|
|
1461
|
+
fs4.rmSync(tempDir, { recursive: true, force: true });
|
|
1059
1462
|
} catch (error) {
|
|
1060
1463
|
console.warn(`Failed to clean up temporary directory: ${error}`);
|
|
1061
1464
|
}
|
|
1062
1465
|
}
|
|
1063
1466
|
}
|
|
1064
1467
|
async function copyDirectoryAsync(source, destination) {
|
|
1065
|
-
if (!
|
|
1066
|
-
|
|
1468
|
+
if (!fs4.existsSync(destination)) {
|
|
1469
|
+
fs4.mkdirSync(destination, { recursive: true });
|
|
1067
1470
|
}
|
|
1068
|
-
const entries =
|
|
1471
|
+
const entries = fs4.readdirSync(source, { withFileTypes: true });
|
|
1069
1472
|
for (const entry of entries) {
|
|
1070
|
-
const srcPath =
|
|
1071
|
-
const destPath =
|
|
1473
|
+
const srcPath = path4.join(source, entry.name);
|
|
1474
|
+
const destPath = path4.join(destination, entry.name);
|
|
1072
1475
|
if (entry.isDirectory()) {
|
|
1073
1476
|
await copyDirectoryAsync(srcPath, destPath);
|
|
1074
1477
|
} else {
|
|
1075
|
-
|
|
1478
|
+
fs4.copyFileSync(srcPath, destPath);
|
|
1076
1479
|
}
|
|
1077
1480
|
if (entries.length > 10) {
|
|
1078
1481
|
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
@@ -1101,20 +1504,20 @@ function parseGitHubUrl(githubUrl) {
|
|
|
1101
1504
|
|
|
1102
1505
|
// src/lib/init/scaffold/packages.ts
|
|
1103
1506
|
import spawn2 from "cross-spawn";
|
|
1104
|
-
import
|
|
1105
|
-
import
|
|
1507
|
+
import chalk6 from "chalk";
|
|
1508
|
+
import ora3 from "ora";
|
|
1106
1509
|
|
|
1107
1510
|
// src/lib/init/scaffold/agent.ts
|
|
1108
|
-
import
|
|
1109
|
-
import
|
|
1110
|
-
import
|
|
1111
|
-
import
|
|
1511
|
+
import ora4 from "ora";
|
|
1512
|
+
import chalk7 from "chalk";
|
|
1513
|
+
import path5 from "path";
|
|
1514
|
+
import fs5 from "fs";
|
|
1112
1515
|
async function scaffoldAgent(userAnswers) {
|
|
1113
1516
|
if (userAnswers.mode === "CrewAI" || userAnswers.mode === "LangGraph" && !userAnswers.langGraphAgent || userAnswers.mode === "Standard" || userAnswers.mode === "MCP") {
|
|
1114
1517
|
return;
|
|
1115
1518
|
}
|
|
1116
|
-
const spinner =
|
|
1117
|
-
text:
|
|
1519
|
+
const spinner = ora4({
|
|
1520
|
+
text: chalk7.cyan("Setting up AI agent..."),
|
|
1118
1521
|
color: "cyan"
|
|
1119
1522
|
}).start();
|
|
1120
1523
|
let template = "";
|
|
@@ -1128,13 +1531,13 @@ async function scaffoldAgent(userAnswers) {
|
|
|
1128
1531
|
break;
|
|
1129
1532
|
}
|
|
1130
1533
|
if (!template) {
|
|
1131
|
-
spinner.fail(
|
|
1534
|
+
spinner.fail(chalk7.red("Failed to determine agent template"));
|
|
1132
1535
|
throw new Error("Failed to determine agent template");
|
|
1133
1536
|
}
|
|
1134
|
-
const agentDir =
|
|
1537
|
+
const agentDir = path5.join(process.cwd(), "agent");
|
|
1135
1538
|
try {
|
|
1136
1539
|
await cloneGitHubSubdirectory(template, agentDir, spinner);
|
|
1137
|
-
spinner.text =
|
|
1540
|
+
spinner.text = chalk7.cyan("Creating agent environment variables...");
|
|
1138
1541
|
let envContent = "";
|
|
1139
1542
|
if (userAnswers.llmToken) {
|
|
1140
1543
|
envContent += `OPENAI_API_KEY=${userAnswers.llmToken}
|
|
@@ -1145,26 +1548,26 @@ async function scaffoldAgent(userAnswers) {
|
|
|
1145
1548
|
`;
|
|
1146
1549
|
}
|
|
1147
1550
|
if (envContent) {
|
|
1148
|
-
const agentEnvFile =
|
|
1149
|
-
|
|
1150
|
-
spinner.text =
|
|
1551
|
+
const agentEnvFile = path5.join(agentDir, ".env");
|
|
1552
|
+
fs5.writeFileSync(agentEnvFile, envContent, "utf8");
|
|
1553
|
+
spinner.text = chalk7.cyan("Added API keys to agent .env file");
|
|
1151
1554
|
}
|
|
1152
1555
|
if (userAnswers.mode === "LangGraph" && userAnswers.langSmithApiKey) {
|
|
1153
1556
|
envContent += `LANGSMITH_API_KEY=${userAnswers.langSmithApiKey}
|
|
1154
1557
|
`;
|
|
1155
1558
|
}
|
|
1156
1559
|
if (envContent) {
|
|
1157
|
-
const agentEnvFile =
|
|
1158
|
-
|
|
1159
|
-
spinner.text =
|
|
1560
|
+
const agentEnvFile = path5.join(agentDir, ".env");
|
|
1561
|
+
fs5.writeFileSync(agentEnvFile, envContent, "utf8");
|
|
1562
|
+
spinner.text = chalk7.cyan("Added API keys to agent .env file");
|
|
1160
1563
|
}
|
|
1161
1564
|
if (envContent) {
|
|
1162
|
-
const agentEnvFile =
|
|
1163
|
-
|
|
1164
|
-
spinner.text =
|
|
1565
|
+
const agentEnvFile = path5.join(agentDir, ".env");
|
|
1566
|
+
fs5.writeFileSync(agentEnvFile, envContent, "utf8");
|
|
1567
|
+
spinner.text = chalk7.cyan("Added API keys to agent .env file");
|
|
1165
1568
|
}
|
|
1166
1569
|
} catch (error) {
|
|
1167
|
-
spinner.fail(
|
|
1570
|
+
spinner.fail(chalk7.red("Failed to clone agent template"));
|
|
1168
1571
|
throw error;
|
|
1169
1572
|
}
|
|
1170
1573
|
spinner.succeed(`${userAnswers.mode} agent cloned successfully`);
|
|
@@ -1184,29 +1587,29 @@ var AgentTemplates = {
|
|
|
1184
1587
|
};
|
|
1185
1588
|
|
|
1186
1589
|
// src/lib/init/scaffold/crew-inputs.ts
|
|
1187
|
-
import * as
|
|
1188
|
-
import
|
|
1189
|
-
import * as
|
|
1590
|
+
import * as fs6 from "fs/promises";
|
|
1591
|
+
import ora5 from "ora";
|
|
1592
|
+
import * as path6 from "path";
|
|
1190
1593
|
async function addCrewInputs(url, token) {
|
|
1191
1594
|
try {
|
|
1192
|
-
const spinner =
|
|
1595
|
+
const spinner = ora5("Analyzing crew inputs...").start();
|
|
1193
1596
|
const inputs = await getCrewInputs(url, token);
|
|
1194
1597
|
spinner.text = "Adding inputs to app/copilotkit/page.tsx...";
|
|
1195
|
-
let filePath =
|
|
1598
|
+
let filePath = path6.join(process.cwd(), "app", "copilotkit", "page.tsx");
|
|
1196
1599
|
try {
|
|
1197
|
-
await
|
|
1600
|
+
await fs6.access(filePath);
|
|
1198
1601
|
} catch {
|
|
1199
|
-
filePath =
|
|
1602
|
+
filePath = path6.join(process.cwd(), "src", "app", "copilotkit", "page.tsx");
|
|
1200
1603
|
}
|
|
1201
1604
|
try {
|
|
1202
|
-
await
|
|
1605
|
+
await fs6.access(filePath);
|
|
1203
1606
|
} catch {
|
|
1204
1607
|
throw new Error("app/copilotkit/page.tsx and src/app/copilotkit/page.tsx not found");
|
|
1205
1608
|
}
|
|
1206
|
-
let fileContent = await
|
|
1609
|
+
let fileContent = await fs6.readFile(filePath, "utf8");
|
|
1207
1610
|
const inputsString = JSON.stringify(inputs);
|
|
1208
1611
|
fileContent = fileContent.replace(/\[["']YOUR_INPUTS_HERE["']\]/g, inputsString);
|
|
1209
|
-
await
|
|
1612
|
+
await fs6.writeFile(filePath, fileContent, "utf8");
|
|
1210
1613
|
spinner.succeed("Successfully added crew inputs to app/copilotkit/page.tsx");
|
|
1211
1614
|
} catch (error) {
|
|
1212
1615
|
console.error("Error updating crew inputs:", error);
|
|
@@ -1227,8 +1630,8 @@ async function getCrewInputs(url, token) {
|
|
|
1227
1630
|
}
|
|
1228
1631
|
|
|
1229
1632
|
// src/commands/init.ts
|
|
1230
|
-
import
|
|
1231
|
-
import
|
|
1633
|
+
import chalk8 from "chalk";
|
|
1634
|
+
import ora6 from "ora";
|
|
1232
1635
|
var CloudInit = class _CloudInit extends BaseCommand {
|
|
1233
1636
|
constructor(argv, config, authService = new AuthService()) {
|
|
1234
1637
|
super(argv, config);
|
|
@@ -1238,24 +1641,31 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1238
1641
|
analytics = null;
|
|
1239
1642
|
startTime = Date.now();
|
|
1240
1643
|
analyticsQueue = [];
|
|
1241
|
-
static description = "Set up CopilotKit in your Next.js project";
|
|
1242
|
-
static examples = ["<%= config.bin %> init"];
|
|
1644
|
+
static description = "Set up CopilotKit in your Next.js project, or create a new project if none exists";
|
|
1645
|
+
static examples = ["<%= config.bin %> init", "<%= config.bin %> init --dir ./my-app"];
|
|
1243
1646
|
static flags = {
|
|
1244
1647
|
...BaseCommand.flags,
|
|
1245
1648
|
...ConfigFlags,
|
|
1246
|
-
runtimeUrl:
|
|
1247
|
-
project:
|
|
1248
|
-
dir:
|
|
1649
|
+
runtimeUrl: Flags3.string({ description: "runtime URL" }),
|
|
1650
|
+
project: Flags3.string({ description: "project ID (can be found in the Copilot Cloud dashboard)" }),
|
|
1651
|
+
dir: Flags3.string({ description: "directory of the Next.js project", default: "." })
|
|
1249
1652
|
};
|
|
1250
1653
|
async run() {
|
|
1251
1654
|
const { flags } = await this.parse(_CloudInit);
|
|
1252
1655
|
try {
|
|
1253
1656
|
this.analytics = new AnalyticsService();
|
|
1254
|
-
this.
|
|
1657
|
+
const nextJsAppExists = this.isNextJsProject(flags);
|
|
1658
|
+
if (!nextJsAppExists) {
|
|
1659
|
+
this.log(chalk8.gray("Running copilotkit create to set up a new project...\n"));
|
|
1660
|
+
const createCommand = new Create(this.argv, this.config, this.authService);
|
|
1661
|
+
await createCommand.run();
|
|
1662
|
+
return;
|
|
1663
|
+
}
|
|
1664
|
+
this.log(chalk8.magenta("\n\u{1FA81} Welcome to CopilotKit"));
|
|
1255
1665
|
if (flags.booth) {
|
|
1256
|
-
this.log(
|
|
1666
|
+
this.log(chalk8.gray("Thanks for giving CopilotKit a try! Now, let's try to impress you \u{1F4AA}\n"));
|
|
1257
1667
|
} else {
|
|
1258
|
-
this.log(
|
|
1668
|
+
this.log(chalk8.gray("Let's power up your Next.js project with AI capabilities\n"));
|
|
1259
1669
|
}
|
|
1260
1670
|
const projectValidated = this.validateProjectCompatibility(flags);
|
|
1261
1671
|
this.queueAnalytics("cli.init.started", {
|
|
@@ -1277,19 +1687,19 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1277
1687
|
deployment_choice: userAnswers.deploymentChoice
|
|
1278
1688
|
});
|
|
1279
1689
|
if (userAnswers.mode === "Mastra") {
|
|
1280
|
-
this.log(
|
|
1690
|
+
this.log(chalk8.magenta(`
|
|
1281
1691
|
\u{1F517} Please go to https://docs.copilotkit.ai/mastra/quickstart to get started.`));
|
|
1282
1692
|
process.exit(0);
|
|
1283
1693
|
} else if (userAnswers.mode === "AG2") {
|
|
1284
|
-
this.log(
|
|
1694
|
+
this.log(chalk8.magenta(`
|
|
1285
1695
|
\u{1F517} Please go to https://docs.copilotkit.ai/ag2/quickstart to get started.`));
|
|
1286
1696
|
process.exit(0);
|
|
1287
1697
|
} else if (userAnswers.mode === "Agno") {
|
|
1288
|
-
this.log(
|
|
1698
|
+
this.log(chalk8.magenta(`
|
|
1289
1699
|
\u{1F517} Please go to https://docs.copilotkit.ai/agno/quickstart to get started.`));
|
|
1290
1700
|
process.exit(0);
|
|
1291
1701
|
} else if (userAnswers.mode === "LlamaIndex") {
|
|
1292
|
-
this.log(
|
|
1702
|
+
this.log(chalk8.magenta(`
|
|
1293
1703
|
\u{1F517} Please go to https://docs.copilotkit.ai/llamaindex/quickstart to get started.`));
|
|
1294
1704
|
process.exit(0);
|
|
1295
1705
|
}
|
|
@@ -1320,7 +1730,7 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1320
1730
|
if (userAnswers.crewUrl && userAnswers.crewBearerToken)
|
|
1321
1731
|
await addCrewInputs(userAnswers.crewUrl, userAnswers.crewBearerToken);
|
|
1322
1732
|
if (userAnswers.setupIDEDocs === "Yes" && userAnswers.selectedIDE !== "skip") {
|
|
1323
|
-
const ideDocsSpinner =
|
|
1733
|
+
const ideDocsSpinner = ora6({
|
|
1324
1734
|
text: "Setting up CopilotKit IDE documentation...",
|
|
1325
1735
|
color: "cyan"
|
|
1326
1736
|
}).start();
|
|
@@ -1342,12 +1752,12 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1342
1752
|
await this.flushAnalytics();
|
|
1343
1753
|
if (flags.booth) {
|
|
1344
1754
|
this.log("\n-----\n");
|
|
1345
|
-
this.log(
|
|
1346
|
-
this.log(
|
|
1347
|
-
this.log(` - Start the Next.js app: ${
|
|
1348
|
-
this.log(` - Navigate to ${
|
|
1755
|
+
this.log(chalk8.magenta("\u{1F389} Your CopilotKit setup is complete! \u{1F389}\n"));
|
|
1756
|
+
this.log(chalk8.bold("\n\u{1F680} Next steps:"));
|
|
1757
|
+
this.log(` - Start the Next.js app: ${chalk8.gray("$")} ${chalk8.cyan("npm run dev")}`);
|
|
1758
|
+
this.log(` - Navigate to ${chalk8.blue("http://localhost:3000/copilotkit")}`);
|
|
1349
1759
|
this.log(` - Talk to your agent.`);
|
|
1350
|
-
this.log(
|
|
1760
|
+
this.log(chalk8.magenta("\nThanks for giving CopilotKit a try! \u{1FA81}\n"));
|
|
1351
1761
|
} else {
|
|
1352
1762
|
this.finalSummary(userAnswers, cloudSetupInfo?.selectedProjectId);
|
|
1353
1763
|
}
|
|
@@ -1404,7 +1814,7 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1404
1814
|
}
|
|
1405
1815
|
}
|
|
1406
1816
|
async getBoothAnswers() {
|
|
1407
|
-
const url = await
|
|
1817
|
+
const url = await inquirer4.prompt({
|
|
1408
1818
|
type: "input",
|
|
1409
1819
|
message: "\u{1F99C}\u{1F517} What is the LangGraph's agent URL?",
|
|
1410
1820
|
name: "agentURL",
|
|
@@ -1479,15 +1889,15 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1479
1889
|
};
|
|
1480
1890
|
}
|
|
1481
1891
|
}).filter((q) => q !== null);
|
|
1482
|
-
const promptAnswers = await
|
|
1892
|
+
const promptAnswers = await inquirer4.prompt(inquirerQuestions);
|
|
1483
1893
|
const answers = {
|
|
1484
1894
|
...initialAnswers,
|
|
1485
1895
|
...promptAnswers,
|
|
1486
1896
|
...earlyApiKey && { copilotCloudPublicApiKey: earlyApiKey }
|
|
1487
1897
|
};
|
|
1488
1898
|
if (abcBranch === "B" && !cloudSetupInfo) {
|
|
1489
|
-
this.log(
|
|
1490
|
-
this.log(
|
|
1899
|
+
this.log(chalk8.cyan("\n\u{1F511} Now you will get an API key"));
|
|
1900
|
+
this.log(chalk8.gray("Setting up your cloud account and retrieving your API key...\n"));
|
|
1491
1901
|
try {
|
|
1492
1902
|
const tempConfig = { ...answers, signupForCopilotCloud: "Yes" };
|
|
1493
1903
|
const cloudSignupResult = await this.setupApiKey(flags, tempConfig);
|
|
@@ -1518,8 +1928,8 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1518
1928
|
}
|
|
1519
1929
|
}
|
|
1520
1930
|
if (abcBranch === "A" && !cloudSetupInfo) {
|
|
1521
|
-
this.log(
|
|
1522
|
-
this.log(
|
|
1931
|
+
this.log(chalk8.cyan("\n\u{1F511} Now get your API key"));
|
|
1932
|
+
this.log(chalk8.gray("Setting up your cloud account and retrieving your API key...\n"));
|
|
1523
1933
|
try {
|
|
1524
1934
|
const tempConfig = { ...answers, signupForCopilotCloud: "Yes" };
|
|
1525
1935
|
const cloudSignupResult = await this.setupApiKey(flags, tempConfig);
|
|
@@ -1553,24 +1963,24 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1553
1963
|
this.log(
|
|
1554
1964
|
"\nCurrently the CLI only supports scaffolding LangGraph Platform agents. Use our quickstart guide to get started:\n"
|
|
1555
1965
|
);
|
|
1556
|
-
this.log(
|
|
1966
|
+
this.log(chalk8.blue("https://docs.copilotkit.ai/coagents/quickstart/langgraph"));
|
|
1557
1967
|
process.exit(0);
|
|
1558
1968
|
}
|
|
1559
1969
|
try {
|
|
1560
|
-
const spinner =
|
|
1970
|
+
const spinner = ora6({ text: "Validating configuration...", color: "green" }).start();
|
|
1561
1971
|
const validatedConfig = ConfigSchema.parse(answers);
|
|
1562
1972
|
spinner.succeed(`\u{1F50D} Configuration validated successfully`);
|
|
1563
1973
|
return { config: validatedConfig, cloudSetupInfo };
|
|
1564
1974
|
} catch (error) {
|
|
1565
|
-
const spinner =
|
|
1975
|
+
const spinner = ora6({ text: "Validation failed...", color: "red" }).start();
|
|
1566
1976
|
if (error.errors) {
|
|
1567
1977
|
const formattedErrors = error.errors.map((err) => `- ${err.path.join(".")}: ${err.message}`).join("\n");
|
|
1568
|
-
spinner.fail(
|
|
1569
|
-
console.error(
|
|
1978
|
+
spinner.fail(chalk8.red("Configuration validation failed:"));
|
|
1979
|
+
console.error(chalk8.red(formattedErrors));
|
|
1570
1980
|
process.exit(1);
|
|
1571
1981
|
}
|
|
1572
|
-
spinner.fail(
|
|
1573
|
-
console.error(
|
|
1982
|
+
spinner.fail(chalk8.red("Unexpected validation error:"));
|
|
1983
|
+
console.error(chalk8.red(error.message || "Unknown error"));
|
|
1574
1984
|
process.exit(1);
|
|
1575
1985
|
}
|
|
1576
1986
|
}
|
|
@@ -1581,13 +1991,13 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1581
1991
|
let selectedProjectId;
|
|
1582
1992
|
if (flags.project) {
|
|
1583
1993
|
if (!availableProjects.some((project) => project.id === flags.project)) {
|
|
1584
|
-
this.log(
|
|
1994
|
+
this.log(chalk8.red(`\u{1F4C1} Project with ID ${flags.project} not found`));
|
|
1585
1995
|
process.exit(1);
|
|
1586
1996
|
}
|
|
1587
1997
|
selectedProjectId = flags.project;
|
|
1588
|
-
this.log(
|
|
1998
|
+
this.log(chalk8.green(`\u{1F4C1} Selected project ${selectedProjectId}`));
|
|
1589
1999
|
} else {
|
|
1590
|
-
const { projectId } = await
|
|
2000
|
+
const { projectId } = await inquirer4.prompt([
|
|
1591
2001
|
{
|
|
1592
2002
|
name: "projectId",
|
|
1593
2003
|
type: "list",
|
|
@@ -1617,12 +2027,12 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1617
2027
|
const updatedConfig = ConfigSchema.parse(sanitizedConfig);
|
|
1618
2028
|
Object.assign(userAnswers, updatedConfig);
|
|
1619
2029
|
} catch (error) {
|
|
1620
|
-
this.log(
|
|
2030
|
+
this.log(chalk8.red(`Failed to update configuration with Copilot Cloud API key: ${error.message}`));
|
|
1621
2031
|
}
|
|
1622
2032
|
if (userAnswers.crewUrl && userAnswers.crewName && userAnswers.crewBearerToken) {
|
|
1623
2033
|
const isFlow = userAnswers.crewType === "Flows";
|
|
1624
|
-
const crewSpinner =
|
|
1625
|
-
text:
|
|
2034
|
+
const crewSpinner = ora6({
|
|
2035
|
+
text: chalk8(`\u{1F465} Adding CrewAI ${isFlow ? "Flow" : "Crew"} to Copilot Cloud...`),
|
|
1626
2036
|
color: "cyan"
|
|
1627
2037
|
}).start();
|
|
1628
2038
|
try {
|
|
@@ -1638,22 +2048,22 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1638
2048
|
crewApiBearerToken: userAnswers.crewBearerToken
|
|
1639
2049
|
}
|
|
1640
2050
|
});
|
|
1641
|
-
crewSpinner.succeed(
|
|
2051
|
+
crewSpinner.succeed(chalk8(`\u{1F465} CrewAI ${isFlow ? "Flow" : "Crew"} added to Copilot Cloud`));
|
|
1642
2052
|
} catch (error) {
|
|
1643
|
-
crewSpinner.fail(
|
|
2053
|
+
crewSpinner.fail(chalk8(`\u{1F465} Failed to add CrewAI ${isFlow ? "Flow" : "Crew"} to Copilot Cloud`));
|
|
1644
2054
|
console.error(error);
|
|
1645
2055
|
process.exit(1);
|
|
1646
2056
|
}
|
|
1647
2057
|
}
|
|
1648
2058
|
if (userAnswers.mode === "LangGraph" && userAnswers.useCopilotCloud === "Yes" && userAnswers.alreadyDeployed === "Yes") {
|
|
1649
|
-
const langGraphSpinner =
|
|
1650
|
-
text:
|
|
2059
|
+
const langGraphSpinner = ora6({
|
|
2060
|
+
text: chalk8("\u{1F99C}\u{1F517} Adding LangGraph to Copilot Cloud..."),
|
|
1651
2061
|
color: "cyan"
|
|
1652
2062
|
}).start();
|
|
1653
2063
|
if (userAnswers.langGraphPlatform === "Yes" && userAnswers.langGraphPlatformUrl) {
|
|
1654
2064
|
try {
|
|
1655
2065
|
if (!userAnswers.langSmithApiKey) {
|
|
1656
|
-
langGraphSpinner.fail(
|
|
2066
|
+
langGraphSpinner.fail(chalk8("\u{1F99C}\u{1F517} LangSmith API key not found. Please provide a valid LangSmith API key."));
|
|
1657
2067
|
process.exit(1);
|
|
1658
2068
|
}
|
|
1659
2069
|
await this.trpcClient.createLGCRemoteEndpoint.mutate({
|
|
@@ -1666,9 +2076,9 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1666
2076
|
agents: []
|
|
1667
2077
|
}
|
|
1668
2078
|
});
|
|
1669
|
-
langGraphSpinner.succeed(
|
|
2079
|
+
langGraphSpinner.succeed(chalk8("\u{1F99C}\u{1F517} LangGraph Cloud remote endpoint created"));
|
|
1670
2080
|
} catch (error) {
|
|
1671
|
-
langGraphSpinner.fail(
|
|
2081
|
+
langGraphSpinner.fail(chalk8("\u{1F99C}\u{1F517} Failed to create LangGraph Cloud remote endpoint. Please try again."));
|
|
1672
2082
|
process.exit(1);
|
|
1673
2083
|
}
|
|
1674
2084
|
} else if (userAnswers.langGraphRemoteEndpointURL) {
|
|
@@ -1682,32 +2092,32 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1682
2092
|
// Already sanitized
|
|
1683
2093
|
}
|
|
1684
2094
|
});
|
|
1685
|
-
langGraphSpinner.succeed(
|
|
2095
|
+
langGraphSpinner.succeed(chalk8("\u{1F99C}\u{1F517} LangGraph remote endpoint created"));
|
|
1686
2096
|
} catch (error) {
|
|
1687
|
-
langGraphSpinner.fail(
|
|
2097
|
+
langGraphSpinner.fail(chalk8("\u{1F99C}\u{1F517} Failed to create LangGraph remote endpoint. Please try again."));
|
|
1688
2098
|
process.exit(1);
|
|
1689
2099
|
}
|
|
1690
2100
|
}
|
|
1691
2101
|
}
|
|
1692
2102
|
}
|
|
1693
2103
|
async setupApiKey(flags, userAnswers) {
|
|
1694
|
-
this.log(
|
|
2104
|
+
this.log(chalk8.cyan("\n\u{1F511} Setting up your API key...\n"));
|
|
1695
2105
|
const { cliToken, organization } = await this.authService.requireLogin(this, "cloud-features");
|
|
1696
2106
|
this.trpcClient = createTRPCClient(cliToken);
|
|
1697
2107
|
const availableProjects = await this.trpcClient.listOrgProjects.query({ orgId: organization.id });
|
|
1698
2108
|
let selectedProjectId;
|
|
1699
2109
|
if (flags.project) {
|
|
1700
2110
|
if (!availableProjects.some((project) => project.id === flags.project)) {
|
|
1701
|
-
this.log(
|
|
2111
|
+
this.log(chalk8.red(`\u{1F4C1} Project with ID ${flags.project} not found`));
|
|
1702
2112
|
process.exit(1);
|
|
1703
2113
|
}
|
|
1704
2114
|
selectedProjectId = flags.project;
|
|
1705
|
-
this.log(
|
|
2115
|
+
this.log(chalk8.green(`\u{1F4C1} Selected project ${selectedProjectId}`));
|
|
1706
2116
|
} else if (availableProjects.length === 1) {
|
|
1707
2117
|
selectedProjectId = availableProjects[0].id;
|
|
1708
|
-
this.log(
|
|
2118
|
+
this.log(chalk8.green(`\u{1F4C1} Auto-selected project ${selectedProjectId}`));
|
|
1709
2119
|
} else {
|
|
1710
|
-
const { projectId } = await
|
|
2120
|
+
const { projectId } = await inquirer4.prompt([
|
|
1711
2121
|
{
|
|
1712
2122
|
name: "projectId",
|
|
1713
2123
|
type: "list",
|
|
@@ -1722,7 +2132,7 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1722
2132
|
}
|
|
1723
2133
|
let apiKey;
|
|
1724
2134
|
if (selectedProjectId) {
|
|
1725
|
-
const spinner =
|
|
2135
|
+
const spinner = ora6({
|
|
1726
2136
|
text: "Retrieving your API key...",
|
|
1727
2137
|
color: "cyan"
|
|
1728
2138
|
}).start();
|
|
@@ -1737,7 +2147,7 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1737
2147
|
console.error(error);
|
|
1738
2148
|
}
|
|
1739
2149
|
}
|
|
1740
|
-
this.log(
|
|
2150
|
+
this.log(chalk8.green("\u2705 API key setup complete!\n"));
|
|
1741
2151
|
return { cliToken, organization, selectedProjectId, apiKey };
|
|
1742
2152
|
}
|
|
1743
2153
|
async completeCloudDeploymentSetup(flags, userAnswers, cloudSetupInfo) {
|
|
@@ -1747,8 +2157,8 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1747
2157
|
const selectedProjectId = cloudSetupInfo.selectedProjectId;
|
|
1748
2158
|
if (userAnswers.crewUrl && userAnswers.crewName && userAnswers.crewBearerToken) {
|
|
1749
2159
|
const isFlow = userAnswers.crewType === "Flows";
|
|
1750
|
-
const crewSpinner =
|
|
1751
|
-
text:
|
|
2160
|
+
const crewSpinner = ora6({
|
|
2161
|
+
text: chalk8(`\u{1F465} Adding CrewAI ${isFlow ? "Flow" : "Crew"} to Copilot Cloud...`),
|
|
1752
2162
|
color: "cyan"
|
|
1753
2163
|
}).start();
|
|
1754
2164
|
try {
|
|
@@ -1763,22 +2173,22 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1763
2173
|
crewApiBearerToken: userAnswers.crewBearerToken
|
|
1764
2174
|
}
|
|
1765
2175
|
});
|
|
1766
|
-
crewSpinner.succeed(
|
|
2176
|
+
crewSpinner.succeed(chalk8(`\u{1F465} CrewAI ${isFlow ? "Flow" : "Crew"} added to Copilot Cloud`));
|
|
1767
2177
|
} catch (error) {
|
|
1768
|
-
crewSpinner.fail(
|
|
2178
|
+
crewSpinner.fail(chalk8(`\u{1F465} Failed to add CrewAI ${isFlow ? "Flow" : "Crew"} to Copilot Cloud`));
|
|
1769
2179
|
console.error(error);
|
|
1770
2180
|
process.exit(1);
|
|
1771
2181
|
}
|
|
1772
2182
|
}
|
|
1773
2183
|
if (userAnswers.mode === "LangGraph" && userAnswers.useCopilotCloud === "Yes" && userAnswers.alreadyDeployed === "Yes") {
|
|
1774
|
-
const langGraphSpinner =
|
|
1775
|
-
text:
|
|
2184
|
+
const langGraphSpinner = ora6({
|
|
2185
|
+
text: chalk8("\u{1F99C}\u{1F517} Adding LangGraph to Copilot Cloud..."),
|
|
1776
2186
|
color: "cyan"
|
|
1777
2187
|
}).start();
|
|
1778
2188
|
if (userAnswers.langGraphPlatform === "Yes" && userAnswers.langGraphPlatformUrl) {
|
|
1779
2189
|
try {
|
|
1780
2190
|
if (!userAnswers.langSmithApiKey) {
|
|
1781
|
-
langGraphSpinner.fail(
|
|
2191
|
+
langGraphSpinner.fail(chalk8("\u{1F99C}\u{1F517} LangSmith API key not found. Please provide a valid LangSmith API key."));
|
|
1782
2192
|
process.exit(1);
|
|
1783
2193
|
}
|
|
1784
2194
|
await this.trpcClient.createLGCRemoteEndpoint.mutate({
|
|
@@ -1790,9 +2200,9 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1790
2200
|
agents: []
|
|
1791
2201
|
}
|
|
1792
2202
|
});
|
|
1793
|
-
langGraphSpinner.succeed(
|
|
2203
|
+
langGraphSpinner.succeed(chalk8("\u{1F99C}\u{1F517} LangGraph Cloud remote endpoint created"));
|
|
1794
2204
|
} catch (error) {
|
|
1795
|
-
langGraphSpinner.fail(
|
|
2205
|
+
langGraphSpinner.fail(chalk8("\u{1F99C}\u{1F517} Failed to create LangGraph Cloud remote endpoint. Please try again."));
|
|
1796
2206
|
process.exit(1);
|
|
1797
2207
|
}
|
|
1798
2208
|
} else if (userAnswers.langGraphRemoteEndpointURL) {
|
|
@@ -1805,41 +2215,57 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1805
2215
|
url: userAnswers.langGraphRemoteEndpointURL
|
|
1806
2216
|
}
|
|
1807
2217
|
});
|
|
1808
|
-
langGraphSpinner.succeed(
|
|
2218
|
+
langGraphSpinner.succeed(chalk8("\u{1F99C}\u{1F517} LangGraph remote endpoint created"));
|
|
1809
2219
|
} catch (error) {
|
|
1810
|
-
langGraphSpinner.fail(
|
|
2220
|
+
langGraphSpinner.fail(chalk8("\u{1F99C}\u{1F517} Failed to create LangGraph remote endpoint. Please try again."));
|
|
1811
2221
|
process.exit(1);
|
|
1812
2222
|
}
|
|
1813
2223
|
}
|
|
1814
2224
|
}
|
|
1815
2225
|
}
|
|
1816
|
-
|
|
1817
|
-
const spinner = ora5("Checking Next.js project compatibility...").start();
|
|
2226
|
+
isNextJsProject(flags) {
|
|
1818
2227
|
try {
|
|
1819
|
-
const projectPath =
|
|
1820
|
-
if (!
|
|
1821
|
-
|
|
1822
|
-
throw new Error(`Please provide a valid Next.js project directory.`);
|
|
2228
|
+
const projectPath = path7.resolve(process.cwd(), flags.dir);
|
|
2229
|
+
if (!fs7.existsSync(projectPath)) {
|
|
2230
|
+
return false;
|
|
1823
2231
|
}
|
|
1824
|
-
const packageJsonPath =
|
|
1825
|
-
if (!
|
|
1826
|
-
|
|
1827
|
-
throw new Error(`Please provide a valid Next.js project with a package.json file.`);
|
|
2232
|
+
const packageJsonPath = path7.join(projectPath, "package.json");
|
|
2233
|
+
if (!fs7.existsSync(packageJsonPath)) {
|
|
2234
|
+
return false;
|
|
1828
2235
|
}
|
|
1829
|
-
const packageJson = JSON.parse(
|
|
1830
|
-
|
|
2236
|
+
const packageJson = JSON.parse(fs7.readFileSync(packageJsonPath, "utf8"));
|
|
2237
|
+
return !!(packageJson.dependencies?.next || packageJson.devDependencies?.next);
|
|
2238
|
+
} catch {
|
|
2239
|
+
return false;
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
validateProjectCompatibility(flags) {
|
|
2243
|
+
const spinner = ora6("Checking Next.js project compatibility...").start();
|
|
2244
|
+
try {
|
|
2245
|
+
if (!this.isNextJsProject(flags)) {
|
|
2246
|
+
const projectPath2 = path7.resolve(process.cwd(), flags.dir);
|
|
2247
|
+
if (!fs7.existsSync(projectPath2)) {
|
|
2248
|
+
spinner.fail(`Directory ${flags.dir} does not exist`);
|
|
2249
|
+
throw new Error(`Please provide a valid Next.js project directory.`);
|
|
2250
|
+
}
|
|
2251
|
+
const packageJsonPath = path7.join(projectPath2, "package.json");
|
|
2252
|
+
if (!fs7.existsSync(packageJsonPath)) {
|
|
2253
|
+
spinner.fail(`No package.json found in ${projectPath2}`);
|
|
2254
|
+
throw new Error(`Please provide a valid Next.js project with a package.json file.`);
|
|
2255
|
+
}
|
|
1831
2256
|
spinner.fail(`Not a Next.js project`);
|
|
1832
2257
|
throw new Error(
|
|
1833
|
-
`Directory ${
|
|
2258
|
+
`Directory ${projectPath2} does not appear to be a Next.js project. Make sure it has next in dependencies.`
|
|
1834
2259
|
);
|
|
1835
2260
|
}
|
|
2261
|
+
const projectPath = path7.resolve(process.cwd(), flags.dir);
|
|
1836
2262
|
spinner.succeed(`\u{1F53C} Valid Next.js project detected at ${projectPath}`);
|
|
1837
2263
|
return true;
|
|
1838
2264
|
} catch (error) {
|
|
1839
2265
|
if (!spinner.isSpinning) {
|
|
1840
|
-
this.log(
|
|
2266
|
+
this.log(chalk8.red(error.message));
|
|
1841
2267
|
} else {
|
|
1842
|
-
spinner.fail(
|
|
2268
|
+
spinner.fail(chalk8.red(error.message));
|
|
1843
2269
|
}
|
|
1844
2270
|
process.exit(1);
|
|
1845
2271
|
}
|
|
@@ -1849,9 +2275,9 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1849
2275
|
let agentSetupMessage = "";
|
|
1850
2276
|
if (userAnswers.mode === "CrewAI") {
|
|
1851
2277
|
if (userAnswers.crewType === "Crews") {
|
|
1852
|
-
agentSetupMessage = `Using your Crew from ${
|
|
2278
|
+
agentSetupMessage = `Using your Crew from ${chalk8.cyan(userAnswers.crewUrl || "the provided URL")}.`;
|
|
1853
2279
|
} else if (userAnswers.crewType === "Flows") {
|
|
1854
|
-
agentSetupMessage = `We've scaffolded a ${
|
|
2280
|
+
agentSetupMessage = `We've scaffolded a ${chalk8.cyan("CrewAI Flow")} agent in the ${chalk8.cyan("./agent")} directory.`;
|
|
1855
2281
|
agentDevInstructions = "poetry lock && poetry install && poetry run demo";
|
|
1856
2282
|
}
|
|
1857
2283
|
}
|
|
@@ -1859,11 +2285,11 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1859
2285
|
case "LangGraph":
|
|
1860
2286
|
switch (userAnswers.langGraphAgent) {
|
|
1861
2287
|
case "Python Starter":
|
|
1862
|
-
agentSetupMessage = `We've scaffolded a ${
|
|
2288
|
+
agentSetupMessage = `We've scaffolded a ${chalk8.cyan(userAnswers.langGraphAgent || "LangGraph")} agent in the ${chalk8.cyan("./agent")} directory.`;
|
|
1863
2289
|
agentDevInstructions = "poetry lock && poetry install && poetry run demo";
|
|
1864
2290
|
break;
|
|
1865
2291
|
case "TypeScript Starter":
|
|
1866
|
-
agentSetupMessage = `We've scaffolded a ${
|
|
2292
|
+
agentSetupMessage = `We've scaffolded a ${chalk8.cyan(userAnswers.langGraphAgent || "LangGraph")} agent in the ${chalk8.cyan("./agent")} directory.`;
|
|
1867
2293
|
agentDevInstructions = "npm install && npm run dev";
|
|
1868
2294
|
break;
|
|
1869
2295
|
default:
|
|
@@ -1873,18 +2299,18 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1873
2299
|
case "CrewAI":
|
|
1874
2300
|
switch (userAnswers.crewType) {
|
|
1875
2301
|
case "Crews":
|
|
1876
|
-
agentSetupMessage = `Using your Crew from ${
|
|
2302
|
+
agentSetupMessage = `Using your Crew from ${chalk8.cyan(userAnswers.crewUrl || "the provided URL")}.`;
|
|
1877
2303
|
break;
|
|
1878
2304
|
case "Flows":
|
|
1879
|
-
agentSetupMessage = `We've scaffolded a ${
|
|
2305
|
+
agentSetupMessage = `We've scaffolded a ${chalk8.cyan("CrewAI Flow")} agent in the ${chalk8.cyan("./agent")} directory.`;
|
|
1880
2306
|
break;
|
|
1881
2307
|
}
|
|
1882
2308
|
break;
|
|
1883
2309
|
default:
|
|
1884
2310
|
}
|
|
1885
2311
|
this.log("\n-----\n");
|
|
1886
|
-
this.log(
|
|
1887
|
-
this.log(
|
|
2312
|
+
this.log(chalk8.magenta("\u{1F389} Your CopilotKit setup is complete! \u{1F389}\n"));
|
|
2313
|
+
this.log(chalk8.bold(`\u{1F4CB} Recap`));
|
|
1888
2314
|
this.log(` - CopilotKit has been added to your Next.js app.`);
|
|
1889
2315
|
if (agentSetupMessage) this.log(` - ${agentSetupMessage}`);
|
|
1890
2316
|
const isCloudDeployment = userAnswers.deploymentChoice === "Copilot Cloud" || // Branch B choice
|
|
@@ -1897,23 +2323,23 @@ var CloudInit = class _CloudInit extends BaseCommand {
|
|
|
1897
2323
|
} else if (isSelfHosted) {
|
|
1898
2324
|
this.log(` - \u{1F3E0} Configured for self-hosted deployment.`);
|
|
1899
2325
|
}
|
|
1900
|
-
this.log(
|
|
1901
|
-
this.log(` - Start your Next.js app: ${
|
|
2326
|
+
this.log(chalk8.bold("\n\u{1F680} Next steps:"));
|
|
2327
|
+
this.log(` - Start your Next.js app: ${chalk8.gray("$")} ${chalk8.cyan("npm run dev")}`);
|
|
1902
2328
|
if (agentDevInstructions) {
|
|
1903
|
-
this.log(` - Start your agent: ${
|
|
2329
|
+
this.log(` - Start your agent: ${chalk8.gray("$")} ${chalk8.cyan(`cd agent && ${agentDevInstructions}`)}`);
|
|
1904
2330
|
if (isCloudDeployment) {
|
|
1905
2331
|
this.log(
|
|
1906
|
-
` - Create local tunnel for your agent: ${
|
|
2332
|
+
` - Create local tunnel for your agent: ${chalk8.gray("$")} ${chalk8.cyan(`npx copilotkit@latest dev --port <value>${projectId ? ` --project ${projectId}` : " [--project <value>]"}`)}`
|
|
1907
2333
|
);
|
|
1908
2334
|
}
|
|
1909
2335
|
}
|
|
1910
|
-
this.log(` - Navigate to ${
|
|
2336
|
+
this.log(` - Navigate to ${chalk8.blue("http://localhost:3000/copilotkit")}`);
|
|
1911
2337
|
this.log(` - Talk to your agent.`);
|
|
1912
2338
|
if (userAnswers.setupIDEDocs === "Yes" && userAnswers.selectedIDE !== "skip") {
|
|
1913
2339
|
this.log(` - Your IDE now has CopilotKit documentation context for better AI assistance.`);
|
|
1914
2340
|
}
|
|
1915
|
-
this.log(` - Read the docs: ${
|
|
1916
|
-
this.log(
|
|
2341
|
+
this.log(` - Read the docs: ${chalk8.blue("https://docs.copilotkit.ai")}`);
|
|
2342
|
+
this.log(chalk8.magenta("\nEnjoy building with CopilotKit \u{1FA81}\n"));
|
|
1917
2343
|
}
|
|
1918
2344
|
};
|
|
1919
2345
|
export {
|