copilotkit 0.0.13 → 0.0.14
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/README.md +28 -1
- package/dist/commands/base-command.js +1 -1
- package/dist/commands/base-command.js.map +1 -1
- package/dist/commands/dev.js +27 -14
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/init.d.ts +36 -0
- package/dist/commands/init.js +856 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.js +1 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +1 -1
- package/dist/commands/logout.js.map +1 -1
- package/dist/lib/init/index.d.ts +9 -0
- package/dist/lib/init/index.js +441 -0
- package/dist/lib/init/index.js.map +1 -0
- package/dist/lib/init/questions.d.ts +6 -0
- package/dist/lib/init/questions.js +133 -0
- package/dist/lib/init/questions.js.map +1 -0
- package/dist/lib/init/scaffold/env.d.ts +6 -0
- package/dist/lib/init/scaffold/env.js +68 -0
- package/dist/lib/init/scaffold/env.js.map +1 -0
- package/dist/lib/init/scaffold/github.d.ts +20 -0
- package/dist/lib/init/scaffold/github.js +138 -0
- package/dist/lib/init/scaffold/github.js.map +1 -0
- package/dist/lib/init/scaffold/index.d.ts +7 -0
- package/dist/lib/init/scaffold/index.js +339 -0
- package/dist/lib/init/scaffold/index.js.map +1 -0
- package/dist/lib/init/scaffold/packages.d.ts +6 -0
- package/dist/lib/init/scaffold/packages.js +60 -0
- package/dist/lib/init/scaffold/packages.js.map +1 -0
- package/dist/lib/init/scaffold/shadcn.d.ts +6 -0
- package/dist/lib/init/scaffold/shadcn.js +79 -0
- package/dist/lib/init/scaffold/shadcn.js.map +1 -0
- package/dist/lib/init/types/index.d.ts +3 -0
- package/dist/lib/init/types/index.js +41 -0
- package/dist/lib/init/types/index.js.map +1 -0
- package/dist/lib/init/types/questions.d.ts +55 -0
- package/dist/lib/init/types/questions.js +28 -0
- package/dist/lib/init/types/questions.js.map +1 -0
- package/dist/lib/init/types/templates.d.ts +6 -0
- package/dist/lib/init/types/templates.js +15 -0
- package/dist/lib/init/types/templates.js.map +1 -0
- package/dist/services/events.d.ts +11 -8
- package/dist/utils/detect-endpoint-type.utils.d.ts +2 -1
- package/dist/utils/detect-endpoint-type.utils.js +27 -13
- package/dist/utils/detect-endpoint-type.utils.js.map +1 -1
- package/dist/utils/trpc.d.ts +64 -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 +158 -1
- package/package.json +3 -1
|
@@ -0,0 +1,856 @@
|
|
|
1
|
+
// src/commands/init.ts
|
|
2
|
+
import { Flags as Flags2 } from "@oclif/core";
|
|
3
|
+
import inquirer2 from "inquirer";
|
|
4
|
+
import path3 from "path";
|
|
5
|
+
import fs3 from "fs";
|
|
6
|
+
|
|
7
|
+
// src/services/auth.service.ts
|
|
8
|
+
import Conf2 from "conf";
|
|
9
|
+
import cors from "cors";
|
|
10
|
+
import express from "express";
|
|
11
|
+
import crypto2 from "node:crypto";
|
|
12
|
+
import open from "open";
|
|
13
|
+
import getPort from "get-port";
|
|
14
|
+
import ora from "ora";
|
|
15
|
+
import chalk from "chalk";
|
|
16
|
+
import inquirer from "inquirer";
|
|
17
|
+
|
|
18
|
+
// src/utils/trpc.ts
|
|
19
|
+
import { createTRPCClient as createTRPClient_, unstable_httpBatchStreamLink } from "@trpc/client";
|
|
20
|
+
import superjson from "superjson";
|
|
21
|
+
var COPILOT_CLOUD_BASE_URL = process.env.COPILOT_CLOUD_BASE_URL || "https://cloud.copilotkit.ai";
|
|
22
|
+
function createTRPCClient(cliToken) {
|
|
23
|
+
return createTRPClient_({
|
|
24
|
+
links: [
|
|
25
|
+
unstable_httpBatchStreamLink({
|
|
26
|
+
transformer: superjson,
|
|
27
|
+
url: `${COPILOT_CLOUD_BASE_URL}/api/trpc-cli`,
|
|
28
|
+
headers: () => {
|
|
29
|
+
const headers = new Headers();
|
|
30
|
+
headers.set("x-trpc-source", "cli");
|
|
31
|
+
headers.set("x-cli-token", cliToken);
|
|
32
|
+
return headers;
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
]
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/services/analytics.service.ts
|
|
40
|
+
import { Analytics } from "@segment/analytics-node";
|
|
41
|
+
import Conf from "conf";
|
|
42
|
+
var AnalyticsService = class {
|
|
43
|
+
constructor(authData) {
|
|
44
|
+
this.authData = authData;
|
|
45
|
+
if (process.env.SEGMENT_DISABLED === "true") {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const segmentWriteKey = process.env.SEGMENT_WRITE_KEY || "9Pv6QyExYef2P4hPz4gks6QAvNMi2AOf";
|
|
49
|
+
this.globalProperties = {
|
|
50
|
+
service: "cli"
|
|
51
|
+
};
|
|
52
|
+
if (this.authData?.userId) {
|
|
53
|
+
this.userId = this.authData.userId;
|
|
54
|
+
}
|
|
55
|
+
if (this.authData?.email) {
|
|
56
|
+
this.email = this.authData.email;
|
|
57
|
+
this.globalProperties.email = this.authData.email;
|
|
58
|
+
}
|
|
59
|
+
if (this.authData?.organizationId) {
|
|
60
|
+
this.organizationId = this.authData.organizationId;
|
|
61
|
+
}
|
|
62
|
+
this.segment = new Analytics({
|
|
63
|
+
writeKey: segmentWriteKey,
|
|
64
|
+
disable: process.env.SEGMENT_DISABLE === "true"
|
|
65
|
+
});
|
|
66
|
+
const config = new Conf({ projectName: "CopilotKitCLI" });
|
|
67
|
+
if (!config.get("anonymousId")) {
|
|
68
|
+
config.set("anonymousId", crypto.randomUUID());
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
segment;
|
|
72
|
+
globalProperties = {};
|
|
73
|
+
userId;
|
|
74
|
+
email;
|
|
75
|
+
organizationId;
|
|
76
|
+
config = new Conf({ projectName: "CopilotKitCLI" });
|
|
77
|
+
getAnonymousId() {
|
|
78
|
+
const anonymousId = this.config.get("anonymousId");
|
|
79
|
+
if (!anonymousId) {
|
|
80
|
+
const anonymousId2 = crypto.randomUUID();
|
|
81
|
+
this.config.set("anonymousId", anonymousId2);
|
|
82
|
+
return anonymousId2;
|
|
83
|
+
}
|
|
84
|
+
return anonymousId;
|
|
85
|
+
}
|
|
86
|
+
track(event) {
|
|
87
|
+
if (!this.segment) {
|
|
88
|
+
return Promise.resolve();
|
|
89
|
+
}
|
|
90
|
+
const payload = {
|
|
91
|
+
userId: this.userId ? this.userId : void 0,
|
|
92
|
+
email: this.email ? this.email : void 0,
|
|
93
|
+
anonymousId: this.getAnonymousId(),
|
|
94
|
+
event: event.event,
|
|
95
|
+
properties: {
|
|
96
|
+
...this.globalProperties,
|
|
97
|
+
...event.properties,
|
|
98
|
+
$groups: this.organizationId ? {
|
|
99
|
+
segment_group: this.organizationId
|
|
100
|
+
} : void 0,
|
|
101
|
+
eventProperties: {
|
|
102
|
+
...event.properties,
|
|
103
|
+
...this.globalProperties
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
return new Promise((resolve, reject) => {
|
|
108
|
+
this.segment.track(payload, (err) => {
|
|
109
|
+
if (err) {
|
|
110
|
+
resolve();
|
|
111
|
+
}
|
|
112
|
+
resolve();
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// src/services/auth.service.ts
|
|
119
|
+
var AuthService = class {
|
|
120
|
+
config = new Conf2({ projectName: "CopilotKitCLI" });
|
|
121
|
+
COPILOT_CLOUD_BASE_URL = process.env.COPILOT_CLOUD_BASE_URL || "https://cloud.copilotkit.ai";
|
|
122
|
+
getToken() {
|
|
123
|
+
return this.config.get("cliToken");
|
|
124
|
+
}
|
|
125
|
+
getCLIToken() {
|
|
126
|
+
const cliToken = this.config.get("cliToken");
|
|
127
|
+
return cliToken;
|
|
128
|
+
}
|
|
129
|
+
async logout(cmd) {
|
|
130
|
+
this.config.delete("cliToken");
|
|
131
|
+
}
|
|
132
|
+
async requireLogin(cmd) {
|
|
133
|
+
let cliToken = this.getCLIToken();
|
|
134
|
+
if (!cliToken) {
|
|
135
|
+
try {
|
|
136
|
+
const { shouldLogin } = await inquirer.prompt([
|
|
137
|
+
{
|
|
138
|
+
name: "shouldLogin",
|
|
139
|
+
type: "confirm",
|
|
140
|
+
message: "You are not yet authenticated. Authenticate with Copilot Cloud? (press Enter to confirm)",
|
|
141
|
+
default: true
|
|
142
|
+
}
|
|
143
|
+
]);
|
|
144
|
+
if (shouldLogin) {
|
|
145
|
+
const loginResult = await this.login({ exitAfterLogin: false });
|
|
146
|
+
cliToken = loginResult.cliToken;
|
|
147
|
+
cmd.log(`\u{1FA81} Logged in as ${chalk.hex("#7553fc")(loginResult.user.email)}
|
|
148
|
+
`);
|
|
149
|
+
return loginResult;
|
|
150
|
+
} else {
|
|
151
|
+
cmd.error("Authentication required to proceed.");
|
|
152
|
+
}
|
|
153
|
+
} catch (error) {
|
|
154
|
+
if (error instanceof Error && error.name === "ExitPromptError") {
|
|
155
|
+
cmd.error(chalk.yellow("\nAuthentication cancelled"));
|
|
156
|
+
}
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
let me;
|
|
161
|
+
const trpcClient = createTRPCClient(cliToken);
|
|
162
|
+
try {
|
|
163
|
+
me = await trpcClient.me.query();
|
|
164
|
+
} catch (error) {
|
|
165
|
+
cmd.log(chalk.red("Could not authenticate with Copilot Cloud. Please try again."));
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
if (!me.organization || !me.user) {
|
|
169
|
+
cmd.error("Authentication required to proceed.");
|
|
170
|
+
}
|
|
171
|
+
return { cliToken, user: me.user, organization: me.organization };
|
|
172
|
+
}
|
|
173
|
+
async login({ exitAfterLogin } = { exitAfterLogin: true }) {
|
|
174
|
+
let analytics;
|
|
175
|
+
analytics = new AnalyticsService();
|
|
176
|
+
const app = express();
|
|
177
|
+
app.use(cors());
|
|
178
|
+
app.use(express.urlencoded({ extended: true }));
|
|
179
|
+
app.use(express.json());
|
|
180
|
+
const port = await getPort();
|
|
181
|
+
const state = crypto2.randomBytes(16).toString("hex");
|
|
182
|
+
return new Promise(async (resolve) => {
|
|
183
|
+
const server = app.listen(port, () => {
|
|
184
|
+
});
|
|
185
|
+
await analytics.track({
|
|
186
|
+
event: "cli.login.initiated",
|
|
187
|
+
properties: {}
|
|
188
|
+
});
|
|
189
|
+
const spinner = ora("Waiting for browser authentication to complete...\n").start();
|
|
190
|
+
app.post("/callback", async (req, res) => {
|
|
191
|
+
const { cliToken, user, organization } = req.body;
|
|
192
|
+
analytics = new AnalyticsService({ userId: user.id, organizationId: organization.id, email: user.email });
|
|
193
|
+
await analytics.track({
|
|
194
|
+
event: "cli.login.success",
|
|
195
|
+
properties: {
|
|
196
|
+
organizationId: organization.id,
|
|
197
|
+
userId: user.id,
|
|
198
|
+
email: user.email
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
if (state !== req.query.state) {
|
|
202
|
+
res.status(401).json({ message: "Invalid state" });
|
|
203
|
+
spinner.fail("Invalid state");
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
this.config.set("cliToken", cliToken);
|
|
207
|
+
res.status(200).json({ message: "Callback called" });
|
|
208
|
+
spinner.succeed(`\u{1FA81} Successfully logged in as ${chalk.hex("#7553fc")(user.email)}
|
|
209
|
+
`);
|
|
210
|
+
if (exitAfterLogin) {
|
|
211
|
+
process.exit(0);
|
|
212
|
+
} else {
|
|
213
|
+
server.close();
|
|
214
|
+
resolve({ cliToken, user, organization });
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
open(`${this.COPILOT_CLOUD_BASE_URL}/cli-auth?callbackUrl=http://localhost:${port}/callback&state=${state}`);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// src/commands/base-command.ts
|
|
223
|
+
import { Command } from "@oclif/core";
|
|
224
|
+
import Sentry, { consoleIntegration } from "@sentry/node";
|
|
225
|
+
|
|
226
|
+
// src/utils/version.ts
|
|
227
|
+
var LIB_VERSION = "0.0.14";
|
|
228
|
+
|
|
229
|
+
// src/commands/base-command.ts
|
|
230
|
+
import chalk2 from "chalk";
|
|
231
|
+
var BaseCommand = class extends Command {
|
|
232
|
+
async init() {
|
|
233
|
+
await this.checkCLIVersion();
|
|
234
|
+
if (process.env.SENTRY_DISABLED === "true") {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
Sentry.init({
|
|
238
|
+
dsn: process.env.SENTRY_DSN || "https://1eea15d32e2eacb0456a77db5e39aeeb@o4507288195170304.ingest.us.sentry.io/4508581448581120",
|
|
239
|
+
integrations: [
|
|
240
|
+
consoleIntegration()
|
|
241
|
+
],
|
|
242
|
+
// Tracing
|
|
243
|
+
tracesSampleRate: 1
|
|
244
|
+
// Capture 100% of the transactions
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
async catch(err) {
|
|
248
|
+
if (process.env.SENTRY_DISABLED === "true") {
|
|
249
|
+
super.catch(err);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
Sentry.captureException(err);
|
|
253
|
+
super.catch(err);
|
|
254
|
+
}
|
|
255
|
+
async finally() {
|
|
256
|
+
if (process.env.SENTRY_DISABLED === "true") {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
Sentry.close();
|
|
260
|
+
}
|
|
261
|
+
async run() {
|
|
262
|
+
}
|
|
263
|
+
async checkCLIVersion() {
|
|
264
|
+
const response = await fetch(`${COPILOT_CLOUD_BASE_URL}/api/healthz`);
|
|
265
|
+
const data = await response.json();
|
|
266
|
+
const cloudVersion = data.cliVersion;
|
|
267
|
+
if (!cloudVersion || cloudVersion === LIB_VERSION) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
this.log(chalk2.yellow("================ New version available! =================\n"));
|
|
271
|
+
this.log(`You are using CopilotKit CLI v${LIB_VERSION}.`);
|
|
272
|
+
this.log(`A new CopilotKit CLI version is available (v${cloudVersion}).
|
|
273
|
+
`);
|
|
274
|
+
this.log("Please update your CLI to the latest version:\n\n");
|
|
275
|
+
this.log(`${chalk2.cyan(chalk2.underline(chalk2.bold("npm:")))} npm install -g copilotkit@${cloudVersion}
|
|
276
|
+
`);
|
|
277
|
+
this.log(`${chalk2.cyan(chalk2.underline(chalk2.bold("pnpm:")))} pnpm install -g copilotkit@${cloudVersion}
|
|
278
|
+
`);
|
|
279
|
+
this.log(`${chalk2.cyan(chalk2.underline(chalk2.bold("yarn:")))} yarn global add copilotkit@${cloudVersion}
|
|
280
|
+
`);
|
|
281
|
+
this.log(chalk2.yellow("============================================================\n\n"));
|
|
282
|
+
}
|
|
283
|
+
async gracefulError(message) {
|
|
284
|
+
this.log("\n" + chalk2.red(message));
|
|
285
|
+
process.exit(1);
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
// src/lib/init/types/questions.ts
|
|
290
|
+
import { Flags } from "@oclif/core";
|
|
291
|
+
var AGENT_FRAMEWORKS = ["CrewAI", "LangGraph", "None"];
|
|
292
|
+
var CREW_TYPES = ["Crews", "Flows"];
|
|
293
|
+
var CHAT_COMPONENTS = ["CopilotChat", "CopilotSidebar", "Headless", "CopilotPopup"];
|
|
294
|
+
var LANGGRAPH_AGENTS = ["Python Starter", "TypeScript Starter", "None"];
|
|
295
|
+
var ConfigFlags = {
|
|
296
|
+
copilotKitVersion: Flags.string({ description: "CopilotKit version to use (e.g. 1.7.0)" }),
|
|
297
|
+
agentFramework: Flags.string({ description: "Agent framework to power your copilot", options: AGENT_FRAMEWORKS }),
|
|
298
|
+
fastApiEnabled: Flags.string({ description: "Use FastAPI to serve your agent locally", options: ["Yes", "No"] }),
|
|
299
|
+
useCopilotCloud: Flags.string({ description: "Use Copilot Cloud for production-ready hosting", options: ["Yes", "No"] }),
|
|
300
|
+
chatUi: Flags.string({ description: "Chat UI component to add to your app", options: CHAT_COMPONENTS }),
|
|
301
|
+
langGraphAgent: Flags.string({ description: "LangGraph agent template to use", options: LANGGRAPH_AGENTS }),
|
|
302
|
+
crewType: Flags.string({ description: "CrewAI implementation type", options: CREW_TYPES }),
|
|
303
|
+
crewName: Flags.string({ description: "Name for your CrewAI agent" }),
|
|
304
|
+
crewUrl: Flags.string({ description: "URL endpoint for your CrewAI agent" }),
|
|
305
|
+
crewBearerToken: Flags.string({ description: "Bearer token for CrewAI authentication" }),
|
|
306
|
+
langSmithApiKey: Flags.string({ description: "LangSmith API key for LangGraph observability" }),
|
|
307
|
+
llmToken: Flags.string({ description: "API key for your preferred LLM provider" })
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
// src/lib/init/types/templates.ts
|
|
311
|
+
var BASE_URL = "http://registry.copilotkit.ai/r";
|
|
312
|
+
var templateMapping = {
|
|
313
|
+
"LangGraphPlatform": `${BASE_URL}/langgraph-platform-starter.json`,
|
|
314
|
+
"RemoteEndpoint": `${BASE_URL}/remote-endpoint-starter.json`,
|
|
315
|
+
"CrewEnterprise": `${BASE_URL}/agent-layout.json`,
|
|
316
|
+
"Standard": `${BASE_URL}/standard-starter.json`,
|
|
317
|
+
"CopilotChat": `${BASE_URL}/chat.json`,
|
|
318
|
+
"CopilotPopup": `${BASE_URL}/popup.json`,
|
|
319
|
+
"CopilotSidebar": `${BASE_URL}/sidebar.json`
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// src/lib/init/questions.ts
|
|
323
|
+
var questions = [
|
|
324
|
+
// Core setup questions - always shown first
|
|
325
|
+
{
|
|
326
|
+
type: "select",
|
|
327
|
+
name: "agentFramework",
|
|
328
|
+
message: "\u{1F916} Choose your AI framework:",
|
|
329
|
+
choices: Array.from(AGENT_FRAMEWORKS)
|
|
330
|
+
},
|
|
331
|
+
// CrewAI specific questions - shown when CrewAI selected
|
|
332
|
+
{
|
|
333
|
+
type: "select",
|
|
334
|
+
name: "crewType",
|
|
335
|
+
message: "\u{1F4CB} Select CrewAI implementation type:",
|
|
336
|
+
choices: Array.from(CREW_TYPES),
|
|
337
|
+
when: (answers) => answers.agentFramework === "CrewAI"
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
type: "input",
|
|
341
|
+
name: "crewName",
|
|
342
|
+
message: "\u{1F465} What would you like to name your crew?",
|
|
343
|
+
when: (answers) => answers.agentFramework === "CrewAI" && answers.crewType === "Crews",
|
|
344
|
+
default: "MyCopilotCrew"
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
type: "input",
|
|
348
|
+
name: "crewUrl",
|
|
349
|
+
message: "\u{1F517} Enter your Crew API endpoint:",
|
|
350
|
+
when: (answers) => answers.agentFramework === "CrewAI" && answers.crewType === "Crews"
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
type: "input",
|
|
354
|
+
name: "crewBearerToken",
|
|
355
|
+
message: "\u{1F511} Enter your Crew authentication token:",
|
|
356
|
+
when: (answers) => answers.agentFramework === "CrewAI" && answers.crewType === "Crews"
|
|
357
|
+
},
|
|
358
|
+
// LangGraph specific questions - shown when LangGraph selected
|
|
359
|
+
{
|
|
360
|
+
type: "yes/no",
|
|
361
|
+
name: "alreadyDeployed",
|
|
362
|
+
message: "\u{1F680} Is your LangGraph agent already deployed?",
|
|
363
|
+
when: (answers) => answers.agentFramework === "LangGraph"
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
type: "yes/no",
|
|
367
|
+
name: "langGraphPlatform",
|
|
368
|
+
message: "\u{1F99C}\u{1F517} Is it hosted on LangGraph Platform?",
|
|
369
|
+
when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "Yes"
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
type: "input",
|
|
373
|
+
name: "langGraphPlatformUrl",
|
|
374
|
+
message: "\u{1F99C}\u{1F517} Enter your LangGraph platform URL:",
|
|
375
|
+
when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "Yes" && answers.langGraphPlatform === "Yes"
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
type: "input",
|
|
379
|
+
name: "langGraphRemoteEndpointURL",
|
|
380
|
+
message: "\u{1F50C} Enter your LangGraph endpoint URL:",
|
|
381
|
+
when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "Yes" && answers.langGraphPlatform === "No"
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
type: "select",
|
|
385
|
+
name: "langGraphAgent",
|
|
386
|
+
message: "\u{1F4E6} Choose a LangGraph starter template:",
|
|
387
|
+
choices: Array.from(LANGGRAPH_AGENTS),
|
|
388
|
+
when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "No"
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
type: "input",
|
|
392
|
+
name: "langSmithApiKey",
|
|
393
|
+
message: "\u{1F99C}\u{1F517} Enter your LangSmith API key (required by LangGraph Platform) :",
|
|
394
|
+
when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "No"
|
|
395
|
+
},
|
|
396
|
+
// Deployment options
|
|
397
|
+
{
|
|
398
|
+
type: "yes/no",
|
|
399
|
+
name: "useCopilotCloud",
|
|
400
|
+
message: "\u{1FA81} Deploy with Copilot Cloud? (recommended for production)",
|
|
401
|
+
when: (answers) => !(answers.agentFramework === "CrewAI" && answers.crewType === "Crews")
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
type: "yes/no",
|
|
405
|
+
name: "fastApiEnabled",
|
|
406
|
+
message: "\u26A1 Set up a FastAPI server for local development?",
|
|
407
|
+
when: (answers) => answers.agentFramework === "LangGraph" && answers.alreadyDeployed === "No" && answers.langGraphAgent === "Python Starter" && answers.useCopilotCloud !== "Yes"
|
|
408
|
+
},
|
|
409
|
+
// UI components - always shown last
|
|
410
|
+
{
|
|
411
|
+
type: "select",
|
|
412
|
+
name: "chatUi",
|
|
413
|
+
message: "\u{1F4AC} Select a UI component for your copilot:",
|
|
414
|
+
choices: Array.from(CHAT_COMPONENTS),
|
|
415
|
+
default: "CopilotChat"
|
|
416
|
+
}
|
|
417
|
+
];
|
|
418
|
+
|
|
419
|
+
// src/lib/init/scaffold/shadcn.ts
|
|
420
|
+
import spawn from "cross-spawn";
|
|
421
|
+
async function scaffoldShadCN(userAnswers) {
|
|
422
|
+
try {
|
|
423
|
+
const components = [
|
|
424
|
+
templateMapping[userAnswers.chatUi]
|
|
425
|
+
];
|
|
426
|
+
if (userAnswers.agentFramework !== "None") {
|
|
427
|
+
switch (userAnswers.agentFramework) {
|
|
428
|
+
case "LangGraph":
|
|
429
|
+
components.push(templateMapping.LangGraphPlatform);
|
|
430
|
+
break;
|
|
431
|
+
case "CrewAI":
|
|
432
|
+
if (userAnswers.crewType === "Crews") {
|
|
433
|
+
components.push(templateMapping.CrewEnterprise);
|
|
434
|
+
} else {
|
|
435
|
+
components.push(templateMapping.RemoteEndpoint);
|
|
436
|
+
}
|
|
437
|
+
break;
|
|
438
|
+
default:
|
|
439
|
+
components.push(templateMapping.RemoteEndpoint);
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
444
|
+
try {
|
|
445
|
+
const result = spawn.sync("npx", ["shadcn@latest", "add", ...components], {
|
|
446
|
+
stdio: "inherit"
|
|
447
|
+
// This ensures stdin/stdout/stderr are all passed through
|
|
448
|
+
});
|
|
449
|
+
if (result.status !== 0) {
|
|
450
|
+
throw new Error(`The shadcn installation process exited with code ${result.status}`);
|
|
451
|
+
}
|
|
452
|
+
} catch (error) {
|
|
453
|
+
throw error;
|
|
454
|
+
}
|
|
455
|
+
} catch (error) {
|
|
456
|
+
throw error;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// src/lib/init/scaffold/env.ts
|
|
461
|
+
import path from "path";
|
|
462
|
+
import fs from "fs";
|
|
463
|
+
import chalk3 from "chalk";
|
|
464
|
+
import ora2 from "ora";
|
|
465
|
+
async function scaffoldEnv(flags, userAnswers) {
|
|
466
|
+
const spinner = ora2({
|
|
467
|
+
text: chalk3.cyan("Configuring environment variables..."),
|
|
468
|
+
color: "cyan"
|
|
469
|
+
}).start();
|
|
470
|
+
try {
|
|
471
|
+
const envFile = path.join(process.cwd(), ".env");
|
|
472
|
+
if (!fs.existsSync(envFile)) {
|
|
473
|
+
fs.writeFileSync(envFile, "", "utf8");
|
|
474
|
+
spinner.text = chalk3.cyan("Created .env file...");
|
|
475
|
+
} else {
|
|
476
|
+
spinner.text = chalk3.cyan("Updating existing .env file...");
|
|
477
|
+
}
|
|
478
|
+
let newEnvValues = "";
|
|
479
|
+
let varsAdded = false;
|
|
480
|
+
if (userAnswers.copilotCloudPublicApiKey) {
|
|
481
|
+
newEnvValues += `NEXT_PUBLIC_COPILOT_API_KEY=${userAnswers.copilotCloudPublicApiKey}
|
|
482
|
+
`;
|
|
483
|
+
spinner.text = chalk3.cyan("Adding Copilot Cloud API key...");
|
|
484
|
+
varsAdded = true;
|
|
485
|
+
}
|
|
486
|
+
if (userAnswers.langSmithApiKey) {
|
|
487
|
+
newEnvValues += `LANG_SMITH_API_KEY=${userAnswers.langSmithApiKey}
|
|
488
|
+
`;
|
|
489
|
+
spinner.text = chalk3.cyan("Adding LangSmith API key...");
|
|
490
|
+
varsAdded = true;
|
|
491
|
+
}
|
|
492
|
+
if (userAnswers.llmToken) {
|
|
493
|
+
newEnvValues += `LLM_TOKEN=${userAnswers.llmToken}
|
|
494
|
+
`;
|
|
495
|
+
spinner.text = chalk3.cyan("Adding LLM token...");
|
|
496
|
+
varsAdded = true;
|
|
497
|
+
}
|
|
498
|
+
if (userAnswers.crewName) {
|
|
499
|
+
newEnvValues += `NEXT_PUBLIC_COPILOTKIT_AGENT_NAME=${userAnswers.crewName}
|
|
500
|
+
`;
|
|
501
|
+
spinner.text = chalk3.cyan("Adding Crew agent name...");
|
|
502
|
+
varsAdded = true;
|
|
503
|
+
}
|
|
504
|
+
if (flags.runtimeUrl) {
|
|
505
|
+
newEnvValues += `NEXT_PUBLIC_COPILOTKIT_RUNTIME_URL=${flags.runtimeUrl}
|
|
506
|
+
`;
|
|
507
|
+
spinner.text = chalk3.cyan("Adding runtime URL...");
|
|
508
|
+
varsAdded = true;
|
|
509
|
+
}
|
|
510
|
+
if (!varsAdded) {
|
|
511
|
+
spinner.text = chalk3.cyan("No environment variables needed...");
|
|
512
|
+
}
|
|
513
|
+
if (newEnvValues) {
|
|
514
|
+
fs.appendFileSync(envFile, newEnvValues);
|
|
515
|
+
spinner.succeed(chalk3("Environment variables configured successfully"));
|
|
516
|
+
} else {
|
|
517
|
+
spinner.info(chalk3.yellow("No environment variables were added"));
|
|
518
|
+
}
|
|
519
|
+
} catch (error) {
|
|
520
|
+
spinner.fail(chalk3.red("Failed to update environment variables"));
|
|
521
|
+
throw error;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// src/lib/init/scaffold/github.ts
|
|
526
|
+
import { execSync } from "child_process";
|
|
527
|
+
import * as fs2 from "fs";
|
|
528
|
+
import * as path2 from "path";
|
|
529
|
+
import * as os from "os";
|
|
530
|
+
import chalk4 from "chalk";
|
|
531
|
+
import ora3 from "ora";
|
|
532
|
+
async function scaffoldAgent(userAnswers) {
|
|
533
|
+
if (userAnswers.agentFramework === "None" || userAnswers.agentFramework === "CrewAI" && userAnswers.crewType === "Crews" || userAnswers.agentFramework === "LangGraph" && (!userAnswers.langGraphAgent || userAnswers.langGraphAgent === "None")) {
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
const spinner = ora3({
|
|
537
|
+
text: chalk4.cyan("Setting up AI agent..."),
|
|
538
|
+
color: "cyan"
|
|
539
|
+
}).start();
|
|
540
|
+
try {
|
|
541
|
+
if (userAnswers.agentFramework === "LangGraph") {
|
|
542
|
+
switch (userAnswers.langGraphAgent) {
|
|
543
|
+
case "Python Starter":
|
|
544
|
+
spinner.text = chalk4.cyan("Setting up Python LangGraph agent...");
|
|
545
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
546
|
+
await cloneGitHubSubdirectory(
|
|
547
|
+
"https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter/agent-py",
|
|
548
|
+
path2.join(process.cwd(), "agent"),
|
|
549
|
+
spinner
|
|
550
|
+
);
|
|
551
|
+
break;
|
|
552
|
+
case "TypeScript Starter":
|
|
553
|
+
spinner.text = chalk4.cyan("Setting up TypeScript LangGraph agent...");
|
|
554
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
555
|
+
await cloneGitHubSubdirectory(
|
|
556
|
+
"https://github.com/CopilotKit/CopilotKit/tree/main/examples/coagents-starter/agent-js",
|
|
557
|
+
path2.join(process.cwd(), "agent"),
|
|
558
|
+
spinner
|
|
559
|
+
);
|
|
560
|
+
break;
|
|
561
|
+
default:
|
|
562
|
+
break;
|
|
563
|
+
}
|
|
564
|
+
} else if (userAnswers.agentFramework === "CrewAI" && userAnswers.crewType === "Flows") {
|
|
565
|
+
spinner.text = chalk4.cyan("Setting up CrewAI Flows agent...");
|
|
566
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
567
|
+
spinner.info(chalk4.yellow("CrewAI Flows support is coming soon..."));
|
|
568
|
+
}
|
|
569
|
+
spinner.succeed(chalk4.green("AI agent setup complete"));
|
|
570
|
+
} catch (error) {
|
|
571
|
+
spinner.fail(chalk4.red("Failed to set up AI agent"));
|
|
572
|
+
throw error;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
async function cloneGitHubSubdirectory(githubUrl, destinationPath, spinner) {
|
|
576
|
+
try {
|
|
577
|
+
const { owner, repo, branch, subdirectoryPath } = parseGitHubUrl(githubUrl);
|
|
578
|
+
spinner.text = chalk4.cyan(`Cloning from ${owner}/${repo}...`);
|
|
579
|
+
return await sparseCheckout(owner, repo, branch, subdirectoryPath, destinationPath, spinner);
|
|
580
|
+
} catch (error) {
|
|
581
|
+
spinner.text = chalk4.red(`Failed to clone from GitHub: ${error}`);
|
|
582
|
+
return false;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
async function sparseCheckout(owner, repo, branch, subdirectoryPath, destinationPath, spinner) {
|
|
586
|
+
const tempDir = fs2.mkdtempSync(path2.join(os.tmpdir(), "copilotkit-sparse-"));
|
|
587
|
+
try {
|
|
588
|
+
spinner.text = chalk4.cyan("Creating temporary workspace...");
|
|
589
|
+
execSync("git init", { cwd: tempDir, stdio: "pipe" });
|
|
590
|
+
spinner.text = chalk4.cyan("Connecting to repository...");
|
|
591
|
+
execSync(`git remote add origin https://github.com/${owner}/${repo}.git`, { cwd: tempDir, stdio: "pipe" });
|
|
592
|
+
execSync("git config core.sparseCheckout true", { cwd: tempDir, stdio: "pipe" });
|
|
593
|
+
fs2.writeFileSync(path2.join(tempDir, ".git/info/sparse-checkout"), subdirectoryPath);
|
|
594
|
+
spinner.text = chalk4.cyan("Downloading agent files...");
|
|
595
|
+
execSync(`git pull origin ${branch} --depth=1`, { cwd: tempDir, stdio: "pipe" });
|
|
596
|
+
const sourcePath = path2.join(tempDir, subdirectoryPath);
|
|
597
|
+
if (!fs2.existsSync(sourcePath)) {
|
|
598
|
+
throw new Error(`Subdirectory '${subdirectoryPath}' not found in the repository.`);
|
|
599
|
+
}
|
|
600
|
+
fs2.mkdirSync(destinationPath, { recursive: true });
|
|
601
|
+
spinner.text = chalk4.cyan("Installing agent files...");
|
|
602
|
+
await copyDirectoryAsync(sourcePath, destinationPath);
|
|
603
|
+
return true;
|
|
604
|
+
} finally {
|
|
605
|
+
try {
|
|
606
|
+
fs2.rmSync(tempDir, { recursive: true, force: true });
|
|
607
|
+
} catch (error) {
|
|
608
|
+
console.warn(`Failed to clean up temporary directory: ${error}`);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
async function copyDirectoryAsync(source, destination) {
|
|
613
|
+
if (!fs2.existsSync(destination)) {
|
|
614
|
+
fs2.mkdirSync(destination, { recursive: true });
|
|
615
|
+
}
|
|
616
|
+
const entries = fs2.readdirSync(source, { withFileTypes: true });
|
|
617
|
+
for (const entry of entries) {
|
|
618
|
+
const srcPath = path2.join(source, entry.name);
|
|
619
|
+
const destPath = path2.join(destination, entry.name);
|
|
620
|
+
if (entry.isDirectory()) {
|
|
621
|
+
await copyDirectoryAsync(srcPath, destPath);
|
|
622
|
+
} else {
|
|
623
|
+
fs2.copyFileSync(srcPath, destPath);
|
|
624
|
+
}
|
|
625
|
+
if (entries.length > 10) {
|
|
626
|
+
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
function parseGitHubUrl(githubUrl) {
|
|
631
|
+
const url = new URL(githubUrl);
|
|
632
|
+
if (url.hostname !== "github.com") {
|
|
633
|
+
throw new Error("Only GitHub URLs are supported");
|
|
634
|
+
}
|
|
635
|
+
const pathParts = url.pathname.split("/").filter(Boolean);
|
|
636
|
+
if (pathParts.length < 2) {
|
|
637
|
+
throw new Error("Invalid GitHub URL format");
|
|
638
|
+
}
|
|
639
|
+
const owner = pathParts[0];
|
|
640
|
+
const repo = pathParts[1];
|
|
641
|
+
let branch = "main";
|
|
642
|
+
let subdirectoryPath = "";
|
|
643
|
+
if (pathParts.length > 3 && (pathParts[2] === "tree" || pathParts[2] === "blob")) {
|
|
644
|
+
branch = pathParts[3];
|
|
645
|
+
subdirectoryPath = pathParts.slice(4).join("/");
|
|
646
|
+
}
|
|
647
|
+
return { owner, repo, branch, subdirectoryPath };
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// src/lib/init/scaffold/packages.ts
|
|
651
|
+
import spawn2 from "cross-spawn";
|
|
652
|
+
import chalk5 from "chalk";
|
|
653
|
+
import ora4 from "ora";
|
|
654
|
+
|
|
655
|
+
// src/commands/init.ts
|
|
656
|
+
import chalk6 from "chalk";
|
|
657
|
+
import ora5 from "ora";
|
|
658
|
+
var CloudInit = class _CloudInit extends BaseCommand {
|
|
659
|
+
constructor(argv, config, authService = new AuthService()) {
|
|
660
|
+
super(argv, config);
|
|
661
|
+
this.authService = authService;
|
|
662
|
+
}
|
|
663
|
+
trpcClient = null;
|
|
664
|
+
static description = "Set up CopilotKit in your Next.js project";
|
|
665
|
+
static examples = [
|
|
666
|
+
"<%= config.bin %> init"
|
|
667
|
+
];
|
|
668
|
+
static flags = {
|
|
669
|
+
...BaseCommand.flags,
|
|
670
|
+
...ConfigFlags,
|
|
671
|
+
runtimeUrl: Flags2.string({ description: "runtime URL" }),
|
|
672
|
+
project: Flags2.string({ description: "project ID (can be found in the Copilot Cloud dashboard)" }),
|
|
673
|
+
dir: Flags2.string({ description: "directory of the Next.js project", default: "." })
|
|
674
|
+
};
|
|
675
|
+
async run() {
|
|
676
|
+
const { flags } = await this.parse(_CloudInit);
|
|
677
|
+
try {
|
|
678
|
+
this.log(chalk6.bold(chalk6.cyan("\n\u{1FA81} Welcome to CopilotKit")));
|
|
679
|
+
this.log(chalk6.gray("Let's power up your Next.js project with AI capabilities\n"));
|
|
680
|
+
this.validateProjectCompatibility(flags);
|
|
681
|
+
const userAnswers = await this.getUserAnswers();
|
|
682
|
+
const needsCloudSetup = userAnswers.useCopilotCloud === "Yes" || userAnswers.agentFramework === "CrewAI" && userAnswers.crewType === "Crews";
|
|
683
|
+
if (needsCloudSetup) {
|
|
684
|
+
await this.setupCloud(flags, userAnswers);
|
|
685
|
+
}
|
|
686
|
+
await scaffoldShadCN(userAnswers);
|
|
687
|
+
await scaffoldAgent(userAnswers);
|
|
688
|
+
await scaffoldEnv(flags, userAnswers);
|
|
689
|
+
this.finalSummary(userAnswers);
|
|
690
|
+
} catch (error) {
|
|
691
|
+
this.gracefulError(error.message);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
async getUserAnswers() {
|
|
695
|
+
const inquirerQuestions = questions.map((q) => {
|
|
696
|
+
const baseQuestion = {
|
|
697
|
+
name: q.name,
|
|
698
|
+
message: q.message,
|
|
699
|
+
when: q.when,
|
|
700
|
+
default: q.default
|
|
701
|
+
};
|
|
702
|
+
switch (q.type) {
|
|
703
|
+
case "yes/no":
|
|
704
|
+
return {
|
|
705
|
+
...baseQuestion,
|
|
706
|
+
type: "list",
|
|
707
|
+
choices: ["Yes", "No"]
|
|
708
|
+
};
|
|
709
|
+
case "select":
|
|
710
|
+
return {
|
|
711
|
+
...baseQuestion,
|
|
712
|
+
type: "list",
|
|
713
|
+
choices: q.choices
|
|
714
|
+
};
|
|
715
|
+
case "input":
|
|
716
|
+
default:
|
|
717
|
+
return {
|
|
718
|
+
...baseQuestion,
|
|
719
|
+
type: "input"
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
const answers = await inquirer2.prompt(inquirerQuestions);
|
|
724
|
+
return answers;
|
|
725
|
+
}
|
|
726
|
+
async setupCloud(flags, userAnswers) {
|
|
727
|
+
const spinner = ora5({
|
|
728
|
+
text: chalk6("\u{1F511} Authenticating for Copilot Cloud..."),
|
|
729
|
+
color: "cyan"
|
|
730
|
+
}).start();
|
|
731
|
+
const { cliToken, organization, user } = await this.authService.requireLogin(this);
|
|
732
|
+
const analytics = new AnalyticsService({ userId: user.id, organizationId: organization.id, email: user.email });
|
|
733
|
+
spinner.succeed(chalk6("\u{1F511} Authenticated for Copilot Cloud"));
|
|
734
|
+
await analytics.track({
|
|
735
|
+
event: "cli.init.cloud_used",
|
|
736
|
+
properties: { userId: user.id }
|
|
737
|
+
});
|
|
738
|
+
this.trpcClient = createTRPCClient(cliToken);
|
|
739
|
+
const availableProjects = await this.trpcClient.listOrgProjects.query({ orgId: organization.id });
|
|
740
|
+
let selectedProjectId;
|
|
741
|
+
if (flags.project) {
|
|
742
|
+
if (!availableProjects.some((project) => project.id === flags.project)) {
|
|
743
|
+
this.log(chalk6.red(`\u{1F4C1} Project with ID ${flags.project} not found`));
|
|
744
|
+
process.exit(1);
|
|
745
|
+
}
|
|
746
|
+
selectedProjectId = flags.project;
|
|
747
|
+
this.log(chalk6.green(`\u{1F4C1} Selected project ${selectedProjectId}`));
|
|
748
|
+
} else {
|
|
749
|
+
const { projectId } = await inquirer2.prompt([
|
|
750
|
+
{
|
|
751
|
+
name: "projectId",
|
|
752
|
+
type: "list",
|
|
753
|
+
message: "Choose a project:",
|
|
754
|
+
choices: availableProjects.map((project) => ({
|
|
755
|
+
value: project.id,
|
|
756
|
+
name: `${project.name} (ID: ${project.id})${availableProjects.length === 1 ? " (press Enter to confirm)" : ""}`
|
|
757
|
+
}))
|
|
758
|
+
}
|
|
759
|
+
]);
|
|
760
|
+
selectedProjectId = projectId;
|
|
761
|
+
}
|
|
762
|
+
const copilotCloudPublicApiKey = await this.trpcClient.getCopilotCloudPublicApiKey.query({ projectId: selectedProjectId });
|
|
763
|
+
userAnswers.copilotCloudPublicApiKey = copilotCloudPublicApiKey?.key;
|
|
764
|
+
if (userAnswers.crewUrl && userAnswers.crewName && userAnswers.crewBearerToken) {
|
|
765
|
+
const crewSpinner = ora5({
|
|
766
|
+
text: chalk6("\u{1F465} Adding Crew to Copilot Cloud..."),
|
|
767
|
+
color: "cyan"
|
|
768
|
+
}).start();
|
|
769
|
+
await this.trpcClient.createRemoteEndpoint.mutate({
|
|
770
|
+
type: "CrewAI",
|
|
771
|
+
projectId: selectedProjectId,
|
|
772
|
+
config: {
|
|
773
|
+
type: "CrewAI",
|
|
774
|
+
url: userAnswers.crewUrl,
|
|
775
|
+
agentName: userAnswers.crewName,
|
|
776
|
+
agentDescription: "A helpful Crew",
|
|
777
|
+
crewApiBearerToken: userAnswers.crewBearerToken
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
crewSpinner.succeed(chalk6("\u{1F465} Crew added to Copilot Cloud"));
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
validateProjectCompatibility(flags) {
|
|
784
|
+
const projectPath = path3.resolve(process.cwd(), flags.dir);
|
|
785
|
+
if (!fs3.existsSync(projectPath)) {
|
|
786
|
+
this.gracefulError(`Directory ${flags.dir} does not exist. Please provide a valid Next.js project directory.`);
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
const packageJsonPath = path3.join(projectPath, "package.json");
|
|
790
|
+
if (!fs3.existsSync(packageJsonPath)) {
|
|
791
|
+
this.gracefulError(`Directory ${projectPath} does not contain a package.json file. Please provide a valid Next.js project.`);
|
|
792
|
+
process.exit(1);
|
|
793
|
+
}
|
|
794
|
+
const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf8"));
|
|
795
|
+
if (!packageJson.dependencies?.next && !packageJson.devDependencies?.next) {
|
|
796
|
+
this.gracefulError(`Directory ${projectPath} does not appear to be a Next.js project. Make sure it has next in dependencies.`);
|
|
797
|
+
process.exit(1);
|
|
798
|
+
}
|
|
799
|
+
this.log(chalk6.green(`Valid Next.js project detected
|
|
800
|
+
`));
|
|
801
|
+
return true;
|
|
802
|
+
}
|
|
803
|
+
finalSummary(userAnswers) {
|
|
804
|
+
let agentDevInstructions = "";
|
|
805
|
+
let agentType = "";
|
|
806
|
+
let agentSetupMessage = "";
|
|
807
|
+
if (userAnswers.agentFramework !== "None") {
|
|
808
|
+
if (userAnswers.agentFramework === "LangGraph") {
|
|
809
|
+
agentType = "LangGraph agent";
|
|
810
|
+
if (userAnswers.alreadyDeployed === "Yes") {
|
|
811
|
+
agentSetupMessage = `Using your existing deployed agent.`;
|
|
812
|
+
} else if (userAnswers.langGraphAgent && userAnswers.langGraphAgent !== "None") {
|
|
813
|
+
agentSetupMessage = `We've scaffolded a ${chalk6.cyan(userAnswers.langGraphAgent)} agent in the ${chalk6.cyan("./agent")} directory.`;
|
|
814
|
+
if (userAnswers.langGraphAgent === "Python Starter") {
|
|
815
|
+
if (userAnswers.fastApiEnabled === "Yes") {
|
|
816
|
+
agentDevInstructions = "poetry install && poetry run demo";
|
|
817
|
+
} else {
|
|
818
|
+
agentDevInstructions = "npx @langchain/langgraph-cli dev --port 8123";
|
|
819
|
+
}
|
|
820
|
+
} else if (userAnswers.langGraphAgent === "TypeScript Starter") {
|
|
821
|
+
agentDevInstructions = "npm i && npm run dev";
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
} else if (userAnswers.agentFramework === "CrewAI") {
|
|
825
|
+
agentType = "CrewAI";
|
|
826
|
+
if (userAnswers.crewType === "Crews") {
|
|
827
|
+
agentSetupMessage = `Using your Crew from ${chalk6.cyan(userAnswers.crewUrl || "the provided URL")}.`;
|
|
828
|
+
} else if (userAnswers.crewType === "Flows") {
|
|
829
|
+
agentSetupMessage = "CrewAI Flows support is coming soon.";
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
this.log(chalk6.bold(chalk6.cyan("\n\u{1F389} Your CopilotKit setup is complete!\n")));
|
|
834
|
+
this.log(chalk6.bold("\u{1F4AC} User Interface:"));
|
|
835
|
+
this.log(chalk6.gray(`We've set up the ${chalk6.cyan(userAnswers.chatUi)} component in your Next.js app.`));
|
|
836
|
+
if (agentType) {
|
|
837
|
+
this.log(chalk6.bold(`
|
|
838
|
+
\u{1F916} ${agentType}:`));
|
|
839
|
+
this.log(chalk6.gray(agentSetupMessage));
|
|
840
|
+
}
|
|
841
|
+
this.log(chalk6.bold("\n\u{1F4CB} Next steps:"));
|
|
842
|
+
this.log(` ${chalk6.cyan("1.")} Start your Next.js app:`);
|
|
843
|
+
this.log(` ${chalk6.gray("$")} ${chalk6.yellow("npm run dev")}`);
|
|
844
|
+
if (agentDevInstructions) {
|
|
845
|
+
this.log(` ${chalk6.cyan("2.")} Start your agent:`);
|
|
846
|
+
this.log(` ${chalk6.gray("$")} ${chalk6.yellow(`cd agent && ${agentDevInstructions}`)}`);
|
|
847
|
+
}
|
|
848
|
+
this.log(chalk6.bold("\n\u{1F4DA} Documentation:"));
|
|
849
|
+
this.log(` ${chalk6.blue("https://docs.copilotkit.ai")}`);
|
|
850
|
+
this.log("");
|
|
851
|
+
}
|
|
852
|
+
};
|
|
853
|
+
export {
|
|
854
|
+
CloudInit as default
|
|
855
|
+
};
|
|
856
|
+
//# sourceMappingURL=init.js.map
|