@arcteninc/core 0.0.175 → 0.0.177
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 +73 -78
- package/dist/index.cjs +3 -16
- package/dist/index.d.ts +1 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +856 -8408
- package/dist/lib/useAgent.d.ts +1 -2
- package/dist/lib/useAgent.d.ts.map +1 -1
- package/dist/types/use-agent.d.ts +3 -44
- package/dist/types/use-agent.d.ts.map +1 -1
- package/dist/utils/extract-tool-metadata.d.ts.map +1 -1
- package/package.json +7 -46
- package/scripts/arcten-cli.cjs +14 -108
- package/scripts/cli-extract-types-auto.ts +22 -4
- package/scripts/update-core.cjs +124 -0
- package/dist/components/ArctenAgent.d.ts +0 -52
- package/dist/components/ArctenAgent.d.ts.map +0 -1
- package/dist/components/ai-elements/prompt-input.d.ts +0 -187
- package/dist/components/ai-elements/prompt-input.d.ts.map +0 -1
- package/dist/components/ai-elements/reasoning.d.ts +0 -17
- package/dist/components/ai-elements/reasoning.d.ts.map +0 -1
- package/dist/components/ai-elements/response.d.ts +0 -8
- package/dist/components/ai-elements/response.d.ts.map +0 -1
- package/dist/components/ai-elements/shimmer.d.ts +0 -10
- package/dist/components/ai-elements/shimmer.d.ts.map +0 -1
- package/dist/components/citation-button.d.ts +0 -14
- package/dist/components/citation-button.d.ts.map +0 -1
- package/dist/components/citation-text-renderer.d.ts +0 -31
- package/dist/components/citation-text-renderer.d.ts.map +0 -1
- package/dist/components/secure-modals/EmailModal.d.ts +0 -10
- package/dist/components/secure-modals/EmailModal.d.ts.map +0 -1
- package/dist/components/secure-modals/FormModal.d.ts +0 -20
- package/dist/components/secure-modals/FormModal.d.ts.map +0 -1
- package/dist/components/secure-modals/PasswordModal.d.ts +0 -10
- package/dist/components/secure-modals/PasswordModal.d.ts.map +0 -1
- package/dist/components/secure-modals/PhoneModal.d.ts +0 -10
- package/dist/components/secure-modals/PhoneModal.d.ts.map +0 -1
- package/dist/components/secure-modals/PinModal.d.ts +0 -11
- package/dist/components/secure-modals/PinModal.d.ts.map +0 -1
- package/dist/components/secure-modals/SecureModalProvider.d.ts +0 -13
- package/dist/components/secure-modals/SecureModalProvider.d.ts.map +0 -1
- package/dist/components/secure-modals/TextModal.d.ts +0 -11
- package/dist/components/secure-modals/TextModal.d.ts.map +0 -1
- package/dist/components/secure-modals/index.d.ts +0 -10
- package/dist/components/secure-modals/index.d.ts.map +0 -1
- package/dist/components/secure-modals/types.d.ts +0 -34
- package/dist/components/secure-modals/types.d.ts.map +0 -1
- package/dist/components/tool-call-approval.d.ts +0 -9
- package/dist/components/tool-call-approval.d.ts.map +0 -1
- package/dist/components/tool-call-result.d.ts +0 -8
- package/dist/components/tool-call-result.d.ts.map +0 -1
- package/dist/components/ui/autotextarea.d.ts +0 -19
- package/dist/components/ui/autotextarea.d.ts.map +0 -1
- package/dist/components/ui/badge.d.ts +0 -10
- package/dist/components/ui/badge.d.ts.map +0 -1
- package/dist/components/ui/button.d.ts +0 -14
- package/dist/components/ui/button.d.ts.map +0 -1
- package/dist/components/ui/collapsible.d.ts +0 -6
- package/dist/components/ui/collapsible.d.ts.map +0 -1
- package/dist/components/ui/command.d.ts +0 -19
- package/dist/components/ui/command.d.ts.map +0 -1
- package/dist/components/ui/dialog.d.ts +0 -16
- package/dist/components/ui/dialog.d.ts.map +0 -1
- package/dist/components/ui/dropdown-menu.d.ts +0 -26
- package/dist/components/ui/dropdown-menu.d.ts.map +0 -1
- package/dist/components/ui/hover-card.d.ts +0 -7
- package/dist/components/ui/hover-card.d.ts.map +0 -1
- package/dist/components/ui/input-group.d.ts +0 -17
- package/dist/components/ui/input-group.d.ts.map +0 -1
- package/dist/components/ui/input.d.ts +0 -4
- package/dist/components/ui/input.d.ts.map +0 -1
- package/dist/components/ui/kbd.d.ts +0 -4
- package/dist/components/ui/kbd.d.ts.map +0 -1
- package/dist/components/ui/select.d.ts +0 -16
- package/dist/components/ui/select.d.ts.map +0 -1
- package/dist/components/ui/textarea.d.ts +0 -4
- package/dist/components/ui/textarea.d.ts.map +0 -1
- package/dist/components/ui/tooltip.d.ts +0 -8
- package/dist/components/ui/tooltip.d.ts.map +0 -1
- package/dist/core.css +0 -1
- package/dist/utils/form-generator.d.ts +0 -29
- package/dist/utils/form-generator.d.ts.map +0 -1
- package/dist/utils/secure-param-detector.d.ts +0 -26
- package/dist/utils/secure-param-detector.d.ts.map +0 -1
- package/scripts/cli-agent-inject.ts +0 -205
- package/scripts/cli-agent-wrapper.cjs +0 -51
- package/scripts/cli-agent.ts +0 -483
- package/scripts/cli-create-project.ts +0 -608
- package/scripts/cli-create-wrapper.cjs +0 -60
- package/scripts/cli-init-wizard-wrapper.cjs +0 -58
- package/scripts/cli-init-wizard.ts +0 -646
- package/scripts/cli-prompt-wrapper.cjs +0 -51
- package/scripts/cli-prompt.ts +0 -306
- package/scripts/cli-sync-wrapper.cjs +0 -69
- package/scripts/cli-sync.ts +0 -915
- package/scripts/cli-tools-wrapper.cjs +0 -51
- package/scripts/cli-tools.ts +0 -320
- package/scripts/cli-uninstall-wrapper.cjs +0 -66
- package/scripts/cli-uninstall.ts +0 -173
- package/scripts/config-parser.ts +0 -432
- package/scripts/dashboard-sync.ts +0 -454
- package/scripts/tree-sitter-discover.ts +0 -526
- package/scripts/wasm/tree-sitter-tsx.wasm +0 -0
- package/scripts/wasm/tree-sitter-typescript.wasm +0 -0
|
@@ -1,608 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Arcten Create - Bootstrap new projects with AI agents
|
|
4
|
-
*
|
|
5
|
-
* Usage: arcten create [project-name]
|
|
6
|
-
*
|
|
7
|
-
* Creates a new Next.js project with Arcten pre-configured,
|
|
8
|
-
* including templates for common use cases.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import * as fs from 'fs';
|
|
12
|
-
import * as path from 'path';
|
|
13
|
-
import * as readline from 'readline';
|
|
14
|
-
import { execSync, spawn } from 'child_process';
|
|
15
|
-
|
|
16
|
-
// Types
|
|
17
|
-
interface TemplateConfig {
|
|
18
|
-
id: 'customer-support' | 'sales' | 'docs' | 'custom';
|
|
19
|
-
name: string;
|
|
20
|
-
description: string;
|
|
21
|
-
agentPrompt: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Template definitions
|
|
25
|
-
const TEMPLATES: TemplateConfig[] = [
|
|
26
|
-
{
|
|
27
|
-
id: 'customer-support',
|
|
28
|
-
name: 'Customer Support',
|
|
29
|
-
description: 'Help customers with orders, tickets, and FAQs',
|
|
30
|
-
agentPrompt: `You are a helpful customer support assistant. Be friendly, empathetic, and solution-oriented.
|
|
31
|
-
|
|
32
|
-
Guidelines:
|
|
33
|
-
- Always verify customer information before making changes
|
|
34
|
-
- Offer to create a support ticket if you cannot resolve an issue
|
|
35
|
-
- Be patient and thorough in your explanations
|
|
36
|
-
- Apologize for any inconvenience the customer has experienced`,
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
id: 'sales',
|
|
40
|
-
name: 'Sales Assistant',
|
|
41
|
-
description: 'Help with products, quotes, and inventory',
|
|
42
|
-
agentPrompt: `You are a knowledgeable sales assistant. Help customers find the right products and answer their questions.
|
|
43
|
-
|
|
44
|
-
Guidelines:
|
|
45
|
-
- Be helpful without being pushy
|
|
46
|
-
- Provide accurate product information
|
|
47
|
-
- Suggest alternatives when items are unavailable
|
|
48
|
-
- Focus on understanding customer needs before recommending products`,
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
id: 'docs',
|
|
52
|
-
name: 'Documentation Helper',
|
|
53
|
-
description: 'Search and explain your documentation',
|
|
54
|
-
agentPrompt: `You are a documentation assistant. Help users find information and understand the documentation.
|
|
55
|
-
|
|
56
|
-
Guidelines:
|
|
57
|
-
- Provide clear, concise explanations
|
|
58
|
-
- Reference specific documentation sections when possible
|
|
59
|
-
- Offer to clarify if the user seems confused
|
|
60
|
-
- Suggest related topics that might be helpful`,
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
id: 'custom',
|
|
64
|
-
name: 'Custom',
|
|
65
|
-
description: 'Start with a minimal example',
|
|
66
|
-
agentPrompt: 'You are a helpful assistant.',
|
|
67
|
-
},
|
|
68
|
-
];
|
|
69
|
-
|
|
70
|
-
// Helper: Create readline interface
|
|
71
|
-
function createPrompt(): readline.Interface {
|
|
72
|
-
return readline.createInterface({
|
|
73
|
-
input: process.stdin,
|
|
74
|
-
output: process.stdout,
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Helper: Ask a question
|
|
79
|
-
function ask(rl: readline.Interface, question: string): Promise<string> {
|
|
80
|
-
return new Promise((resolve) => {
|
|
81
|
-
rl.question(question, (answer) => {
|
|
82
|
-
resolve(answer.trim());
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Helper: Show progress
|
|
88
|
-
function showProgress(step: number, total: number, message: string): void {
|
|
89
|
-
const filled = Math.floor((step / total) * 20);
|
|
90
|
-
const bar = '='.repeat(filled) + '-'.repeat(20 - filled);
|
|
91
|
-
console.log(`\n[${bar}] Step ${step}/${total}: ${message}\n`);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Helper: Run command with output
|
|
95
|
-
function runCommand(command: string, cwd: string): Promise<void> {
|
|
96
|
-
return new Promise((resolve, reject) => {
|
|
97
|
-
const child = spawn(command, {
|
|
98
|
-
cwd,
|
|
99
|
-
shell: true,
|
|
100
|
-
stdio: 'inherit',
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
child.on('error', reject);
|
|
104
|
-
child.on('exit', (code) => {
|
|
105
|
-
if (code === 0) {
|
|
106
|
-
resolve();
|
|
107
|
-
} else {
|
|
108
|
-
reject(new Error(`Command failed with code ${code}`));
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Helper: Detect package manager
|
|
115
|
-
function detectPackageManager(): string {
|
|
116
|
-
if (fs.existsSync('bun.lockb')) return 'bun';
|
|
117
|
-
if (fs.existsSync('pnpm-lock.yaml')) return 'pnpm';
|
|
118
|
-
if (fs.existsSync('yarn.lock')) return 'yarn';
|
|
119
|
-
return 'npm';
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Helper: Open URL in browser
|
|
123
|
-
function openBrowser(url: string): void {
|
|
124
|
-
const command = process.platform === 'win32' ? 'start' :
|
|
125
|
-
process.platform === 'darwin' ? 'open' : 'xdg-open';
|
|
126
|
-
try {
|
|
127
|
-
execSync(`${command} "${url}"`, { stdio: 'ignore' });
|
|
128
|
-
} catch {
|
|
129
|
-
console.log(` Open in browser: ${url}`);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Generate tools file based on template
|
|
134
|
-
function generateToolsFile(template: TemplateConfig): string {
|
|
135
|
-
switch (template.id) {
|
|
136
|
-
case 'customer-support':
|
|
137
|
-
return `/**
|
|
138
|
-
* Customer Support Tools
|
|
139
|
-
* These functions will be available to your AI agent.
|
|
140
|
-
*/
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Look up an order by ID
|
|
144
|
-
* @param orderId - The order ID to look up
|
|
145
|
-
*/
|
|
146
|
-
export async function getOrderStatus(orderId: string) {
|
|
147
|
-
// TODO: Replace with your actual order lookup logic
|
|
148
|
-
return {
|
|
149
|
-
orderId,
|
|
150
|
-
status: "shipped",
|
|
151
|
-
trackingNumber: "1Z999AA10123456784",
|
|
152
|
-
estimatedDelivery: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Look up a customer by email
|
|
158
|
-
* @param email - Customer email address
|
|
159
|
-
*/
|
|
160
|
-
export async function lookupCustomer(email: string) {
|
|
161
|
-
// TODO: Replace with your actual customer lookup
|
|
162
|
-
return {
|
|
163
|
-
email,
|
|
164
|
-
name: "John Doe",
|
|
165
|
-
orders: 5,
|
|
166
|
-
memberSince: "2023-01-01",
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Create a support ticket
|
|
172
|
-
* @param subject - Ticket subject
|
|
173
|
-
* @param description - Detailed description of the issue
|
|
174
|
-
* @param priority - Ticket priority level
|
|
175
|
-
*/
|
|
176
|
-
export async function createTicket(
|
|
177
|
-
subject: string,
|
|
178
|
-
description: string,
|
|
179
|
-
priority: "low" | "medium" | "high" = "medium"
|
|
180
|
-
) {
|
|
181
|
-
// TODO: Replace with your ticketing system integration
|
|
182
|
-
return {
|
|
183
|
-
ticketId: \`TKT-\${Date.now()}\`,
|
|
184
|
-
subject,
|
|
185
|
-
priority,
|
|
186
|
-
status: "open",
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
`;
|
|
190
|
-
|
|
191
|
-
case 'sales':
|
|
192
|
-
return `/**
|
|
193
|
-
* Sales Tools
|
|
194
|
-
* These functions will be available to your AI agent.
|
|
195
|
-
*/
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Get product information
|
|
199
|
-
* @param productId - The product ID to look up
|
|
200
|
-
*/
|
|
201
|
-
export async function getProductInfo(productId: string) {
|
|
202
|
-
// TODO: Replace with your actual product lookup
|
|
203
|
-
return {
|
|
204
|
-
productId,
|
|
205
|
-
name: "Example Product",
|
|
206
|
-
price: 99.99,
|
|
207
|
-
inStock: true,
|
|
208
|
-
description: "A high-quality product for your needs.",
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Search for products
|
|
214
|
-
* @param query - Search query
|
|
215
|
-
* @param category - Optional category filter
|
|
216
|
-
*/
|
|
217
|
-
export async function searchProducts(query: string, category?: string) {
|
|
218
|
-
// TODO: Replace with your actual product search
|
|
219
|
-
return {
|
|
220
|
-
query,
|
|
221
|
-
category,
|
|
222
|
-
results: [
|
|
223
|
-
{ id: "prod-1", name: "Product 1", price: 49.99 },
|
|
224
|
-
{ id: "prod-2", name: "Product 2", price: 79.99 },
|
|
225
|
-
],
|
|
226
|
-
totalResults: 2,
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Check inventory levels
|
|
232
|
-
* @param productId - Product to check
|
|
233
|
-
*/
|
|
234
|
-
export async function checkInventory(productId: string) {
|
|
235
|
-
// TODO: Replace with your actual inventory check
|
|
236
|
-
return {
|
|
237
|
-
productId,
|
|
238
|
-
available: 150,
|
|
239
|
-
warehouse: "Main",
|
|
240
|
-
lastUpdated: new Date().toISOString(),
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Create a quote for a customer
|
|
246
|
-
* @param items - Array of product IDs and quantities
|
|
247
|
-
* @param customerEmail - Customer email for the quote
|
|
248
|
-
*/
|
|
249
|
-
export async function createQuote(
|
|
250
|
-
items: Array<{ productId: string; quantity: number }>,
|
|
251
|
-
customerEmail: string
|
|
252
|
-
) {
|
|
253
|
-
// TODO: Replace with your actual quote creation
|
|
254
|
-
return {
|
|
255
|
-
quoteId: \`QT-\${Date.now()}\`,
|
|
256
|
-
items,
|
|
257
|
-
customerEmail,
|
|
258
|
-
total: items.length * 50, // Placeholder calculation
|
|
259
|
-
validUntil: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
`;
|
|
263
|
-
|
|
264
|
-
case 'docs':
|
|
265
|
-
return `/**
|
|
266
|
-
* Documentation Tools
|
|
267
|
-
* These functions will be available to your AI agent.
|
|
268
|
-
*
|
|
269
|
-
* Note: For advanced documentation search, enable RAG in the dashboard
|
|
270
|
-
* to let the AI search through your actual documentation.
|
|
271
|
-
*/
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Search documentation
|
|
275
|
-
* @param query - Search query
|
|
276
|
-
*/
|
|
277
|
-
export async function searchDocs(query: string) {
|
|
278
|
-
// This is a placeholder - enable RAG in dashboard for real doc search
|
|
279
|
-
return {
|
|
280
|
-
query,
|
|
281
|
-
results: [
|
|
282
|
-
{
|
|
283
|
-
title: "Getting Started",
|
|
284
|
-
url: "/docs/getting-started",
|
|
285
|
-
excerpt: "Learn how to get started with our product...",
|
|
286
|
-
},
|
|
287
|
-
{
|
|
288
|
-
title: "API Reference",
|
|
289
|
-
url: "/docs/api",
|
|
290
|
-
excerpt: "Complete API documentation...",
|
|
291
|
-
},
|
|
292
|
-
],
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* Get a specific documentation page
|
|
298
|
-
* @param path - Documentation path
|
|
299
|
-
*/
|
|
300
|
-
export async function getDocPage(path: string) {
|
|
301
|
-
// TODO: Replace with your actual doc fetching
|
|
302
|
-
return {
|
|
303
|
-
path,
|
|
304
|
-
title: "Documentation Page",
|
|
305
|
-
content: "This is placeholder content. Connect to your CMS or documentation system.",
|
|
306
|
-
lastUpdated: new Date().toISOString(),
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
`;
|
|
310
|
-
|
|
311
|
-
case 'custom':
|
|
312
|
-
default:
|
|
313
|
-
return `/**
|
|
314
|
-
* Tools
|
|
315
|
-
* Add your functions here - they'll be available to your AI agent.
|
|
316
|
-
*
|
|
317
|
-
* Example:
|
|
318
|
-
*
|
|
319
|
-
* export async function myFunction(param: string) {
|
|
320
|
-
* // Your logic here
|
|
321
|
-
* return { result: "success" };
|
|
322
|
-
* }
|
|
323
|
-
*/
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Example tool - replace with your own
|
|
327
|
-
* @param name - A greeting name
|
|
328
|
-
*/
|
|
329
|
-
export async function greet(name: string) {
|
|
330
|
-
return {
|
|
331
|
-
message: \`Hello, \${name}! This is a placeholder tool.\`,
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
`;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// Generate chat page component
|
|
339
|
-
function generateChatPage(projectId: string, template: TemplateConfig): string {
|
|
340
|
-
return `"use client";
|
|
341
|
-
|
|
342
|
-
import { ArctenAgent } from "@arcteninc/core";
|
|
343
|
-
|
|
344
|
-
export default function ChatPage() {
|
|
345
|
-
return (
|
|
346
|
-
<main className="min-h-screen bg-stone-50">
|
|
347
|
-
<div className="max-w-4xl mx-auto p-4">
|
|
348
|
-
<h1 className="text-2xl font-bold text-stone-900 mb-4">
|
|
349
|
-
${template.name} Agent
|
|
350
|
-
</h1>
|
|
351
|
-
<ArctenAgent
|
|
352
|
-
projectId="${projectId}"
|
|
353
|
-
agentName="default"
|
|
354
|
-
/>
|
|
355
|
-
</div>
|
|
356
|
-
</main>
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
`;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
// Generate .env.local file
|
|
363
|
-
function generateEnvFile(apiKey: string): string {
|
|
364
|
-
return `# Arcten Configuration
|
|
365
|
-
# Generated by: arcten create
|
|
366
|
-
|
|
367
|
-
ARCTEN_API_KEY=${apiKey}
|
|
368
|
-
`;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
// Generate arcten config
|
|
372
|
-
function generateArctenConfig(projectId: string): string {
|
|
373
|
-
return `/**
|
|
374
|
-
* Arcten Configuration
|
|
375
|
-
* Generated by: arcten create
|
|
376
|
-
*/
|
|
377
|
-
|
|
378
|
-
export const arctenConfig = {
|
|
379
|
-
projectId: "${projectId}",
|
|
380
|
-
routes: [
|
|
381
|
-
{ pattern: "/*", agentName: "default" },
|
|
382
|
-
],
|
|
383
|
-
} as const;
|
|
384
|
-
`;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// Main create function
|
|
388
|
-
async function main() {
|
|
389
|
-
const args = process.argv.slice(2);
|
|
390
|
-
let projectName = args[0];
|
|
391
|
-
|
|
392
|
-
console.log('');
|
|
393
|
-
console.log('╔═══════════════════════════════════════════════╗');
|
|
394
|
-
console.log('║ ║');
|
|
395
|
-
console.log('║ 🚀 Arcten Create Project 🚀 ║');
|
|
396
|
-
console.log('║ ║');
|
|
397
|
-
console.log('╚═══════════════════════════════════════════════╝');
|
|
398
|
-
console.log('');
|
|
399
|
-
|
|
400
|
-
const rl = createPrompt();
|
|
401
|
-
|
|
402
|
-
try {
|
|
403
|
-
// Step 1: Get project name
|
|
404
|
-
showProgress(1, 5, 'Project setup');
|
|
405
|
-
|
|
406
|
-
if (!projectName) {
|
|
407
|
-
projectName = await ask(rl, '? Project name: ');
|
|
408
|
-
if (!projectName) {
|
|
409
|
-
console.error('❌ Project name is required');
|
|
410
|
-
process.exit(1);
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
// Validate project name
|
|
415
|
-
const projectDir = path.resolve(process.cwd(), projectName);
|
|
416
|
-
if (fs.existsSync(projectDir)) {
|
|
417
|
-
console.error(`❌ Directory "${projectName}" already exists`);
|
|
418
|
-
process.exit(1);
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
console.log(`\n Creating project: ${projectName}\n`);
|
|
422
|
-
|
|
423
|
-
// Step 2: Template selection
|
|
424
|
-
showProgress(2, 5, 'Choose template');
|
|
425
|
-
|
|
426
|
-
console.log('Select a template:\n');
|
|
427
|
-
TEMPLATES.forEach((t, i) => {
|
|
428
|
-
console.log(` ${i + 1}. ${t.name}`);
|
|
429
|
-
console.log(` ${t.description}\n`);
|
|
430
|
-
});
|
|
431
|
-
|
|
432
|
-
const templateChoice = await ask(rl, '? Enter number (1-4): ');
|
|
433
|
-
const templateIndex = parseInt(templateChoice, 10) - 1;
|
|
434
|
-
const template = TEMPLATES[templateIndex] || TEMPLATES[3]; // Default to custom
|
|
435
|
-
|
|
436
|
-
console.log(`\n Selected: ${template.name}\n`);
|
|
437
|
-
|
|
438
|
-
// Step 3: API Key
|
|
439
|
-
showProgress(3, 5, 'Authentication');
|
|
440
|
-
|
|
441
|
-
let apiKey = '';
|
|
442
|
-
let projectId = '';
|
|
443
|
-
|
|
444
|
-
// Check if API key exists in environment
|
|
445
|
-
const envLocalPath = path.join(process.cwd(), '.env.local');
|
|
446
|
-
const envPath = path.join(process.cwd(), '.env');
|
|
447
|
-
|
|
448
|
-
if (fs.existsSync(envLocalPath)) {
|
|
449
|
-
const content = fs.readFileSync(envLocalPath, 'utf-8');
|
|
450
|
-
const match = content.match(/ARCTEN_API_KEY=([^\s\n]+)/);
|
|
451
|
-
if (match) {
|
|
452
|
-
apiKey = match[1];
|
|
453
|
-
console.log(' Found existing API key in .env.local');
|
|
454
|
-
}
|
|
455
|
-
} else if (fs.existsSync(envPath)) {
|
|
456
|
-
const content = fs.readFileSync(envPath, 'utf-8');
|
|
457
|
-
const match = content.match(/ARCTEN_API_KEY=([^\s\n]+)/);
|
|
458
|
-
if (match) {
|
|
459
|
-
apiKey = match[1];
|
|
460
|
-
console.log(' Found existing API key in .env');
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
if (!apiKey) {
|
|
465
|
-
console.log(' No API key found.\n');
|
|
466
|
-
console.log(' Options:');
|
|
467
|
-
console.log(' 1. Enter your API key');
|
|
468
|
-
console.log(' 2. Open dashboard to create one\n');
|
|
469
|
-
|
|
470
|
-
const keyChoice = await ask(rl, '? Choose (1 or 2): ');
|
|
471
|
-
|
|
472
|
-
if (keyChoice === '2') {
|
|
473
|
-
console.log('\n Opening dashboard...');
|
|
474
|
-
openBrowser('https://arcten.com/dashboard?action=create-project');
|
|
475
|
-
console.log('');
|
|
476
|
-
apiKey = await ask(rl, '? Paste your API key: ');
|
|
477
|
-
} else {
|
|
478
|
-
apiKey = await ask(rl, '? Enter your API key: ');
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
if (!apiKey) {
|
|
482
|
-
console.error('❌ API key is required');
|
|
483
|
-
process.exit(1);
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// Extract project ID from API key
|
|
488
|
-
const projectIdMatch = apiKey.match(/sk_(proj_[a-zA-Z0-9]+)_/);
|
|
489
|
-
if (!projectIdMatch) {
|
|
490
|
-
console.error('');
|
|
491
|
-
console.error('┌─────────────────────────────────────────────────┐');
|
|
492
|
-
console.error('│ ❌ Invalid API Key Format │');
|
|
493
|
-
console.error('├─────────────────────────────────────────────────┤');
|
|
494
|
-
console.error('│ Expected format: sk_proj_xxxxx_yyyyy │');
|
|
495
|
-
console.error('│ │');
|
|
496
|
-
console.error('│ Get your API key at: │');
|
|
497
|
-
console.error('│ https://arcten.com/dashboard │');
|
|
498
|
-
console.error('└─────────────────────────────────────────────────┘');
|
|
499
|
-
console.error('');
|
|
500
|
-
process.exit(1);
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
projectId = projectIdMatch[1];
|
|
504
|
-
console.log(` Project ID: ${projectId}`);
|
|
505
|
-
|
|
506
|
-
// Step 4: Create project
|
|
507
|
-
showProgress(4, 5, 'Creating project');
|
|
508
|
-
|
|
509
|
-
console.log(' Running create-next-app...\n');
|
|
510
|
-
|
|
511
|
-
// Detect best package manager to use
|
|
512
|
-
const pm = detectPackageManager();
|
|
513
|
-
const createCommand = pm === 'bun'
|
|
514
|
-
? `bunx create-next-app@latest ${projectName} --typescript --tailwind --eslint --app --src-dir --import-alias "@/*" --use-bun`
|
|
515
|
-
: pm === 'pnpm'
|
|
516
|
-
? `pnpm create next-app@latest ${projectName} --typescript --tailwind --eslint --app --src-dir --import-alias "@/*" --use-pnpm`
|
|
517
|
-
: `npx create-next-app@latest ${projectName} --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"`;
|
|
518
|
-
|
|
519
|
-
try {
|
|
520
|
-
await runCommand(createCommand, process.cwd());
|
|
521
|
-
} catch (error) {
|
|
522
|
-
console.error('❌ Failed to create Next.js project');
|
|
523
|
-
process.exit(1);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
// Step 5: Configure project
|
|
527
|
-
showProgress(5, 5, 'Configuring project');
|
|
528
|
-
|
|
529
|
-
// Install @arcteninc/core
|
|
530
|
-
console.log(' Installing @arcteninc/core...');
|
|
531
|
-
const installCommand = pm === 'bun' ? 'bun add @arcteninc/core' :
|
|
532
|
-
pm === 'pnpm' ? 'pnpm add @arcteninc/core' :
|
|
533
|
-
pm === 'yarn' ? 'yarn add @arcteninc/core' :
|
|
534
|
-
'npm install @arcteninc/core';
|
|
535
|
-
|
|
536
|
-
try {
|
|
537
|
-
await runCommand(installCommand, projectDir);
|
|
538
|
-
} catch (error) {
|
|
539
|
-
console.warn(' ⚠️ Could not install @arcteninc/core automatically');
|
|
540
|
-
console.warn(` Run: cd ${projectName} && ${installCommand}`);
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
// Create .env.local
|
|
544
|
-
const envContent = generateEnvFile(apiKey);
|
|
545
|
-
fs.writeFileSync(path.join(projectDir, '.env.local'), envContent);
|
|
546
|
-
console.log(' Created .env.local');
|
|
547
|
-
|
|
548
|
-
// Create .arcten directory
|
|
549
|
-
const arctenDir = path.join(projectDir, '.arcten');
|
|
550
|
-
fs.mkdirSync(arctenDir, { recursive: true });
|
|
551
|
-
|
|
552
|
-
// Create .arcten/config.ts
|
|
553
|
-
const configContent = generateArctenConfig(projectId);
|
|
554
|
-
fs.writeFileSync(path.join(arctenDir, 'config.ts'), configContent);
|
|
555
|
-
console.log(' Created .arcten/config.ts');
|
|
556
|
-
|
|
557
|
-
// Create src/tools.ts
|
|
558
|
-
const toolsContent = generateToolsFile(template);
|
|
559
|
-
fs.writeFileSync(path.join(projectDir, 'src', 'tools.ts'), toolsContent);
|
|
560
|
-
console.log(' Created src/tools.ts');
|
|
561
|
-
|
|
562
|
-
// Create src/app/chat/page.tsx
|
|
563
|
-
const chatDir = path.join(projectDir, 'src', 'app', 'chat');
|
|
564
|
-
fs.mkdirSync(chatDir, { recursive: true });
|
|
565
|
-
const chatPageContent = generateChatPage(projectId, template);
|
|
566
|
-
fs.writeFileSync(path.join(chatDir, 'page.tsx'), chatPageContent);
|
|
567
|
-
console.log(' Created src/app/chat/page.tsx');
|
|
568
|
-
|
|
569
|
-
// Success!
|
|
570
|
-
console.log('');
|
|
571
|
-
console.log('╔═══════════════════════════════════════════════╗');
|
|
572
|
-
console.log('║ ║');
|
|
573
|
-
console.log('║ ✅ Project Created! ║');
|
|
574
|
-
console.log('║ ║');
|
|
575
|
-
console.log('╚═══════════════════════════════════════════════╝');
|
|
576
|
-
console.log('');
|
|
577
|
-
console.log('Next steps:');
|
|
578
|
-
console.log('');
|
|
579
|
-
console.log(` cd ${projectName}`);
|
|
580
|
-
console.log(` ${pm === 'bun' ? 'bun' : pm} run dev`);
|
|
581
|
-
console.log('');
|
|
582
|
-
console.log('Your AI agent is ready at:');
|
|
583
|
-
console.log(' http://localhost:3000/chat');
|
|
584
|
-
console.log('');
|
|
585
|
-
console.log('Dashboard:');
|
|
586
|
-
console.log(` https://arcten.com/dashboard/projects/${projectId}`);
|
|
587
|
-
console.log('');
|
|
588
|
-
console.log('To sync your tools to the dashboard:');
|
|
589
|
-
console.log(' arcten sync --tools ./src/tools.ts');
|
|
590
|
-
console.log('');
|
|
591
|
-
|
|
592
|
-
} catch (error: any) {
|
|
593
|
-
console.error('\n❌ Error:', error.message);
|
|
594
|
-
process.exit(1);
|
|
595
|
-
} finally {
|
|
596
|
-
rl.close();
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
// Run if executed directly
|
|
601
|
-
if (require.main === module) {
|
|
602
|
-
main().catch((error) => {
|
|
603
|
-
console.error('Fatal error:', error);
|
|
604
|
-
process.exit(1);
|
|
605
|
-
});
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
export { main };
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Wrapper script to execute cli-create-project.ts
|
|
4
|
-
* Tries to use bun/tsx for TypeScript execution
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const { spawn } = require('child_process');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const fs = require('fs');
|
|
10
|
-
|
|
11
|
-
const scriptPath = path.join(__dirname, 'cli-create-project.ts');
|
|
12
|
-
|
|
13
|
-
if (!fs.existsSync(scriptPath)) {
|
|
14
|
-
console.error(`❌ Script not found: ${scriptPath}`);
|
|
15
|
-
process.exit(1);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Pass through command line args
|
|
19
|
-
const args = process.argv.slice(2);
|
|
20
|
-
|
|
21
|
-
// Try bun first (fastest), then tsx, then ts-node
|
|
22
|
-
const runners = [
|
|
23
|
-
{ cmd: 'bun', args: [scriptPath, ...args] },
|
|
24
|
-
{ cmd: 'tsx', args: [scriptPath, ...args] },
|
|
25
|
-
{ cmd: 'ts-node', args: [scriptPath, ...args] },
|
|
26
|
-
{ cmd: 'node', args: ['--loader', 'ts-node/esm', scriptPath, ...args] },
|
|
27
|
-
];
|
|
28
|
-
|
|
29
|
-
function tryRunner(index) {
|
|
30
|
-
if (index >= runners.length) {
|
|
31
|
-
console.error('❌ No TypeScript runner found. Please install one:');
|
|
32
|
-
console.error(' bun: https://bun.sh');
|
|
33
|
-
console.error(' tsx: npm install -g tsx');
|
|
34
|
-
console.error(' ts-node: npm install -g ts-node');
|
|
35
|
-
process.exit(1);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const runner = runners[index];
|
|
39
|
-
const child = spawn(runner.cmd, runner.args, {
|
|
40
|
-
stdio: 'inherit',
|
|
41
|
-
cwd: process.cwd(),
|
|
42
|
-
shell: true,
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
child.on('error', (error) => {
|
|
46
|
-
if (error.code === 'ENOENT') {
|
|
47
|
-
// Runner not found, try next one
|
|
48
|
-
tryRunner(index + 1);
|
|
49
|
-
} else {
|
|
50
|
-
console.error(`❌ Error running ${runner.cmd}:`, error.message);
|
|
51
|
-
process.exit(1);
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
child.on('exit', (code) => {
|
|
56
|
-
process.exit(code || 0);
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
tryRunner(0);
|