copilotkit 0.0.58 → 1.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) Atai Barkai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -3,7 +3,7 @@ import { Command } from "@oclif/core";
3
3
  import Sentry, { consoleIntegration } from "@sentry/node";
4
4
 
5
5
  // src/utils/version.ts
6
- var LIB_VERSION = "0.0.58";
6
+ var LIB_VERSION = "1.54.0";
7
7
 
8
8
  // src/utils/trpc.ts
9
9
  import { createTRPCClient as trpcClient, httpBatchLink } from "@trpc/client";
@@ -44,11 +44,14 @@ var BaseCommand = class extends Command {
44
44
  async run() {
45
45
  }
46
46
  async checkCLIVersion() {
47
- const response = await fetch(`${COPILOT_CLOUD_BASE_URL}/api/healthz`);
48
- const data = await response.json();
49
- const cloudVersion = data.cliVersion;
50
- if (!cloudVersion || cloudVersion === LIB_VERSION) {
51
- 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 {
52
55
  }
53
56
  }
54
57
  async gracefulError(message) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/base-command.ts","../../src/utils/version.ts","../../src/utils/trpc.ts"],"sourcesContent":["import {Command} from '@oclif/core'\nimport Sentry, {consoleIntegration} from '@sentry/node'\nimport {LIB_VERSION} from '../utils/version.js'\nimport {COPILOT_CLOUD_BASE_URL} from '../utils/trpc.js'\nimport chalk from 'chalk'\n\nexport class BaseCommand extends Command {\n async init() {\n await this.checkCLIVersion()\n\n if (process.env.SENTRY_DISABLED === 'true') {\n return\n }\n\n Sentry.init({\n dsn:\n process.env.SENTRY_DSN ||\n 'https://1eea15d32e2eacb0456a77db5e39aeeb@o4507288195170304.ingest.us.sentry.io/4508581448581120',\n integrations: [consoleIntegration()],\n // Tracing\n tracesSampleRate: 1.0, // Capture 100% of the transactions\n })\n }\n\n async catch(err: any) {\n if (process.env.SENTRY_DISABLED !== 'true') {\n Sentry.captureException(err)\n }\n\n const message = err?.message ?? 'Unknown error'\n\n this.log('\\n' + chalk.red(message) + '\\n')\n\n const exitCode = err?.oclif?.exit ?? 1\n this.exit(exitCode)\n }\n\n async finally() {\n if (process.env.SENTRY_DISABLED === 'true') {\n return\n }\n\n Sentry.close()\n }\n\n async run() {}\n\n async checkCLIVersion() {\n const response = await fetch(`${COPILOT_CLOUD_BASE_URL}/api/healthz`)\n\n const data = await response.json()\n const cloudVersion = data.cliVersion\n\n if (!cloudVersion || cloudVersion === LIB_VERSION) {\n return\n }\n\n // TODO: add this back in, removed for crew ai launch since we don't want to keep releasing cloud\n // this.log(chalk.yellow('================ New version available! =================\\n'))\n // this.log(`You are using CopilotKit CLI v${LIB_VERSION}.`)\n // this.log(`A new CopilotKit CLI version is available (v${cloudVersion}).\\n`)\n // this.log('Please update your CLI to the latest version:\\n\\n')\n // this.log(`${chalk.cyan(chalk.underline(chalk.bold('npm:')))}\\t npm install -g copilotkit@${cloudVersion}\\n`)\n // this.log(`${chalk.cyan(chalk.underline(chalk.bold('pnpm:')))}\\t pnpm install -g copilotkit@${cloudVersion}\\n`)\n // this.log(`${chalk.cyan(chalk.underline(chalk.bold('yarn:')))}\\t yarn global add copilotkit@${cloudVersion}\\n`)\n // this.log(chalk.yellow('============================================================\\n\\n'))\n }\n\n async gracefulError(message: string) {\n this.log('\\n' + chalk.red(message))\n process.exit(1)\n }\n}\n","// This is auto generated!\nexport const LIB_VERSION = \"0.0.58\";\n","import {createTRPCClient as trpcClient, httpBatchLink} from '@trpc/client'\nimport superjson from 'superjson'\n\nexport const COPILOT_CLOUD_BASE_URL = process.env.COPILOT_CLOUD_BASE_URL || 'https://cloud.copilotkit.ai'\n\nexport function createTRPCClient(cliToken: string): any {\n return trpcClient({\n links: [\n httpBatchLink({\n url: `${COPILOT_CLOUD_BASE_URL}/api/trpc-cli`,\n transformer: superjson,\n headers: () => {\n return {\n 'x-trpc-source': 'cli',\n 'x-cli-token': cliToken,\n }\n },\n }),\n ],\n })\n}\n"],"mappings":";AAAA,SAAQ,eAAc;AACtB,OAAO,UAAS,0BAAyB;;;ACAlC,IAAM,cAAc;;;ACD3B,SAAQ,oBAAoB,YAAY,qBAAoB;AAC5D,OAAO,eAAe;AAEf,IAAM,yBAAyB,QAAQ,IAAI,0BAA0B;;;AFC5E,OAAO,WAAW;AAEX,IAAM,cAAN,cAA0B,QAAQ;AAAA,EACvC,MAAM,OAAO;AACX,UAAM,KAAK,gBAAgB;AAE3B,QAAI,QAAQ,IAAI,oBAAoB,QAAQ;AAC1C;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,MACV,KACE,QAAQ,IAAI,cACZ;AAAA,MACF,cAAc,CAAC,mBAAmB,CAAC;AAAA;AAAA,MAEnC,kBAAkB;AAAA;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAM,KAAU;AACpB,QAAI,QAAQ,IAAI,oBAAoB,QAAQ;AAC1C,aAAO,iBAAiB,GAAG;AAAA,IAC7B;AAEA,UAAM,UAAU,KAAK,WAAW;AAEhC,SAAK,IAAI,OAAO,MAAM,IAAI,OAAO,IAAI,IAAI;AAEzC,UAAM,WAAW,KAAK,OAAO,QAAQ;AACrC,SAAK,KAAK,QAAQ;AAAA,EACpB;AAAA,EAEA,MAAM,UAAU;AACd,QAAI,QAAQ,IAAI,oBAAoB,QAAQ;AAC1C;AAAA,IACF;AAEA,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,MAAM,MAAM;AAAA,EAAC;AAAA,EAEb,MAAM,kBAAkB;AACtB,UAAM,WAAW,MAAM,MAAM,GAAG,sBAAsB,cAAc;AAEpE,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAM,eAAe,KAAK;AAE1B,QAAI,CAAC,gBAAgB,iBAAiB,aAAa;AACjD;AAAA,IACF;AAAA,EAWF;AAAA,EAEA,MAAM,cAAc,SAAiB;AACnC,SAAK,IAAI,OAAO,MAAM,IAAI,OAAO,CAAC;AAClC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/commands/base-command.ts","../../src/utils/version.ts","../../src/utils/trpc.ts"],"sourcesContent":["import { Command } from \"@oclif/core\";\nimport Sentry, { consoleIntegration } from \"@sentry/node\";\nimport { LIB_VERSION } from \"../utils/version.js\";\nimport { COPILOT_CLOUD_BASE_URL } from \"../utils/trpc.js\";\nimport chalk from \"chalk\";\n\nexport class BaseCommand extends Command {\n async init() {\n await this.checkCLIVersion();\n\n if (process.env.SENTRY_DISABLED === \"true\") {\n return;\n }\n\n Sentry.init({\n dsn:\n process.env.SENTRY_DSN ||\n \"https://1eea15d32e2eacb0456a77db5e39aeeb@o4507288195170304.ingest.us.sentry.io/4508581448581120\",\n integrations: [consoleIntegration()],\n // Tracing\n tracesSampleRate: 1.0, // Capture 100% of the transactions\n });\n }\n\n async catch(err: any) {\n if (process.env.SENTRY_DISABLED !== \"true\") {\n Sentry.captureException(err);\n }\n\n const message = err?.message ?? \"Unknown error\";\n\n this.log(\"\\n\" + chalk.red(message) + \"\\n\");\n\n const exitCode = err?.oclif?.exit ?? 1;\n this.exit(exitCode);\n }\n\n async finally() {\n if (process.env.SENTRY_DISABLED === \"true\") {\n return;\n }\n\n Sentry.close();\n }\n\n async run() {}\n\n async checkCLIVersion() {\n try {\n const response = await fetch(`${COPILOT_CLOUD_BASE_URL}/api/healthz`);\n\n const data = await response.json();\n const cloudVersion = data.cliVersion;\n\n if (!cloudVersion || cloudVersion === LIB_VERSION) {\n return;\n }\n\n // TODO: add this back in, removed for crew ai launch since we don't want to keep releasing cloud\n // this.log(chalk.yellow('================ New version available! =================\\n'))\n // this.log(`You are using CopilotKit CLI v${LIB_VERSION}.`)\n // this.log(`A new CopilotKit CLI version is available (v${cloudVersion}).\\n`)\n // this.log('Please update your CLI to the latest version:\\n\\n')\n // this.log(`${chalk.cyan(chalk.underline(chalk.bold('npm:')))}\\t npm install -g copilotkit@${cloudVersion}\\n`)\n // this.log(`${chalk.cyan(chalk.underline(chalk.bold('pnpm:')))}\\t pnpm install -g copilotkit@${cloudVersion}\\n`)\n // this.log(`${chalk.cyan(chalk.underline(chalk.bold('yarn:')))}\\t yarn global add copilotkit@${cloudVersion}\\n`)\n // this.log(chalk.yellow('============================================================\\n\\n'))\n } catch {\n // Version check is non-critical — don't crash the CLI when offline\n }\n }\n\n async gracefulError(message: string) {\n this.log(\"\\n\" + chalk.red(message));\n process.exit(1);\n }\n}\n","// This is auto generated!\nexport const LIB_VERSION = \"1.54.0\";\n","import { createTRPCClient as trpcClient, httpBatchLink } from \"@trpc/client\";\nimport superjson from \"superjson\";\n\nexport const COPILOT_CLOUD_BASE_URL =\n process.env.COPILOT_CLOUD_BASE_URL || \"https://cloud.copilotkit.ai\";\n\nexport function createTRPCClient(cliToken: string): any {\n return trpcClient({\n links: [\n httpBatchLink({\n url: `${COPILOT_CLOUD_BASE_URL}/api/trpc-cli`,\n transformer: superjson,\n headers: () => {\n return {\n \"x-trpc-source\": \"cli\",\n \"x-cli-token\": cliToken,\n };\n },\n }),\n ],\n });\n}\n"],"mappings":";AAAA,SAAS,eAAe;AACxB,OAAO,UAAU,0BAA0B;;;ACApC,IAAM,cAAc;;;ACD3B,SAAS,oBAAoB,YAAY,qBAAqB;AAC9D,OAAO,eAAe;AAEf,IAAM,yBACX,QAAQ,IAAI,0BAA0B;;;AFAxC,OAAO,WAAW;AAEX,IAAM,cAAN,cAA0B,QAAQ;AAAA,EACvC,MAAM,OAAO;AACX,UAAM,KAAK,gBAAgB;AAE3B,QAAI,QAAQ,IAAI,oBAAoB,QAAQ;AAC1C;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,MACV,KACE,QAAQ,IAAI,cACZ;AAAA,MACF,cAAc,CAAC,mBAAmB,CAAC;AAAA;AAAA,MAEnC,kBAAkB;AAAA;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAM,KAAU;AACpB,QAAI,QAAQ,IAAI,oBAAoB,QAAQ;AAC1C,aAAO,iBAAiB,GAAG;AAAA,IAC7B;AAEA,UAAM,UAAU,KAAK,WAAW;AAEhC,SAAK,IAAI,OAAO,MAAM,IAAI,OAAO,IAAI,IAAI;AAEzC,UAAM,WAAW,KAAK,OAAO,QAAQ;AACrC,SAAK,KAAK,QAAQ;AAAA,EACpB;AAAA,EAEA,MAAM,UAAU;AACd,QAAI,QAAQ,IAAI,oBAAoB,QAAQ;AAC1C;AAAA,IACF;AAEA,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,MAAM,MAAM;AAAA,EAAC;AAAA,EAEb,MAAM,kBAAkB;AACtB,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,sBAAsB,cAAc;AAEpE,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,eAAe,KAAK;AAE1B,UAAI,CAAC,gBAAgB,iBAAiB,aAAa;AACjD;AAAA,MACF;AAAA,IAWF,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,SAAiB;AACnC,SAAK,IAAI,OAAO,MAAM,IAAI,OAAO,CAAC;AAClC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;","names":[]}
@@ -8,7 +8,7 @@ declare class Create extends BaseCommand {
8
8
  static flags: {
9
9
  framework: _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
10
10
  name: _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
11
- 'no-banner': _oclif_core_interfaces.BooleanFlag<boolean>;
11
+ "no-banner": _oclif_core_interfaces.BooleanFlag<boolean>;
12
12
  project: _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
13
13
  };
14
14
  static args: {
@@ -1,9 +1,9 @@
1
1
  // src/commands/create.ts
2
2
  import { Flags, Args } from "@oclif/core";
3
3
  import inquirer from "inquirer";
4
- import chalk2 from "chalk";
5
- import fs from "fs-extra";
6
- import path from "path";
4
+ import chalk3 from "chalk";
5
+ import fs2 from "fs-extra";
6
+ import path2 from "path";
7
7
  import { promisify } from "util";
8
8
  import { pipeline } from "stream";
9
9
  import { createWriteStream } from "fs";
@@ -15,7 +15,7 @@ import { Command } from "@oclif/core";
15
15
  import Sentry, { consoleIntegration } from "@sentry/node";
16
16
 
17
17
  // src/utils/version.ts
18
- var LIB_VERSION = "0.0.58";
18
+ var LIB_VERSION = "1.54.0";
19
19
 
20
20
  // src/utils/trpc.ts
21
21
  import { createTRPCClient as trpcClient, httpBatchLink } from "@trpc/client";
@@ -56,11 +56,14 @@ var BaseCommand = class extends Command {
56
56
  async run() {
57
57
  }
58
58
  async checkCLIVersion() {
59
- const response = await fetch(`${COPILOT_CLOUD_BASE_URL}/api/healthz`);
60
- const data = await response.json();
61
- const cloudVersion = data.cliVersion;
62
- if (!cloudVersion || cloudVersion === LIB_VERSION) {
63
- return;
59
+ try {
60
+ const response = await fetch(`${COPILOT_CLOUD_BASE_URL}/api/healthz`);
61
+ const data = await response.json();
62
+ const cloudVersion = data.cliVersion;
63
+ if (!cloudVersion || cloudVersion === LIB_VERSION) {
64
+ return;
65
+ }
66
+ } catch {
64
67
  }
65
68
  }
66
69
  async gracefulError(message) {
@@ -69,34 +72,144 @@ var BaseCommand = class extends Command {
69
72
  }
70
73
  };
71
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
+
72
185
  // src/commands/create.ts
73
186
  var streamPipeline = promisify(pipeline);
74
187
  var theme = {
75
- primary: chalk2.magenta,
76
- secondary: chalk2.gray,
77
- tertiary: chalk2.gray,
78
- error: chalk2.red,
79
- command: chalk2.blue,
80
- success: chalk2.green,
81
- warning: chalk2.yellow,
82
- divider: chalk2.gray("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"),
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"),
83
196
  bottomPadding: ""
84
197
  };
85
198
  var TEMPLATE_REPOS = {
86
- "langgraph-py": "copilotkit/with-langgraph-python",
87
- "langgraph-js": "copilotkit/with-langgraph-js",
88
- mastra: "copilotkit/with-mastra",
89
- flows: "copilotkit/with-crewai-flows",
90
- llamaindex: "copilotkit/with-llamaindex",
91
- agno: "copilotkit/with-agno",
92
- "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",
93
206
  ag2: "ag2ai/ag2-copilotkit-starter",
94
- adk: "copilotkit/with-adk",
95
- "aws-strands-py": "copilotkit/with-strands-python",
96
- a2a: "copilotkit/with-a2a-middleware",
97
- "microsoft-agent-framework-dotnet": "copilotkit/with-microsoft-agent-framework-dotnet",
98
- "microsoft-agent-framework-py": "copilotkit/with-microsoft-agent-framework-python",
99
- "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"
100
213
  };
101
214
  var FRAMEWORK_DOCUMENTATION = {
102
215
  "langgraph-py": "https://langchain-ai.github.io/langgraph/concepts/why-langgraph",
@@ -192,30 +305,42 @@ var Create = class _Create extends BaseCommand {
192
305
  this.log(theme.primary(KITE));
193
306
  this.log(theme.primary("~ Welcome to CopilotKit! ~\n"));
194
307
  this.log(theme.divider);
195
- if ((!flags.name || flags.projectName) && !flags.framework) {
196
- 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
+ );
197
312
  }
198
313
  }
199
314
  const projectNameInput = flags.name || args.projectName || await this.promptProjectName();
200
315
  const projectName = projectNameInput.trim();
201
316
  const usingCurrentDir = projectName === "." || projectName === "./";
202
317
  const agentFramework = flags.framework || await this.promptAgentFramework();
203
- const projectDir = usingCurrentDir ? process.cwd() : path.resolve(process.cwd(), projectName);
318
+ const projectDir = usingCurrentDir ? process.cwd() : path2.resolve(process.cwd(), projectName);
204
319
  if (usingCurrentDir) {
205
320
  const allowedEntries = /* @__PURE__ */ new Set([".git", ".gitignore", ".DS_Store"]);
206
- const existingEntries = await fs.readdir(projectDir);
207
- 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
+ );
208
325
  if (blockingEntries.length > 0) {
209
326
  this.log(theme.error("\nCurrent directory is not empty."));
210
- 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
+ );
211
332
  this.exit(1);
212
333
  }
213
- } else if (await fs.pathExists(projectDir)) {
334
+ } else if (await fs2.pathExists(projectDir)) {
214
335
  this.log(theme.error(`
215
336
  Directory "${projectName}" already exists.`));
216
337
  this.log(theme.secondary("\nYou can:"));
217
338
  this.log(theme.secondary(" 1. Choose a different project name"));
218
- 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
+ );
219
344
  this.exit(1);
220
345
  }
221
346
  const options = {
@@ -228,11 +353,13 @@ Directory "${projectName}" already exists.`));
228
353
  spinner: "dots"
229
354
  }).start();
230
355
  try {
231
- await fs.ensureDir(projectDir);
356
+ await fs2.ensureDir(projectDir);
232
357
  spinner.text = theme.secondary.bold("Downloading template...");
233
- await this.downloadTemplate(projectDir, options.agentFramework);
358
+ await this.downloadTemplate(projectDir, options.agentFramework, spinner);
234
359
  const displayName = usingCurrentDir ? "current directory" : `"${projectName}"`;
235
- spinner.succeed(theme.secondary.bold(`Project ${displayName} created successfully!`));
360
+ spinner.succeed(
361
+ theme.secondary.bold(`Project ${displayName} created successfully!`)
362
+ );
236
363
  } catch (error) {
237
364
  spinner.fail(theme.error(`Failed to create project: ${error.message}`));
238
365
  this.exit(1);
@@ -247,14 +374,24 @@ Your project is ready to explore CopilotKit locally.`
247
374
  );
248
375
  this.log("\n" + theme.secondary("Next steps:"));
249
376
  if (usingCurrentDir) {
250
- 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
+ );
251
382
  } else {
252
383
  this.log(theme.secondary(` \u2022 ${theme.command(`cd ${projectName}`)}`));
253
384
  }
254
- 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
+ );
255
388
  this.log("\n" + theme.secondary("Documentation:"));
256
- this.log(theme.secondary(" \u2022 ") + theme.command("https://docs.copilotkit.ai"));
257
- 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
+ );
258
395
  this.log(theme.bottomPadding);
259
396
  }
260
397
  async promptProjectName() {
@@ -266,7 +403,9 @@ Your project is ready to explore CopilotKit locally.`
266
403
  validate: (input) => {
267
404
  if (!input) return theme.error("Project name is required");
268
405
  if (!/^[a-z0-9-]+$/.test(input)) {
269
- 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
+ );
270
409
  }
271
410
  if (input.length > 30) {
272
411
  return theme.error("Project name must be less than 30 characters");
@@ -282,13 +421,27 @@ Your project is ready to explore CopilotKit locally.`
282
421
  {
283
422
  type: "list",
284
423
  name: "framework",
285
- 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
+ ),
286
427
  choices: [
287
- { name: `${FRAMEWORK_EMOJI["langgraph-py"]} LangGraph (Python)`, value: "langgraph-py" },
288
- { 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
+ },
289
436
  { name: `${FRAMEWORK_EMOJI.mastra} Mastra`, value: "mastra" },
290
- { name: `${FRAMEWORK_EMOJI["pydantic-ai"]} Pydantic AI`, value: "pydantic-ai" },
291
- { 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
+ },
292
445
  { name: `${FRAMEWORK_EMOJI.adk} ADK`, value: "adk" },
293
446
  {
294
447
  name: `${FRAMEWORK_EMOJI["microsoft-agent-framework-dotnet"]} Microsoft Agent Framework (.NET)`,
@@ -298,9 +451,15 @@ Your project is ready to explore CopilotKit locally.`
298
451
  name: `${FRAMEWORK_EMOJI["microsoft-agent-framework-py"]} Microsoft Agent Framework (Python)`,
299
452
  value: "microsoft-agent-framework-py"
300
453
  },
301
- { name: `${FRAMEWORK_EMOJI["mcp-apps"]} MCP Apps`, value: "mcp-apps" },
454
+ {
455
+ name: `${FRAMEWORK_EMOJI["mcp-apps"]} MCP Apps`,
456
+ value: "mcp-apps"
457
+ },
302
458
  { name: `${FRAMEWORK_EMOJI.flows} CrewAI Flows`, value: "flows" },
303
- { name: `${FRAMEWORK_EMOJI.llamaindex} LlamaIndex`, value: "llamaindex" },
459
+ {
460
+ name: `${FRAMEWORK_EMOJI.llamaindex} LlamaIndex`,
461
+ value: "llamaindex"
462
+ },
304
463
  { name: `${FRAMEWORK_EMOJI.agno} Agno`, value: "agno" },
305
464
  { name: `${FRAMEWORK_EMOJI.ag2} AG2`, value: "ag2" },
306
465
  { name: `${FRAMEWORK_EMOJI.a2a} A2A`, value: "a2a" }
@@ -309,13 +468,25 @@ Your project is ready to explore CopilotKit locally.`
309
468
  ]);
310
469
  return framework;
311
470
  }
312
- async downloadTemplate(projectDir, framework) {
313
- const repo = TEMPLATE_REPOS[framework];
314
- 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`;
315
485
  try {
316
486
  const response = await fetch(url);
317
- if (!response.ok) throw new Error(`Failed to download template: ${response.statusText}`);
318
- 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");
319
490
  const fileStream = createWriteStream(tempFile);
320
491
  if (!response.body) throw new Error("Failed to get response body");
321
492
  await streamPipeline(response.body, fileStream);
@@ -324,7 +495,7 @@ Your project is ready to explore CopilotKit locally.`
324
495
  cwd: projectDir,
325
496
  strip: 1
326
497
  });
327
- await fs.remove(tempFile);
498
+ await fs2.remove(tempFile);
328
499
  } catch (error) {
329
500
  throw new Error(`Failed to download template: ${error.message}`);
330
501
  }