@eyeglass/cli 0.1.6 → 0.1.8

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 (2) hide show
  1. package/dist/index.js +99 -20
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -554,25 +554,111 @@ function setupVite(configFile, dryRun) {
554
554
  }
555
555
  function setupNext(configFile, dryRun) {
556
556
  const cwd = process.cwd();
557
- const config = readFile(configFile);
557
+ // Check for App Router (app/ directory) vs Pages Router (pages/ directory)
558
+ const isAppRouter = fileExists(path.join(cwd, 'app')) || fileExists(path.join(cwd, 'src/app'));
559
+ if (isAppRouter) {
560
+ return setupNextAppRouter(cwd, dryRun);
561
+ }
562
+ else {
563
+ return setupNextPagesRouter(cwd, dryRun);
564
+ }
565
+ }
566
+ function setupNextAppRouter(cwd, dryRun) {
567
+ // For App Router, we need a client component wrapper since layout.tsx is a server component
568
+ const appDirs = ['app', 'src/app'];
569
+ let appDir = null;
570
+ for (const dir of appDirs) {
571
+ if (fileExists(path.join(cwd, dir))) {
572
+ appDir = path.join(cwd, dir);
573
+ break;
574
+ }
575
+ }
576
+ if (!appDir) {
577
+ log('Could not find app/ directory', 'warn');
578
+ return false;
579
+ }
580
+ // Create the client component wrapper
581
+ const providerPath = path.join(appDir, 'eyeglass-provider.tsx');
582
+ const providerContent = `'use client';
583
+
584
+ import { useEffect } from 'react';
585
+
586
+ export function EyeglassProvider({ children }: { children: React.ReactNode }) {
587
+ useEffect(() => {
588
+ import('@eyeglass/inspector');
589
+ }, []);
590
+
591
+ return <>{children}</>;
592
+ }
593
+ `;
594
+ if (fileExists(providerPath)) {
595
+ log('Eyeglass provider already exists', 'success');
596
+ }
597
+ else {
598
+ if (dryRun) {
599
+ log(`Would create ${path.relative(cwd, providerPath)}`);
600
+ }
601
+ else {
602
+ writeFile(providerPath, providerContent);
603
+ log(`Created ${path.relative(cwd, providerPath)}`, 'success');
604
+ }
605
+ }
606
+ // Find and update layout.tsx to include the provider
607
+ const layoutFiles = ['layout.tsx', 'layout.jsx'];
608
+ let layoutPath = null;
609
+ for (const file of layoutFiles) {
610
+ const fullPath = path.join(appDir, file);
611
+ if (fileExists(fullPath)) {
612
+ layoutPath = fullPath;
613
+ break;
614
+ }
615
+ }
616
+ if (!layoutPath) {
617
+ log('Could not find app/layout.tsx - please add <EyeglassProvider> manually', 'warn');
618
+ log('Import: import { EyeglassProvider } from "./eyeglass-provider"', 'info');
619
+ log('Wrap your {children} with <EyeglassProvider>{children}</EyeglassProvider>', 'info');
620
+ return false;
621
+ }
622
+ const layoutContent = readFile(layoutPath);
558
623
  // Check if already configured
559
- if (config.includes('@eyeglass/inspector')) {
560
- log('Next.js config already has eyeglass', 'success');
624
+ if (layoutContent.includes('EyeglassProvider') || layoutContent.includes('@eyeglass/inspector')) {
625
+ log('Layout already has Eyeglass configured', 'success');
561
626
  return true;
562
627
  }
563
- // For Next.js, we'll add the inspector import to the layout or _app file
564
- const layoutFiles = [
565
- 'app/layout.tsx',
566
- 'app/layout.jsx',
567
- 'src/app/layout.tsx',
568
- 'src/app/layout.jsx',
628
+ // Add import and wrap children with provider
629
+ const importStatement = `import { EyeglassProvider } from './eyeglass-provider';\n`;
630
+ // Find where to add import (after any existing imports or 'use client')
631
+ let newContent = layoutContent;
632
+ // Add import at the top
633
+ if (newContent.startsWith("'use client'") || newContent.startsWith('"use client"')) {
634
+ const firstLineEnd = newContent.indexOf('\n') + 1;
635
+ newContent = newContent.slice(0, firstLineEnd) + importStatement + newContent.slice(firstLineEnd);
636
+ }
637
+ else {
638
+ newContent = importStatement + newContent;
639
+ }
640
+ // Wrap {children} with <EyeglassProvider>
641
+ // Look for patterns like: {children} or { children }
642
+ newContent = newContent.replace(/(\{[\s]*children[\s]*\})/g, '<EyeglassProvider>$1</EyeglassProvider>');
643
+ if (dryRun) {
644
+ log(`Would update ${path.relative(cwd, layoutPath)} to include EyeglassProvider`);
645
+ }
646
+ else {
647
+ writeFile(layoutPath, newContent);
648
+ log(`Updated ${path.relative(cwd, layoutPath)} with EyeglassProvider`, 'success');
649
+ }
650
+ return true;
651
+ }
652
+ function setupNextPagesRouter(cwd, dryRun) {
653
+ // For Pages Router, we can import directly in _app.tsx
654
+ const appFiles = [
569
655
  'pages/_app.tsx',
570
656
  'pages/_app.jsx',
571
657
  'src/pages/_app.tsx',
572
658
  'src/pages/_app.jsx',
573
659
  ];
574
660
  let targetFile = null;
575
- for (const file of layoutFiles) {
661
+ for (const file of appFiles) {
576
662
  const fullPath = path.join(cwd, file);
577
663
  if (fileExists(fullPath)) {
578
664
  targetFile = fullPath;
@@ -580,7 +666,7 @@ function setupNext(configFile, dryRun) {
580
666
  }
581
667
  }
582
668
  if (!targetFile) {
583
- log('Could not find layout.tsx or _app.tsx - please import @eyeglass/inspector manually', 'warn');
669
+ log('Could not find pages/_app.tsx - please import @eyeglass/inspector manually', 'warn');
584
670
  return false;
585
671
  }
586
672
  const fileContent = readFile(targetFile);
@@ -589,16 +675,9 @@ function setupNext(configFile, dryRun) {
589
675
  log('Inspector already imported in ' + path.basename(targetFile), 'success');
590
676
  return true;
591
677
  }
592
- // Add import at the top (after 'use client' if present)
678
+ // Add import at the top
593
679
  const importStatement = `import '@eyeglass/inspector';\n`;
594
- let newContent;
595
- if (fileContent.startsWith("'use client'") || fileContent.startsWith('"use client"')) {
596
- const firstLineEnd = fileContent.indexOf('\n') + 1;
597
- newContent = fileContent.slice(0, firstLineEnd) + importStatement + fileContent.slice(firstLineEnd);
598
- }
599
- else {
600
- newContent = importStatement + fileContent;
601
- }
680
+ const newContent = importStatement + fileContent;
602
681
  if (dryRun) {
603
682
  log(`Would add inspector import to ${path.relative(cwd, targetFile)}`);
604
683
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eyeglass/cli",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Visual debugging for AI coding agents - CLI",
5
5
  "type": "module",
6
6
  "bin": {