@agent-scope/cli 1.0.2 → 1.2.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.
package/dist/index.cjs CHANGED
@@ -8,6 +8,7 @@ var playwright = require('@agent-scope/playwright');
8
8
  var playwright$1 = require('playwright');
9
9
  var render = require('@agent-scope/render');
10
10
  var esbuild = require('esbuild');
11
+ var module$1 = require('module');
11
12
 
12
13
  function _interopNamespace(e) {
13
14
  if (e && e.__esModule) return e;
@@ -337,7 +338,7 @@ function writeReportToFile(report, outputPath, pretty) {
337
338
  const json = pretty ? JSON.stringify(report, null, 2) : JSON.stringify(report);
338
339
  fs.writeFileSync(outputPath, json, "utf-8");
339
340
  }
340
- async function buildComponentHarness(filePath, componentName, props, viewportWidth) {
341
+ async function buildComponentHarness(filePath, componentName, props, viewportWidth, projectCss) {
341
342
  const bundledScript = await bundleComponentToIIFE(filePath, componentName, props);
342
343
  return wrapInHtml(bundledScript, viewportWidth);
343
344
  }
@@ -425,7 +426,8 @@ ${msg}`);
425
426
  }
426
427
  return outputFile.text;
427
428
  }
428
- function wrapInHtml(bundledScript, viewportWidth) {
429
+ function wrapInHtml(bundledScript, viewportWidth, projectCss) {
430
+ const projectStyleBlock = "";
429
431
  return `<!DOCTYPE html>
430
432
  <html lang="en">
431
433
  <head>
@@ -436,6 +438,7 @@ function wrapInHtml(bundledScript, viewportWidth) {
436
438
  html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, sans-serif; }
437
439
  #scope-root { display: inline-block; min-width: 1px; min-height: 1px; }
438
440
  </style>
441
+ ${projectStyleBlock}
439
442
  </head>
440
443
  <body>
441
444
  <div id="scope-root" data-reactscope-root></div>
@@ -603,6 +606,121 @@ function csvEscape(value) {
603
606
  }
604
607
  return value;
605
608
  }
609
+ var CONFIG_FILENAMES = [
610
+ ".reactscope/config.json",
611
+ ".reactscope/config.js",
612
+ ".reactscope/config.mjs"
613
+ ];
614
+ var STYLE_ENTRY_CANDIDATES = [
615
+ "src/index.css",
616
+ "src/globals.css",
617
+ "app/globals.css",
618
+ "app/index.css",
619
+ "styles/index.css",
620
+ "index.css"
621
+ ];
622
+ var TAILWIND_IMPORT = /@import\s+["']tailwindcss["']\s*;?/;
623
+ var compilerCache = null;
624
+ function getCachedBuild(cwd) {
625
+ if (compilerCache !== null && path.resolve(compilerCache.cwd) === path.resolve(cwd)) {
626
+ return compilerCache.build;
627
+ }
628
+ return null;
629
+ }
630
+ function findStylesEntry(cwd) {
631
+ for (const name of CONFIG_FILENAMES) {
632
+ const p = path.resolve(cwd, name);
633
+ if (!fs.existsSync(p)) continue;
634
+ try {
635
+ if (name.endsWith(".json")) {
636
+ const raw = fs.readFileSync(p, "utf-8");
637
+ const data = JSON.parse(raw);
638
+ const scope = data.scope;
639
+ const entry = scope?.stylesEntry ?? data.stylesEntry;
640
+ if (typeof entry === "string") {
641
+ const full = path.resolve(cwd, entry);
642
+ if (fs.existsSync(full)) return full;
643
+ }
644
+ }
645
+ } catch {
646
+ }
647
+ }
648
+ const pkgPath = path.resolve(cwd, "package.json");
649
+ if (fs.existsSync(pkgPath)) {
650
+ try {
651
+ const raw = fs.readFileSync(pkgPath, "utf-8");
652
+ const pkg = JSON.parse(raw);
653
+ const entry = pkg.scope?.stylesEntry;
654
+ if (typeof entry === "string") {
655
+ const full = path.resolve(cwd, entry);
656
+ if (fs.existsSync(full)) return full;
657
+ }
658
+ } catch {
659
+ }
660
+ }
661
+ for (const candidate of STYLE_ENTRY_CANDIDATES) {
662
+ const full = path.resolve(cwd, candidate);
663
+ if (fs.existsSync(full)) {
664
+ try {
665
+ const content = fs.readFileSync(full, "utf-8");
666
+ if (TAILWIND_IMPORT.test(content)) return full;
667
+ } catch {
668
+ }
669
+ }
670
+ }
671
+ return null;
672
+ }
673
+ async function getTailwindCompiler(cwd) {
674
+ const cached = getCachedBuild(cwd);
675
+ if (cached !== null) return cached;
676
+ const entryPath = findStylesEntry(cwd);
677
+ if (entryPath === null) return null;
678
+ let compile;
679
+ try {
680
+ const require2 = module$1.createRequire(path.resolve(cwd, "package.json"));
681
+ const tailwind = require2("tailwindcss");
682
+ const fn = tailwind.compile;
683
+ if (typeof fn !== "function") return null;
684
+ compile = fn;
685
+ } catch {
686
+ return null;
687
+ }
688
+ const entryContent = fs.readFileSync(entryPath, "utf-8");
689
+ const loadStylesheet = async (id, base) => {
690
+ if (id === "tailwindcss") {
691
+ const nodeModules = path.resolve(cwd, "node_modules");
692
+ const tailwindCssPath = path.resolve(nodeModules, "tailwindcss", "index.css");
693
+ if (!fs.existsSync(tailwindCssPath)) {
694
+ throw new Error(
695
+ `Tailwind v4: tailwindcss package not found at ${tailwindCssPath}. Install with: npm install tailwindcss`
696
+ );
697
+ }
698
+ const content = fs.readFileSync(tailwindCssPath, "utf-8");
699
+ return { path: "virtual:tailwindcss/index.css", base, content };
700
+ }
701
+ const full = path.resolve(base, id);
702
+ if (fs.existsSync(full)) {
703
+ const content = fs.readFileSync(full, "utf-8");
704
+ return { path: full, base: path.resolve(full, ".."), content };
705
+ }
706
+ throw new Error(`Tailwind v4: could not load stylesheet: ${id} (base: ${base})`);
707
+ };
708
+ const result = await compile(entryContent, {
709
+ base: cwd,
710
+ from: entryPath,
711
+ loadStylesheet
712
+ });
713
+ const build2 = result.build.bind(result);
714
+ compilerCache = { cwd, build: build2 };
715
+ return build2;
716
+ }
717
+ async function getCompiledCssForClasses(cwd, classes) {
718
+ const build2 = await getTailwindCompiler(cwd);
719
+ if (build2 === null) return null;
720
+ const deduped = [...new Set(classes)].filter(Boolean);
721
+ if (deduped.length === 0) return null;
722
+ return build2(deduped);
723
+ }
606
724
 
607
725
  // src/render-commands.ts
608
726
  var MANIFEST_PATH2 = ".reactscope/manifest.json";
@@ -657,6 +775,20 @@ function buildRenderer(filePath, componentName, viewportWidth, viewportHeight) {
657
775
  if (renderError !== null) {
658
776
  throw new Error(`Component render error: ${renderError}`);
659
777
  }
778
+ const rootDir = process.cwd();
779
+ const classes = await page.evaluate(() => {
780
+ const set = /* @__PURE__ */ new Set();
781
+ document.querySelectorAll("[class]").forEach((el) => {
782
+ for (const c of el.className.split(/\s+/)) {
783
+ if (c) set.add(c);
784
+ }
785
+ });
786
+ return [...set];
787
+ });
788
+ const projectCss = await getCompiledCssForClasses(rootDir, classes);
789
+ if (projectCss != null && projectCss.length > 0) {
790
+ await page.addStyleTag({ content: projectCss });
791
+ }
660
792
  const renderTimeMs = performance.now() - startMs;
661
793
  const rootLocator = page.locator("[data-reactscope-root]");
662
794
  const boundingBox = await rootLocator.boundingBox();