copilotkit 0.0.58 → 0.0.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/dist/commands/base-command.js +9 -6
  3. package/dist/commands/base-command.js.map +1 -1
  4. package/dist/commands/create.d.ts +1 -1
  5. package/dist/commands/create.js +230 -59
  6. package/dist/commands/create.js.map +1 -1
  7. package/dist/commands/dev.js +94 -35
  8. package/dist/commands/dev.js.map +1 -1
  9. package/dist/commands/init.d.ts +0 -20
  10. package/dist/commands/init.js +239 -209
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/commands/login.js +44 -20
  13. package/dist/commands/login.js.map +1 -1
  14. package/dist/commands/logout.js +44 -20
  15. package/dist/commands/logout.js.map +1 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/lib/init/ide-docs.d.ts +1 -1
  18. package/dist/lib/init/ide-docs.js +19 -5
  19. package/dist/lib/init/ide-docs.js.map +1 -1
  20. package/dist/lib/init/index.js +171 -67
  21. package/dist/lib/init/index.js.map +1 -1
  22. package/dist/lib/init/questions.d.ts +1 -1
  23. package/dist/lib/init/questions.js +77 -18
  24. package/dist/lib/init/questions.js.map +1 -1
  25. package/dist/lib/init/scaffold/agent.js +30 -23
  26. package/dist/lib/init/scaffold/agent.js.map +1 -1
  27. package/dist/lib/init/scaffold/crew-inputs.js +17 -4
  28. package/dist/lib/init/scaffold/crew-inputs.js.map +1 -1
  29. package/dist/lib/init/scaffold/env.js +14 -11
  30. package/dist/lib/init/scaffold/env.js.map +1 -1
  31. package/dist/lib/init/scaffold/github.js +27 -6
  32. package/dist/lib/init/scaffold/github.js.map +1 -1
  33. package/dist/lib/init/scaffold/index.js +152 -62
  34. package/dist/lib/init/scaffold/index.js.map +1 -1
  35. package/dist/lib/init/scaffold/langgraph-assistants.js +14 -11
  36. package/dist/lib/init/scaffold/langgraph-assistants.js.map +1 -1
  37. package/dist/lib/init/scaffold/packages.js +3 -1
  38. package/dist/lib/init/scaffold/packages.js.map +1 -1
  39. package/dist/lib/init/scaffold/shadcn.js +88 -23
  40. package/dist/lib/init/scaffold/shadcn.js.map +1 -1
  41. package/dist/lib/init/types/index.js +77 -18
  42. package/dist/lib/init/types/index.js.map +1 -1
  43. package/dist/lib/init/types/questions.d.ts +19 -19
  44. package/dist/lib/init/types/questions.js +73 -17
  45. package/dist/lib/init/types/questions.js.map +1 -1
  46. package/dist/lib/init/types/templates.d.ts +2 -2
  47. package/dist/lib/init/types/templates.js +4 -1
  48. package/dist/lib/init/types/templates.js.map +1 -1
  49. package/dist/lib/init/utils.js.map +1 -1
  50. package/dist/services/analytics.service.d.ts +1 -1
  51. package/dist/services/analytics.service.js +4 -1
  52. package/dist/services/analytics.service.js.map +1 -1
  53. package/dist/services/auth.service.d.ts +1 -1
  54. package/dist/services/auth.service.js +35 -14
  55. package/dist/services/auth.service.js.map +1 -1
  56. package/dist/services/events.d.ts +33 -33
  57. package/dist/services/tunnel.service.js.map +1 -1
  58. package/dist/utils/detect-endpoint-type.utils.d.ts +1 -1
  59. package/dist/utils/detect-endpoint-type.utils.js +11 -4
  60. package/dist/utils/detect-endpoint-type.utils.js.map +1 -1
  61. package/dist/utils/trpc.js.map +1 -1
  62. package/dist/utils/version.d.ts +1 -1
  63. package/dist/utils/version.js +1 -1
  64. package/dist/utils/version.js.map +1 -1
  65. package/oclif.manifest.json +4 -162
  66. package/package.json +8 -4
@@ -1,12 +1,9 @@
1
- // src/commands/init.ts
2
- import { Flags as Flags3 } from "@oclif/core";
3
-
4
1
  // src/commands/base-command.ts
5
2
  import { Command } from "@oclif/core";
6
3
  import Sentry, { consoleIntegration } from "@sentry/node";
7
4
 
8
5
  // src/utils/version.ts
9
- var LIB_VERSION = "0.0.58";
6
+ var LIB_VERSION = "0.0.59";
10
7
 
11
8
  // src/utils/trpc.ts
12
9
  import { createTRPCClient as trpcClient, httpBatchLink } from "@trpc/client";
@@ -47,11 +44,14 @@ var BaseCommand = class extends Command {
47
44
  async run() {
48
45
  }
49
46
  async checkCLIVersion() {
50
- const response = await fetch(`${COPILOT_CLOUD_BASE_URL}/api/healthz`);
51
- const data = await response.json();
52
- const cloudVersion = data.cliVersion;
53
- if (!cloudVersion || cloudVersion === LIB_VERSION) {
54
- return;
47
+ try {
48
+ const response = await fetch(`${COPILOT_CLOUD_BASE_URL}/api/healthz`);
49
+ const data = await response.json();
50
+ const cloudVersion = data.cliVersion;
51
+ if (!cloudVersion || cloudVersion === LIB_VERSION) {
52
+ return;
53
+ }
54
+ } catch {
55
55
  }
56
56
  }
57
57
  async gracefulError(message) {
@@ -63,41 +63,153 @@ var BaseCommand = class extends Command {
63
63
  // src/commands/create.ts
64
64
  import { Flags, Args } from "@oclif/core";
65
65
  import inquirer from "inquirer";
66
- import chalk2 from "chalk";
67
- import fs from "fs-extra";
68
- import path from "path";
66
+ import chalk3 from "chalk";
67
+ import fs2 from "fs-extra";
68
+ import path2 from "path";
69
69
  import { promisify } from "util";
70
70
  import { pipeline } from "stream";
71
71
  import { createWriteStream } from "fs";
72
72
  import { extract } from "tar";
73
73
  import ora from "ora";
74
+
75
+ // src/lib/init/scaffold/github.ts
76
+ import { execSync } from "child_process";
77
+ import * as fs from "fs";
78
+ import * as path from "path";
79
+ import * as os from "os";
80
+ import chalk2 from "chalk";
81
+ async function cloneGitHubSubdirectory(githubUrl, destinationPath, spinner) {
82
+ try {
83
+ const { owner, repo, branch, subdirectoryPath } = parseGitHubUrl(githubUrl);
84
+ spinner.text = chalk2.cyan(`Cloning from ${owner}/${repo}...`);
85
+ return await sparseCheckout(
86
+ owner,
87
+ repo,
88
+ branch,
89
+ subdirectoryPath,
90
+ destinationPath,
91
+ spinner
92
+ );
93
+ } catch (error) {
94
+ spinner.text = chalk2.red(`Failed to clone from GitHub: ${error}`);
95
+ return false;
96
+ }
97
+ }
98
+ async function sparseCheckout(owner, repo, branch, subdirectoryPath, destinationPath, spinner) {
99
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "copilotkit-sparse-"));
100
+ try {
101
+ spinner.text = chalk2.cyan("Creating temporary workspace...");
102
+ execSync("git init", { cwd: tempDir, stdio: "pipe" });
103
+ spinner.text = chalk2.cyan("Connecting to repository...");
104
+ execSync(`git remote add origin https://github.com/${owner}/${repo}.git`, {
105
+ cwd: tempDir,
106
+ stdio: "pipe"
107
+ });
108
+ execSync("git config core.sparseCheckout true", {
109
+ cwd: tempDir,
110
+ stdio: "pipe"
111
+ });
112
+ fs.writeFileSync(
113
+ path.join(tempDir, ".git/info/sparse-checkout"),
114
+ subdirectoryPath
115
+ );
116
+ spinner.text = chalk2.cyan("Downloading agent files...");
117
+ execSync(`git pull origin ${branch} --depth=1`, {
118
+ cwd: tempDir,
119
+ stdio: "pipe"
120
+ });
121
+ const sourcePath = path.join(tempDir, subdirectoryPath);
122
+ if (!fs.existsSync(sourcePath)) {
123
+ throw new Error(
124
+ `Subdirectory '${subdirectoryPath}' not found in the repository.`
125
+ );
126
+ }
127
+ fs.mkdirSync(destinationPath, { recursive: true });
128
+ spinner.text = chalk2.cyan("Installing agent files...");
129
+ await copyDirectoryAsync(sourcePath, destinationPath);
130
+ return true;
131
+ } finally {
132
+ try {
133
+ fs.rmSync(tempDir, { recursive: true, force: true });
134
+ } catch (error) {
135
+ console.warn(`Failed to clean up temporary directory: ${error}`);
136
+ }
137
+ }
138
+ }
139
+ async function copyDirectoryAsync(source, destination) {
140
+ if (!fs.existsSync(destination)) {
141
+ fs.mkdirSync(destination, { recursive: true });
142
+ }
143
+ const entries = fs.readdirSync(source, { withFileTypes: true });
144
+ for (const entry of entries) {
145
+ const srcPath = path.join(source, entry.name);
146
+ const destPath = path.join(destination, entry.name);
147
+ if (entry.isDirectory()) {
148
+ await copyDirectoryAsync(srcPath, destPath);
149
+ } else {
150
+ fs.copyFileSync(srcPath, destPath);
151
+ }
152
+ if (entries.length > 10) {
153
+ await new Promise((resolve) => setTimeout(resolve, 1));
154
+ }
155
+ }
156
+ }
157
+ function parseGitHubUrl(githubUrl) {
158
+ const url = new URL(githubUrl);
159
+ if (url.hostname !== "github.com") {
160
+ throw new Error("Only GitHub URLs are supported");
161
+ }
162
+ const pathParts = url.pathname.split("/").filter(Boolean);
163
+ if (pathParts.length < 2) {
164
+ throw new Error("Invalid GitHub URL format");
165
+ }
166
+ const owner = pathParts[0];
167
+ const repo = pathParts[1];
168
+ let branch = "main";
169
+ let subdirectoryPath = "";
170
+ if (pathParts.length > 3 && (pathParts[2] === "tree" || pathParts[2] === "blob")) {
171
+ branch = pathParts[3];
172
+ subdirectoryPath = pathParts.slice(4).join("/");
173
+ }
174
+ return { owner, repo, branch, subdirectoryPath };
175
+ }
176
+ function isValidGitHubUrl(url) {
177
+ try {
178
+ const parsedUrl = new URL(url);
179
+ return parsedUrl.hostname === "github.com" && parsedUrl.pathname.split("/").filter(Boolean).length >= 2;
180
+ } catch {
181
+ return false;
182
+ }
183
+ }
184
+
185
+ // src/commands/create.ts
74
186
  var streamPipeline = promisify(pipeline);
75
187
  var theme = {
76
- primary: chalk2.magenta,
77
- secondary: chalk2.gray,
78
- tertiary: chalk2.gray,
79
- error: chalk2.red,
80
- command: chalk2.blue,
81
- success: chalk2.green,
82
- warning: chalk2.yellow,
83
- 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"),
188
+ primary: chalk3.magenta,
189
+ secondary: chalk3.gray,
190
+ tertiary: chalk3.gray,
191
+ error: chalk3.red,
192
+ command: chalk3.blue,
193
+ success: chalk3.green,
194
+ warning: chalk3.yellow,
195
+ 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"),
84
196
  bottomPadding: ""
85
197
  };
86
198
  var TEMPLATE_REPOS = {
87
- "langgraph-py": "copilotkit/with-langgraph-python",
88
- "langgraph-js": "copilotkit/with-langgraph-js",
89
- mastra: "copilotkit/with-mastra",
90
- flows: "copilotkit/with-crewai-flows",
91
- llamaindex: "copilotkit/with-llamaindex",
92
- agno: "copilotkit/with-agno",
93
- "pydantic-ai": "copilotkit/with-pydantic-ai",
199
+ "langgraph-py": "https://github.com/CopilotKit/CopilotKit/tree/main/examples/integrations/langgraph-python",
200
+ "langgraph-js": "https://github.com/CopilotKit/CopilotKit/tree/main/examples/integrations/langgraph-js",
201
+ mastra: "https://github.com/CopilotKit/CopilotKit/tree/main/examples/integrations/mastra",
202
+ flows: "https://github.com/CopilotKit/CopilotKit/tree/main/examples/integrations/crewai-flows",
203
+ llamaindex: "https://github.com/CopilotKit/CopilotKit/tree/main/examples/integrations/llamaindex",
204
+ agno: "https://github.com/CopilotKit/CopilotKit/tree/main/examples/integrations/agno",
205
+ "pydantic-ai": "https://github.com/CopilotKit/CopilotKit/tree/main/examples/integrations/pydantic-ai",
94
206
  ag2: "ag2ai/ag2-copilotkit-starter",
95
- adk: "copilotkit/with-adk",
96
- "aws-strands-py": "copilotkit/with-strands-python",
97
- a2a: "copilotkit/with-a2a-middleware",
98
- "microsoft-agent-framework-dotnet": "copilotkit/with-microsoft-agent-framework-dotnet",
99
- "microsoft-agent-framework-py": "copilotkit/with-microsoft-agent-framework-python",
100
- "mcp-apps": "copilotkit/with-mcp-apps"
207
+ adk: "https://github.com/CopilotKit/CopilotKit/tree/main/examples/integrations/adk",
208
+ "aws-strands-py": "https://github.com/CopilotKit/CopilotKit/tree/main/examples/integrations/strands-python",
209
+ a2a: "https://github.com/CopilotKit/CopilotKit/tree/main/examples/integrations/a2a-middleware",
210
+ "microsoft-agent-framework-dotnet": "https://github.com/CopilotKit/CopilotKit/tree/main/examples/integrations/ms-agent-framework-dotnet",
211
+ "microsoft-agent-framework-py": "https://github.com/CopilotKit/CopilotKit/tree/main/examples/integrations/ms-agent-framework-python",
212
+ "mcp-apps": "https://github.com/CopilotKit/CopilotKit/tree/main/examples/integrations/mcp-apps"
101
213
  };
102
214
  var FRAMEWORK_DOCUMENTATION = {
103
215
  "langgraph-py": "https://langchain-ai.github.io/langgraph/concepts/why-langgraph",
@@ -193,30 +305,42 @@ var Create = class _Create extends BaseCommand {
193
305
  this.log(theme.primary(KITE));
194
306
  this.log(theme.primary("~ Welcome to CopilotKit! ~\n"));
195
307
  this.log(theme.divider);
196
- if ((!flags.name || flags.projectName) && !flags.framework) {
197
- this.log("\n" + theme.secondary("Just a few questions to get started!\n"));
308
+ if (!flags.name && !args.projectName && !flags.framework) {
309
+ this.log(
310
+ "\n" + theme.secondary("Just a few questions to get started!\n")
311
+ );
198
312
  }
199
313
  }
200
314
  const projectNameInput = flags.name || args.projectName || await this.promptProjectName();
201
315
  const projectName = projectNameInput.trim();
202
316
  const usingCurrentDir = projectName === "." || projectName === "./";
203
317
  const agentFramework = flags.framework || await this.promptAgentFramework();
204
- const projectDir = usingCurrentDir ? process.cwd() : path.resolve(process.cwd(), projectName);
318
+ const projectDir = usingCurrentDir ? process.cwd() : path2.resolve(process.cwd(), projectName);
205
319
  if (usingCurrentDir) {
206
320
  const allowedEntries = /* @__PURE__ */ new Set([".git", ".gitignore", ".DS_Store"]);
207
- const existingEntries = await fs.readdir(projectDir);
208
- const blockingEntries = existingEntries.filter((entry) => !allowedEntries.has(entry));
321
+ const existingEntries = await fs2.readdir(projectDir);
322
+ const blockingEntries = existingEntries.filter(
323
+ (entry) => !allowedEntries.has(entry)
324
+ );
209
325
  if (blockingEntries.length > 0) {
210
326
  this.log(theme.error("\nCurrent directory is not empty."));
211
- this.log(theme.secondary("\nPlease run create in an empty directory or specify a new project name."));
327
+ this.log(
328
+ theme.secondary(
329
+ "\nPlease run create in an empty directory or specify a new project name."
330
+ )
331
+ );
212
332
  this.exit(1);
213
333
  }
214
- } else if (await fs.pathExists(projectDir)) {
334
+ } else if (await fs2.pathExists(projectDir)) {
215
335
  this.log(theme.error(`
216
336
  Directory "${projectName}" already exists.`));
217
337
  this.log(theme.secondary("\nYou can:"));
218
338
  this.log(theme.secondary(" 1. Choose a different project name"));
219
- this.log(theme.secondary(" 2. Remove the existing directory manually if you want to use this name\n"));
339
+ this.log(
340
+ theme.secondary(
341
+ " 2. Remove the existing directory manually if you want to use this name\n"
342
+ )
343
+ );
220
344
  this.exit(1);
221
345
  }
222
346
  const options = {
@@ -229,11 +353,13 @@ Directory "${projectName}" already exists.`));
229
353
  spinner: "dots"
230
354
  }).start();
231
355
  try {
232
- await fs.ensureDir(projectDir);
356
+ await fs2.ensureDir(projectDir);
233
357
  spinner.text = theme.secondary.bold("Downloading template...");
234
- await this.downloadTemplate(projectDir, options.agentFramework);
358
+ await this.downloadTemplate(projectDir, options.agentFramework, spinner);
235
359
  const displayName = usingCurrentDir ? "current directory" : `"${projectName}"`;
236
- spinner.succeed(theme.secondary.bold(`Project ${displayName} created successfully!`));
360
+ spinner.succeed(
361
+ theme.secondary.bold(`Project ${displayName} created successfully!`)
362
+ );
237
363
  } catch (error) {
238
364
  spinner.fail(theme.error(`Failed to create project: ${error.message}`));
239
365
  this.exit(1);
@@ -248,14 +374,24 @@ Your project is ready to explore CopilotKit locally.`
248
374
  );
249
375
  this.log("\n" + theme.secondary("Next steps:"));
250
376
  if (usingCurrentDir) {
251
- this.log(theme.secondary(" \u2022 You are already inside your new project directory"));
377
+ this.log(
378
+ theme.secondary(
379
+ " \u2022 You are already inside your new project directory"
380
+ )
381
+ );
252
382
  } else {
253
383
  this.log(theme.secondary(` \u2022 ${theme.command(`cd ${projectName}`)}`));
254
384
  }
255
- this.log(theme.secondary(" \u2022 Follow the setup instructions in the README.md"));
385
+ this.log(
386
+ theme.secondary(" \u2022 Follow the setup instructions in the README.md")
387
+ );
256
388
  this.log("\n" + theme.secondary("Documentation:"));
257
- this.log(theme.secondary(" \u2022 ") + theme.command("https://docs.copilotkit.ai"));
258
- this.log(theme.secondary(" \u2022 ") + theme.command(FRAMEWORK_DOCUMENTATION[options.agentFramework]));
389
+ this.log(
390
+ theme.secondary(" \u2022 ") + theme.command("https://docs.copilotkit.ai")
391
+ );
392
+ this.log(
393
+ theme.secondary(" \u2022 ") + theme.command(FRAMEWORK_DOCUMENTATION[options.agentFramework])
394
+ );
259
395
  this.log(theme.bottomPadding);
260
396
  }
261
397
  async promptProjectName() {
@@ -267,7 +403,9 @@ Your project is ready to explore CopilotKit locally.`
267
403
  validate: (input) => {
268
404
  if (!input) return theme.error("Project name is required");
269
405
  if (!/^[a-z0-9-]+$/.test(input)) {
270
- return theme.error("Project name can only contain lowercase letters, numbers, and hyphens");
406
+ return theme.error(
407
+ "Project name can only contain lowercase letters, numbers, and hyphens"
408
+ );
271
409
  }
272
410
  if (input.length > 30) {
273
411
  return theme.error("Project name must be less than 30 characters");
@@ -283,13 +421,27 @@ Your project is ready to explore CopilotKit locally.`
283
421
  {
284
422
  type: "list",
285
423
  name: "framework",
286
- message: theme.secondary("Which agent framework would you like to use?"),
424
+ message: theme.secondary(
425
+ "Which agent framework would you like to use?"
426
+ ),
287
427
  choices: [
288
- { name: `${FRAMEWORK_EMOJI["langgraph-py"]} LangGraph (Python)`, value: "langgraph-py" },
289
- { name: `${FRAMEWORK_EMOJI["langgraph-js"]} LangGraph (JavaScript)`, value: "langgraph-js" },
428
+ {
429
+ name: `${FRAMEWORK_EMOJI["langgraph-py"]} LangGraph (Python)`,
430
+ value: "langgraph-py"
431
+ },
432
+ {
433
+ name: `${FRAMEWORK_EMOJI["langgraph-js"]} LangGraph (JavaScript)`,
434
+ value: "langgraph-js"
435
+ },
290
436
  { name: `${FRAMEWORK_EMOJI.mastra} Mastra`, value: "mastra" },
291
- { name: `${FRAMEWORK_EMOJI["pydantic-ai"]} Pydantic AI`, value: "pydantic-ai" },
292
- { name: `${FRAMEWORK_EMOJI["aws-strands-py"]} AWS Strands (Python)`, value: "aws-strands-py" },
437
+ {
438
+ name: `${FRAMEWORK_EMOJI["pydantic-ai"]} Pydantic AI`,
439
+ value: "pydantic-ai"
440
+ },
441
+ {
442
+ name: `${FRAMEWORK_EMOJI["aws-strands-py"]} AWS Strands (Python)`,
443
+ value: "aws-strands-py"
444
+ },
293
445
  { name: `${FRAMEWORK_EMOJI.adk} ADK`, value: "adk" },
294
446
  {
295
447
  name: `${FRAMEWORK_EMOJI["microsoft-agent-framework-dotnet"]} Microsoft Agent Framework (.NET)`,
@@ -299,9 +451,15 @@ Your project is ready to explore CopilotKit locally.`
299
451
  name: `${FRAMEWORK_EMOJI["microsoft-agent-framework-py"]} Microsoft Agent Framework (Python)`,
300
452
  value: "microsoft-agent-framework-py"
301
453
  },
302
- { name: `${FRAMEWORK_EMOJI["mcp-apps"]} MCP Apps`, value: "mcp-apps" },
454
+ {
455
+ name: `${FRAMEWORK_EMOJI["mcp-apps"]} MCP Apps`,
456
+ value: "mcp-apps"
457
+ },
303
458
  { name: `${FRAMEWORK_EMOJI.flows} CrewAI Flows`, value: "flows" },
304
- { name: `${FRAMEWORK_EMOJI.llamaindex} LlamaIndex`, value: "llamaindex" },
459
+ {
460
+ name: `${FRAMEWORK_EMOJI.llamaindex} LlamaIndex`,
461
+ value: "llamaindex"
462
+ },
305
463
  { name: `${FRAMEWORK_EMOJI.agno} Agno`, value: "agno" },
306
464
  { name: `${FRAMEWORK_EMOJI.ag2} AG2`, value: "ag2" },
307
465
  { name: `${FRAMEWORK_EMOJI.a2a} A2A`, value: "a2a" }
@@ -310,13 +468,25 @@ Your project is ready to explore CopilotKit locally.`
310
468
  ]);
311
469
  return framework;
312
470
  }
313
- async downloadTemplate(projectDir, framework) {
314
- const repo = TEMPLATE_REPOS[framework];
315
- const url = `https://github.com/${repo}/archive/refs/heads/main.tar.gz`;
471
+ async downloadTemplate(projectDir, framework, spinner) {
472
+ const templateRef = TEMPLATE_REPOS[framework];
473
+ if (isValidGitHubUrl(templateRef)) {
474
+ const success = await cloneGitHubSubdirectory(
475
+ templateRef,
476
+ projectDir,
477
+ spinner
478
+ );
479
+ if (!success) {
480
+ throw new Error(`Failed to clone template from ${templateRef}`);
481
+ }
482
+ return;
483
+ }
484
+ const url = `https://github.com/${templateRef}/archive/refs/heads/main.tar.gz`;
316
485
  try {
317
486
  const response = await fetch(url);
318
- if (!response.ok) throw new Error(`Failed to download template: ${response.statusText}`);
319
- const tempFile = path.join(projectDir, "template.tar.gz");
487
+ if (!response.ok)
488
+ throw new Error(`Failed to download template: ${response.statusText}`);
489
+ const tempFile = path2.join(projectDir, "template.tar.gz");
320
490
  const fileStream = createWriteStream(tempFile);
321
491
  if (!response.body) throw new Error("Failed to get response body");
322
492
  await streamPipeline(response.body, fileStream);
@@ -325,165 +495,25 @@ Your project is ready to explore CopilotKit locally.`
325
495
  cwd: projectDir,
326
496
  strip: 1
327
497
  });
328
- await fs.remove(tempFile);
498
+ await fs2.remove(tempFile);
329
499
  } catch (error) {
330
500
  throw new Error(`Failed to download template: ${error.message}`);
331
501
  }
332
502
  }
333
503
  };
334
504
 
335
- // src/lib/init/types/questions.ts
336
- import { z } from "zod";
337
- import { Flags as Flags2 } from "@oclif/core";
338
-
339
- // src/lib/init/utils.ts
340
- var isLocalhost = (url) => {
341
- return url.includes("localhost") || url.includes("127.0.0.1") || url.includes("0.0.0.0");
342
- };
343
-
344
- // src/lib/init/types/questions.ts
345
- var MODES = ["LangGraph", "CrewAI", "Mastra", "LlamaIndex", "Agno", "AG2", "MCP", "Standard"];
346
- var CREW_TYPES = ["Crews", "Flows"];
347
- var CHAT_COMPONENTS = ["CopilotChat", "CopilotSidebar", "Headless", "CopilotPopup"];
348
- var LANGGRAPH_AGENTS = ["Python Starter", "TypeScript Starter"];
349
- var CREW_FLOW_TEMPLATES = ["Starter"];
350
- var YES_NO = ["Yes", "No"];
351
- var DEPLOYMENT_CHOICES = ["Copilot Cloud", "Self-hosted"];
352
- var sanitizers = {
353
- // Remove trailing slash from URLs
354
- url: (value) => {
355
- if (!value) return value;
356
- return value.trim().replace(/\/+$/, "");
357
- },
358
- // Trim whitespace from strings
359
- trim: (value) => {
360
- if (!value) return value;
361
- return value.trim();
362
- },
363
- // Lowercase strings
364
- lowercase: (value) => {
365
- if (!value) return value;
366
- return value.toLowerCase().trim();
367
- },
368
- // Clean API keys (remove whitespace)
369
- apiKey: (value) => {
370
- if (!value) return value;
371
- return value.trim().replace(/\s/g, "");
372
- }
373
- };
374
- var ModeSchema = z.enum(MODES);
375
- var CrewTypeSchema = z.enum(CREW_TYPES);
376
- var ChatComponentSchema = z.enum(CHAT_COMPONENTS);
377
- var LangGraphAgentSchema = z.enum(LANGGRAPH_AGENTS);
378
- var CrewFlowTemplateSchema = z.enum(CREW_FLOW_TEMPLATES);
379
- var YesNoSchema = z.enum(YES_NO);
380
- var DeploymentChoiceSchema = z.enum(DEPLOYMENT_CHOICES);
381
- var UrlSchema = z.preprocess(
382
- (val) => sanitizers.url(String(val)),
383
- z.string().url("Please enter a valid URL").min(1, "URL is required")
384
- );
385
- var TokenSchema = z.preprocess((val) => sanitizers.trim(String(val)), z.string().min(1, "Token is required"));
386
- var ApiKeySchema = z.preprocess(
387
- (val) => sanitizers.apiKey(String(val)),
388
- z.string().min(1, "API key is required")
389
- );
390
- var LLMApiKeySchema = z.preprocess((val) => sanitizers.apiKey(String(val)), z.string().optional());
391
- var NameSchema = z.preprocess((val) => sanitizers.trim(String(val)), z.string().min(1, "Name is required"));
392
- var ConfigSchema = z.object({
393
- // Core fields
394
- copilotKitVersion: z.string().optional(),
395
- mode: ModeSchema,
396
- chatUi: ChatComponentSchema.optional(),
397
- // Yes/No fields
398
- alreadyDeployed: YesNoSchema.optional(),
399
- fastApiEnabled: YesNoSchema.optional(),
400
- // DEPRECATED: useCopilotCloud - consolidated with signupForCopilotCloud
401
- useCopilotCloud: YesNoSchema.optional(),
402
- // LangGraph specific fields
403
- langGraphAgent: LangGraphAgentSchema.optional(),
404
- langGraphPlatform: YesNoSchema.optional(),
405
- langGraphPlatformUrl: UrlSchema.optional(),
406
- langGraphRemoteEndpointURL: UrlSchema.optional(),
407
- // CrewAI specific fields
408
- crewType: CrewTypeSchema.optional(),
409
- crewName: NameSchema.optional(),
410
- crewUrl: UrlSchema.optional(),
411
- crewBearerToken: TokenSchema.optional(),
412
- // API keys and tokens
413
- copilotCloudPublicApiKey: z.string().optional(),
414
- langSmithApiKey: ApiKeySchema.optional(),
415
- llmToken: LLMApiKeySchema.optional(),
416
- // IDE Documentation setup fields
417
- setupIDEDocs: YesNoSchema.optional(),
418
- selectedIDE: z.union([z.enum(["cursor", "windsurf"]), z.literal("skip")]).optional(),
419
- // NEW: A/B/C test fields
420
- deploymentChoice: DeploymentChoiceSchema.optional()
421
- // For branch B only (Cloud vs Self-hosted)
422
- }).refine(
423
- (data) => {
424
- if (data.mode === "CrewAI") {
425
- return !!data.crewUrl && !!data.crewBearerToken;
426
- }
427
- return true;
428
- },
429
- {
430
- message: "Crew URL and bearer token are required for CrewAI",
431
- path: ["crewUrl", "crewBearerToken"]
432
- }
433
- ).refine(
434
- (data) => {
435
- if (data.mode === "LangGraph" && data.alreadyDeployed === "Yes" && data.langGraphPlatform === "Yes") {
436
- return !!data.langGraphPlatformUrl && !!data.langSmithApiKey || isLocalhost(data.langGraphPlatformUrl || "");
437
- }
438
- return true;
439
- },
440
- {
441
- message: "LangGraph Platform URL and LangSmith API key are required",
442
- path: ["langGraphPlatformUrl", "langSmithApiKey"]
443
- }
444
- );
445
- var ConfigFlags = {
446
- booth: Flags2.boolean({ description: "Use CopilotKit in booth mode", default: false, char: "b" }),
447
- mode: Flags2.string({ description: "How you will be interacting with AI", options: MODES, char: "m" }),
448
- "copilotkit-version": Flags2.string({ description: "CopilotKit version to use (e.g. 1.7.0)" }),
449
- "use-copilot-cloud": Flags2.string({ description: "Use Copilot Cloud for production-ready hosting", options: YES_NO }),
450
- "langgraph-agent": Flags2.string({ description: "LangGraph agent template to use", options: LANGGRAPH_AGENTS }),
451
- "crew-type": Flags2.string({ description: "CrewAI implementation type", options: CREW_TYPES }),
452
- "crew-name": Flags2.string({ description: "Name for your CrewAI agent" }),
453
- "crew-url": Flags2.string({ description: "URL endpoint for your CrewAI agent" }),
454
- "crew-bearer-token": Flags2.string({ description: "Bearer token for CrewAI authentication" }),
455
- "langsmith-api-key": Flags2.string({ description: "LangSmith API key for LangGraph observability" }),
456
- "llm-token": Flags2.string({ description: "API key for your preferred LLM provider" }),
457
- "setup-ide-docs": Flags2.string({ description: "Setup IDE documentation rules for AI assistance", options: YES_NO }),
458
- "selected-ide": Flags2.string({
459
- description: "IDE to configure with documentation rules",
460
- options: ["cursor", "windsurf", "skip"]
461
- }),
462
- // NEW: A/B/C test flags
463
- "deployment-choice": Flags2.string({
464
- description: "Choose between Copilot Cloud or Self-hosted deployment",
465
- options: DEPLOYMENT_CHOICES
466
- })
467
- };
468
-
469
505
  // src/commands/init.ts
470
- var CloudInit = class _CloudInit extends BaseCommand {
471
- static description = "Set up CopilotKit in your Next.js project, or create a new project if none exists";
472
- static examples = ["<%= config.bin %> init", "<%= config.bin %> init --dir ./my-app"];
473
- static flags = {
474
- ...BaseCommand.flags,
475
- ...ConfigFlags,
476
- runtimeUrl: Flags3.string({ description: "runtime URL" }),
477
- project: Flags3.string({ description: "project ID (can be found in the Copilot Cloud dashboard)" }),
478
- dir: Flags3.string({ description: "directory of the Next.js project", default: "." })
479
- };
506
+ var CloudInit = class extends BaseCommand {
507
+ static description = "`init` is deprecated \u2014 use `create` instead.";
508
+ static examples = ["<%= config.bin %> create"];
480
509
  constructor(argv, config) {
481
510
  super(argv, config);
482
511
  }
483
512
  async run() {
484
- const { flags } = await this.parse(_CloudInit);
485
- this.log("`copilotkit init` now routes to `copilotkit create`.");
486
- const createCommand = new Create([], this.config);
513
+ this.log(
514
+ "`copilotkit init` is deprecated. Redirecting to `copilotkit create`..."
515
+ );
516
+ const createCommand = new Create(this.argv, this.config);
487
517
  await createCommand.run();
488
518
  }
489
519
  };