@arcteninc/core 0.0.145 → 0.0.146
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/package.json +1 -1
- package/scripts/cli-init-wizard.ts +152 -34
- package/scripts/cli-sync.ts +13 -2
package/package.json
CHANGED
|
@@ -135,7 +135,12 @@ async function discoverContext(): Promise<InitContext> {
|
|
|
135
135
|
}
|
|
136
136
|
if (!envContent.includes('ARCTEN_API_KEY')) {
|
|
137
137
|
envContent += `\nARCTEN_API_KEY=${apiKeyInput}\n`;
|
|
138
|
-
|
|
138
|
+
// Use correct env prefix based on framework
|
|
139
|
+
if (framework === 'vite') {
|
|
140
|
+
envContent += `VITE_ARCTEN_API_URL=https://api.arcten.com\n`;
|
|
141
|
+
} else {
|
|
142
|
+
envContent += `NEXT_PUBLIC_ARCTEN_API_URL=https://api.arcten.com\n`;
|
|
143
|
+
}
|
|
139
144
|
fs.writeFileSync(envPath, envContent.trim() + '\n');
|
|
140
145
|
console.log(' Saved API key to .env.local');
|
|
141
146
|
}
|
|
@@ -429,15 +434,100 @@ export async function POST(req: NextRequest) {
|
|
|
429
434
|
fs.writeFileSync(path.join(tokenDir, 'route.ts'), tokenRouteContent);
|
|
430
435
|
createdFiles.push(`${appDir}/api/arcten/token/route.ts`);
|
|
431
436
|
console.log(` Created ${appDir}/api/arcten/token/route.ts`);
|
|
437
|
+
} else if (framework === 'vite') {
|
|
438
|
+
// Create Vite middleware plugin for token endpoint
|
|
439
|
+
const vitePluginContent = `// Arcten Token Plugin for Vite Dev Server
|
|
440
|
+
// This provides the /api/arcten/token endpoint during development
|
|
441
|
+
|
|
442
|
+
export function arctenTokenPlugin() {
|
|
443
|
+
return {
|
|
444
|
+
name: 'arcten-token',
|
|
445
|
+
configureServer(server: any) {
|
|
446
|
+
server.middlewares.use('/api/arcten/token', async (req: any, res: any, next: any) => {
|
|
447
|
+
if (req.method !== 'POST') {
|
|
448
|
+
return next();
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
let body = '';
|
|
452
|
+
req.on('data', (chunk: any) => body += chunk);
|
|
453
|
+
req.on('end', async () => {
|
|
454
|
+
try {
|
|
455
|
+
const { user } = JSON.parse(body || '{}');
|
|
456
|
+
const apiKey = process.env.ARCTEN_API_KEY;
|
|
457
|
+
|
|
458
|
+
if (!apiKey) {
|
|
459
|
+
res.statusCode = 500;
|
|
460
|
+
res.setHeader('Content-Type', 'application/json');
|
|
461
|
+
res.end(JSON.stringify({ error: 'ARCTEN_API_KEY not configured' }));
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Dynamic import to avoid bundling issues
|
|
466
|
+
const { verifyToken } = await import('@arcteninc/core/server');
|
|
467
|
+
const tokenResponse = await verifyToken({
|
|
468
|
+
apiKey,
|
|
469
|
+
user: user || { id: 'anonymous', name: 'User' },
|
|
470
|
+
apiUrl: process.env.VITE_ARCTEN_API_URL || 'https://api.arcten.com',
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
res.setHeader('Content-Type', 'application/json');
|
|
474
|
+
res.end(JSON.stringify(tokenResponse));
|
|
475
|
+
} catch (error: any) {
|
|
476
|
+
console.error('Token generation error:', error);
|
|
477
|
+
res.statusCode = 500;
|
|
478
|
+
res.setHeader('Content-Type', 'application/json');
|
|
479
|
+
res.end(JSON.stringify({ error: error.message || 'Failed to generate token' }));
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
},
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
`;
|
|
487
|
+
fs.writeFileSync(path.join(projectRoot, 'vite-plugin-arcten.ts'), vitePluginContent);
|
|
488
|
+
createdFiles.push('vite-plugin-arcten.ts');
|
|
489
|
+
console.log(' Created vite-plugin-arcten.ts');
|
|
490
|
+
|
|
491
|
+
// Update vite.config.ts to include the plugin
|
|
492
|
+
const viteConfigPath = path.join(projectRoot, 'vite.config.ts');
|
|
493
|
+
if (fs.existsSync(viteConfigPath)) {
|
|
494
|
+
let viteConfig = fs.readFileSync(viteConfigPath, 'utf-8');
|
|
495
|
+
|
|
496
|
+
if (!viteConfig.includes('arctenTokenPlugin')) {
|
|
497
|
+
// Add import at the top
|
|
498
|
+
if (viteConfig.includes("from 'vite'")) {
|
|
499
|
+
viteConfig = viteConfig.replace(
|
|
500
|
+
/from ['"]vite['"]/,
|
|
501
|
+
`from 'vite'\nimport { arctenTokenPlugin } from './vite-plugin-arcten'`
|
|
502
|
+
);
|
|
503
|
+
} else {
|
|
504
|
+
viteConfig = `import { arctenTokenPlugin } from './vite-plugin-arcten'\n` + viteConfig;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Add to plugins array
|
|
508
|
+
viteConfig = viteConfig.replace(
|
|
509
|
+
/plugins:\s*\[/,
|
|
510
|
+
'plugins: [arctenTokenPlugin(), '
|
|
511
|
+
);
|
|
512
|
+
|
|
513
|
+
fs.writeFileSync(viteConfigPath, viteConfig);
|
|
514
|
+
createdFiles.push('vite.config.ts (modified)');
|
|
515
|
+
console.log(' Modified vite.config.ts');
|
|
516
|
+
}
|
|
517
|
+
}
|
|
432
518
|
}
|
|
433
519
|
|
|
434
520
|
// 3. Create wrapper component based on placement
|
|
435
521
|
const toolsImportPath = path.relative(appDirPath, context.toolsFile).replace(/\.ts$/, '').replace(/\\/g, '/');
|
|
436
522
|
|
|
437
|
-
|
|
438
|
-
|
|
523
|
+
// Get the correct env variable syntax based on framework
|
|
524
|
+
const envVarSyntax = framework === 'vite'
|
|
525
|
+
? 'import.meta.env.VITE_ARCTEN_API_URL'
|
|
526
|
+
: 'process.env.NEXT_PUBLIC_ARCTEN_API_URL';
|
|
527
|
+
const useClientDirective = framework === 'vite' ? '' : '"use client";\n\n';
|
|
439
528
|
|
|
440
|
-
|
|
529
|
+
if (placement === 'everywhere') {
|
|
530
|
+
const wrapperContent = `${useClientDirective}import { ArctenAgent } from "@arcteninc/core";
|
|
441
531
|
import { toolMetadata } from "../.arcten/tool-metadata";
|
|
442
532
|
import { allTools, safeToolNames } from "../.arcten/arcten.tools";
|
|
443
533
|
|
|
@@ -452,7 +542,7 @@ export function ArctenWrapper({ children }: ArctenWrapperProps) {
|
|
|
452
542
|
{children}
|
|
453
543
|
</div>
|
|
454
544
|
<ArctenAgent
|
|
455
|
-
apiBaseUrl={
|
|
545
|
+
apiBaseUrl={${envVarSyntax} || "https://api.arcten.com"}
|
|
456
546
|
user={{ id: "user-1", name: "User" }}
|
|
457
547
|
tools={allTools}
|
|
458
548
|
safeToolNames={safeToolNames}
|
|
@@ -468,46 +558,74 @@ export default ArctenWrapper;
|
|
|
468
558
|
createdFiles.push(`${appDir}/ArctenWrapper.tsx`);
|
|
469
559
|
console.log(` Created ${appDir}/ArctenWrapper.tsx`);
|
|
470
560
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
561
|
+
if (framework === 'vite') {
|
|
562
|
+
// 4a. Modify main.tsx for Vite
|
|
563
|
+
const mainPath = path.join(projectRoot, 'src', 'main.tsx');
|
|
564
|
+
if (fs.existsSync(mainPath)) {
|
|
565
|
+
let mainContent = fs.readFileSync(mainPath, 'utf-8');
|
|
566
|
+
|
|
567
|
+
if (!mainContent.includes('ArctenWrapper')) {
|
|
568
|
+
// Add import after existing imports
|
|
569
|
+
const importStatement = `import { ArctenWrapper } from './ArctenWrapper'\n`;
|
|
570
|
+
const lastImportIndex = mainContent.lastIndexOf('import ');
|
|
571
|
+
if (lastImportIndex !== -1) {
|
|
572
|
+
const endOfImport = mainContent.indexOf('\n', lastImportIndex);
|
|
573
|
+
mainContent = mainContent.slice(0, endOfImport + 1) + importStatement + mainContent.slice(endOfImport + 1);
|
|
574
|
+
} else {
|
|
575
|
+
mainContent = importStatement + mainContent;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// Wrap <App /> with <ArctenWrapper>
|
|
579
|
+
mainContent = mainContent.replace(
|
|
580
|
+
/<App\s*\/>/,
|
|
581
|
+
'<ArctenWrapper><App /></ArctenWrapper>'
|
|
582
|
+
);
|
|
583
|
+
|
|
584
|
+
fs.writeFileSync(mainPath, mainContent);
|
|
585
|
+
createdFiles.push('src/main.tsx (modified)');
|
|
586
|
+
console.log(' Modified src/main.tsx');
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
} else {
|
|
590
|
+
// 4b. Modify layout.tsx for Next.js
|
|
591
|
+
const layoutPath = path.join(appDirPath, 'layout.tsx');
|
|
592
|
+
if (fs.existsSync(layoutPath)) {
|
|
593
|
+
let layoutContent = fs.readFileSync(layoutPath, 'utf-8');
|
|
594
|
+
|
|
595
|
+
// Add import if not present
|
|
596
|
+
if (!layoutContent.includes('ArctenWrapper')) {
|
|
597
|
+
// Add import at the top (after existing imports)
|
|
598
|
+
const importStatement = `import { ArctenWrapper } from "./ArctenWrapper";\n`;
|
|
599
|
+
const lastImportIndex = layoutContent.lastIndexOf('import ');
|
|
600
|
+
if (lastImportIndex !== -1) {
|
|
601
|
+
const endOfImport = layoutContent.indexOf('\n', lastImportIndex);
|
|
602
|
+
layoutContent = layoutContent.slice(0, endOfImport + 1) + importStatement + layoutContent.slice(endOfImport + 1);
|
|
603
|
+
} else {
|
|
604
|
+
layoutContent = importStatement + layoutContent;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// Wrap {children} with <ArctenWrapper>
|
|
608
|
+
layoutContent = layoutContent.replace(
|
|
609
|
+
/(\{children\})/,
|
|
610
|
+
'<ArctenWrapper>{children}</ArctenWrapper>'
|
|
611
|
+
);
|
|
612
|
+
|
|
613
|
+
fs.writeFileSync(layoutPath, layoutContent);
|
|
614
|
+
createdFiles.push(`${appDir}/layout.tsx (modified)`);
|
|
615
|
+
console.log(` Modified ${appDir}/layout.tsx`);
|
|
486
616
|
}
|
|
487
|
-
|
|
488
|
-
// Wrap {children} with <ArctenWrapper>
|
|
489
|
-
layoutContent = layoutContent.replace(
|
|
490
|
-
/(\{children\})/,
|
|
491
|
-
'<ArctenWrapper>{children}</ArctenWrapper>'
|
|
492
|
-
);
|
|
493
|
-
|
|
494
|
-
fs.writeFileSync(layoutPath, layoutContent);
|
|
495
|
-
createdFiles.push(`${appDir}/layout.tsx (modified)`);
|
|
496
|
-
console.log(` Modified ${appDir}/layout.tsx`);
|
|
497
617
|
}
|
|
498
618
|
}
|
|
499
619
|
} else if (placement === 'specific') {
|
|
500
620
|
// Create standalone component for specific pages
|
|
501
|
-
const componentContent =
|
|
502
|
-
|
|
503
|
-
import { ArctenAgent } from "@arcteninc/core";
|
|
621
|
+
const componentContent = `${useClientDirective}import { ArctenAgent } from "@arcteninc/core";
|
|
504
622
|
import { toolMetadata } from "../.arcten/tool-metadata";
|
|
505
623
|
import { allTools, safeToolNames } from "../.arcten/arcten.tools";
|
|
506
624
|
|
|
507
625
|
export function ArctenChat() {
|
|
508
626
|
return (
|
|
509
627
|
<ArctenAgent
|
|
510
|
-
apiBaseUrl={
|
|
628
|
+
apiBaseUrl={${envVarSyntax} || "https://api.arcten.com"}
|
|
511
629
|
user={{ id: "user-1", name: "User" }}
|
|
512
630
|
tools={allTools}
|
|
513
631
|
safeToolNames={safeToolNames}
|
package/scripts/cli-sync.ts
CHANGED
|
@@ -663,17 +663,28 @@ async function main() {
|
|
|
663
663
|
const scriptDir = path.dirname(new URL(import.meta.url).pathname).replace(/^\/([A-Z]:)/, '$1');
|
|
664
664
|
|
|
665
665
|
try {
|
|
666
|
+
// Read config to get tool file path
|
|
667
|
+
const configPath = path.join(projectRoot, '.arcten', 'config.ts');
|
|
668
|
+
let toolsArg = '';
|
|
669
|
+
if (fs.existsSync(configPath)) {
|
|
670
|
+
const configContent = fs.readFileSync(configPath, 'utf-8');
|
|
671
|
+
const toolFileMatch = configContent.match(/toolFile:\s*["']([^"']+)["']/);
|
|
672
|
+
if (toolFileMatch) {
|
|
673
|
+
toolsArg = ` --tools "${toolFileMatch[1]}"`;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
666
677
|
// Try running the wrapper script directly first
|
|
667
678
|
const extractScript = path.join(scriptDir, 'cli-extract-types-auto-wrapper.js');
|
|
668
679
|
if (fs.existsSync(extractScript)) {
|
|
669
|
-
execSync(`node "${extractScript}"`, {
|
|
680
|
+
execSync(`node "${extractScript}"${toolsArg}`, {
|
|
670
681
|
cwd: projectRoot,
|
|
671
682
|
stdio: options.quiet ? 'pipe' : ['inherit', 'pipe', 'pipe'],
|
|
672
683
|
});
|
|
673
684
|
if (!options.quiet) console.log(' Done');
|
|
674
685
|
} else {
|
|
675
686
|
// Fall back to npx
|
|
676
|
-
execSync(
|
|
687
|
+
execSync(`npx arcten-extract-types${toolsArg}`, {
|
|
677
688
|
cwd: projectRoot,
|
|
678
689
|
stdio: options.quiet ? 'pipe' : ['inherit', 'pipe', 'pipe'],
|
|
679
690
|
});
|