@agent-scope/cli 1.11.0 → 1.12.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/cli.js CHANGED
@@ -3,7 +3,7 @@
3
3
  // src/program.ts
4
4
  import { readFileSync as readFileSync7 } from "fs";
5
5
  import { generateTest, loadTrace } from "@agent-scope/playwright";
6
- import { Command as Command7 } from "commander";
6
+ import { Command as Command8 } from "commander";
7
7
 
8
8
  // src/browser.ts
9
9
  import { writeFileSync } from "fs";
@@ -255,9 +255,9 @@ function createRL() {
255
255
  });
256
256
  }
257
257
  async function ask(rl, question) {
258
- return new Promise((resolve10) => {
258
+ return new Promise((resolve11) => {
259
259
  rl.question(question, (answer) => {
260
- resolve10(answer.trim());
260
+ resolve11(answer.trim());
261
261
  });
262
262
  });
263
263
  }
@@ -406,9 +406,9 @@ function createInitCommand() {
406
406
  }
407
407
 
408
408
  // src/instrument/renders.ts
409
- import { resolve as resolve4 } from "path";
410
- import { BrowserPool } from "@agent-scope/render";
411
- import { Command as Command3 } from "commander";
409
+ import { resolve as resolve5 } from "path";
410
+ import { BrowserPool as BrowserPool2 } from "@agent-scope/render";
411
+ import { Command as Command4 } from "commander";
412
412
 
413
413
  // src/component-bundler.ts
414
414
  import { dirname } from "path";
@@ -1602,8 +1602,371 @@ Available: ${available}`
1602
1602
  return cmd;
1603
1603
  }
1604
1604
 
1605
- // src/instrument/renders.ts
1605
+ // src/instrument/tree.ts
1606
+ import { resolve as resolve4 } from "path";
1607
+ import { getBrowserEntryScript as getBrowserEntryScript2 } from "@agent-scope/playwright";
1608
+ import { BrowserPool } from "@agent-scope/render";
1609
+ import { Command as Command3 } from "commander";
1606
1610
  var MANIFEST_PATH4 = ".reactscope/manifest.json";
1611
+ var DEFAULT_VIEWPORT_WIDTH = 375;
1612
+ var DEFAULT_VIEWPORT_HEIGHT = 812;
1613
+ var _pool = null;
1614
+ async function getPool() {
1615
+ if (_pool === null) {
1616
+ _pool = new BrowserPool({
1617
+ size: { browsers: 1, pagesPerBrowser: 1 },
1618
+ viewportWidth: DEFAULT_VIEWPORT_WIDTH,
1619
+ viewportHeight: DEFAULT_VIEWPORT_HEIGHT
1620
+ });
1621
+ await _pool.init();
1622
+ }
1623
+ return _pool;
1624
+ }
1625
+ async function shutdownPool() {
1626
+ if (_pool !== null) {
1627
+ await _pool.close();
1628
+ _pool = null;
1629
+ }
1630
+ }
1631
+ function mapNodeType(node) {
1632
+ if (node.type === "forward_ref") return "forwardRef";
1633
+ if (node.type === "host") return "host";
1634
+ const name = node.name;
1635
+ if (name.endsWith(".Provider") || name === "Provider") return "context.provider";
1636
+ if (name.endsWith(".Consumer") || name === "Consumer") return "context.consumer";
1637
+ return node.type;
1638
+ }
1639
+ function flattenSerializedValue(sv) {
1640
+ if (sv === null || sv === void 0) return null;
1641
+ const v = sv;
1642
+ switch (v.type) {
1643
+ case "null":
1644
+ case "undefined":
1645
+ return null;
1646
+ case "string":
1647
+ case "number":
1648
+ case "boolean":
1649
+ return v.value;
1650
+ case "object": {
1651
+ if (!Array.isArray(v.entries)) return {};
1652
+ const result = {};
1653
+ for (const entry of v.entries) {
1654
+ result[entry.key] = flattenSerializedValue(entry.value);
1655
+ }
1656
+ return result;
1657
+ }
1658
+ case "array": {
1659
+ if (!Array.isArray(v.items)) return [];
1660
+ return v.items.map(flattenSerializedValue);
1661
+ }
1662
+ case "function":
1663
+ return "[Function]";
1664
+ case "symbol":
1665
+ return `[Symbol: ${v.description ?? ""}]`;
1666
+ case "circular":
1667
+ return "[Circular]";
1668
+ case "truncated":
1669
+ return `[Truncated: ${v.preview ?? ""}]`;
1670
+ default:
1671
+ return v.preview ?? null;
1672
+ }
1673
+ }
1674
+ function flattenHookState(hooks) {
1675
+ const result = {};
1676
+ for (let i = 0; i < hooks.length; i++) {
1677
+ const hook = hooks[i];
1678
+ if (hook === void 0) continue;
1679
+ const key = hook.name !== null && hook.name !== void 0 ? hook.name : `${hook.type}[${i}]`;
1680
+ result[key] = flattenSerializedValue(hook.value);
1681
+ }
1682
+ return result;
1683
+ }
1684
+ function extractContextNames(contexts) {
1685
+ const names = contexts.map((c) => c.contextName ?? "Unknown").filter((name, idx, arr) => arr.indexOf(name) === idx);
1686
+ return names;
1687
+ }
1688
+ function anyContextChanged(contexts) {
1689
+ return contexts.some((c) => c.didTriggerRender);
1690
+ }
1691
+ function convertToInstrumentNode(node, depth = 0) {
1692
+ const contexts = extractContextNames(node.context);
1693
+ const contextChanged = anyContextChanged(node.context);
1694
+ const state = flattenHookState(node.state);
1695
+ const propsFlat = flattenSerializedValue(node.props);
1696
+ const props = propsFlat !== null && typeof propsFlat === "object" && !Array.isArray(propsFlat) ? propsFlat : {};
1697
+ return {
1698
+ component: node.name,
1699
+ type: mapNodeType(node),
1700
+ renderCount: node.renderCount,
1701
+ lastRenderDuration: node.renderDuration,
1702
+ memoized: node.type === "memo",
1703
+ // memoSkipped requires tracking bail-outs across commits — not available from
1704
+ // a single-shot capture. Defaulted to 0.
1705
+ memoSkipped: 0,
1706
+ props,
1707
+ // propsChanged is not tracked in a single-shot capture — would need a diff
1708
+ // between two renders. Defaulted to false.
1709
+ propsChanged: false,
1710
+ state,
1711
+ stateChanged: false,
1712
+ contextChanged,
1713
+ contexts,
1714
+ depth,
1715
+ children: node.children.map((child) => convertToInstrumentNode(child, depth + 1))
1716
+ };
1717
+ }
1718
+ function filterByContext(node, contextName) {
1719
+ const filteredChildren = node.children.map((child) => filterByContext(child, contextName)).filter((c) => c !== null);
1720
+ const selfMatches = node.contexts.some((c) => c.toLowerCase() === contextName.toLowerCase());
1721
+ if (!selfMatches && filteredChildren.length === 0) return null;
1722
+ return { ...node, children: filteredChildren };
1723
+ }
1724
+ function filterWastedRenders(node) {
1725
+ const filteredChildren = node.children.map((child) => filterWastedRenders(child)).filter((c) => c !== null);
1726
+ const isWasted = !node.propsChanged && !node.stateChanged && !node.contextChanged && !node.memoized && node.renderCount > 1;
1727
+ if (!isWasted && filteredChildren.length === 0) return null;
1728
+ return { ...node, children: filteredChildren };
1729
+ }
1730
+ function sortTree(node, sortBy) {
1731
+ const sortedChildren = node.children.map((child) => sortTree(child, sortBy)).sort((a, b) => {
1732
+ if (sortBy === "renderCount") return b.renderCount - a.renderCount;
1733
+ return a.depth - b.depth;
1734
+ });
1735
+ return { ...node, children: sortedChildren };
1736
+ }
1737
+ function annotateProviderDepth(node, providerDepth = 0) {
1738
+ const isProvider = node.type === "context.provider";
1739
+ const childProviderDepth = isProvider ? providerDepth + 1 : providerDepth;
1740
+ return {
1741
+ ...node,
1742
+ _providerDepth: providerDepth,
1743
+ children: node.children.map((child) => annotateProviderDepth(child, childProviderDepth))
1744
+ };
1745
+ }
1746
+ function limitNodes(root, limit) {
1747
+ let remaining = limit;
1748
+ const clip = (node) => {
1749
+ if (remaining <= 0) return null;
1750
+ remaining--;
1751
+ const clippedChildren = [];
1752
+ for (const child of node.children) {
1753
+ const clipped = clip(child);
1754
+ if (clipped !== null) clippedChildren.push(clipped);
1755
+ }
1756
+ return { ...node, children: clippedChildren };
1757
+ };
1758
+ return clip(root) ?? root;
1759
+ }
1760
+ var BRANCH = "\u251C\u2500\u2500 ";
1761
+ var LAST_BRANCH = "\u2514\u2500\u2500 ";
1762
+ var VERTICAL = "\u2502 ";
1763
+ var EMPTY = " ";
1764
+ function buildTTYLabel(node, showProviderDepth) {
1765
+ const parts = [node.component];
1766
+ switch (node.type) {
1767
+ case "memo":
1768
+ parts.push("[memo]");
1769
+ break;
1770
+ case "forwardRef":
1771
+ parts.push("[forwardRef]");
1772
+ break;
1773
+ case "class":
1774
+ parts.push("[class]");
1775
+ break;
1776
+ case "context.provider":
1777
+ parts.push("[provider]");
1778
+ break;
1779
+ case "context.consumer":
1780
+ parts.push("[consumer]");
1781
+ break;
1782
+ default:
1783
+ break;
1784
+ }
1785
+ if (node.renderCount > 0) {
1786
+ const durationStr = node.lastRenderDuration > 0 ? ` ${node.lastRenderDuration.toFixed(2)}ms` : "";
1787
+ parts.push(`(renders:${node.renderCount}${durationStr})`);
1788
+ }
1789
+ if (node.contexts.length > 0) {
1790
+ parts.push(`[ctx:${node.contexts.join(",")}]`);
1791
+ }
1792
+ if (showProviderDepth) {
1793
+ const pd = node._providerDepth;
1794
+ if (pd !== void 0 && pd > 0) {
1795
+ parts.push(`[pd:${pd}]`);
1796
+ }
1797
+ }
1798
+ return parts.join(" ");
1799
+ }
1800
+ function renderTTYNode(node, prefix, isLast, showProviderDepth, lines) {
1801
+ if (node.type === "host") {
1802
+ for (let i = 0; i < node.children.length; i++) {
1803
+ const child = node.children[i];
1804
+ if (child !== void 0) {
1805
+ renderTTYNode(child, prefix, i === node.children.length - 1, showProviderDepth, lines);
1806
+ }
1807
+ }
1808
+ return;
1809
+ }
1810
+ const connector = isLast ? LAST_BRANCH : BRANCH;
1811
+ lines.push(`${prefix}${connector}${buildTTYLabel(node, showProviderDepth)}`);
1812
+ const nextPrefix = prefix + (isLast ? EMPTY : VERTICAL);
1813
+ for (let i = 0; i < node.children.length; i++) {
1814
+ const child = node.children[i];
1815
+ if (child !== void 0) {
1816
+ renderTTYNode(child, nextPrefix, i === node.children.length - 1, showProviderDepth, lines);
1817
+ }
1818
+ }
1819
+ }
1820
+ function formatInstrumentTree(root, showProviderDepth = false) {
1821
+ const lines = [];
1822
+ if (root.type !== "host") {
1823
+ lines.push(buildTTYLabel(root, showProviderDepth));
1824
+ for (let i = 0; i < root.children.length; i++) {
1825
+ const child = root.children[i];
1826
+ if (child !== void 0) {
1827
+ renderTTYNode(child, "", i === root.children.length - 1, showProviderDepth, lines);
1828
+ }
1829
+ }
1830
+ } else {
1831
+ for (let i = 0; i < root.children.length; i++) {
1832
+ const child = root.children[i];
1833
+ if (child !== void 0) {
1834
+ renderTTYNode(child, "", i === root.children.length - 1, showProviderDepth, lines);
1835
+ }
1836
+ }
1837
+ }
1838
+ return lines.join("\n");
1839
+ }
1840
+ async function runInstrumentTree(options) {
1841
+ const { componentName, filePath } = options;
1842
+ const pool = await getPool();
1843
+ const slot = await pool.acquire();
1844
+ const { page } = slot;
1845
+ try {
1846
+ await page.addInitScript({ content: getBrowserEntryScript2() });
1847
+ const htmlHarness = await buildComponentHarness(
1848
+ filePath,
1849
+ componentName,
1850
+ {},
1851
+ DEFAULT_VIEWPORT_WIDTH
1852
+ );
1853
+ await page.setContent(htmlHarness, { waitUntil: "load" });
1854
+ await page.waitForFunction(
1855
+ () => {
1856
+ const w = window;
1857
+ return w.__SCOPE_RENDER_COMPLETE__ === true;
1858
+ },
1859
+ { timeout: 15e3 }
1860
+ );
1861
+ const renderError = await page.evaluate(
1862
+ () => window.__SCOPE_RENDER_ERROR__ ?? null
1863
+ );
1864
+ if (renderError !== null) {
1865
+ throw new Error(`Component render error: ${renderError}`);
1866
+ }
1867
+ const captureJson = await page.evaluate(async () => {
1868
+ const w = window;
1869
+ if (typeof w.__SCOPE_CAPTURE_JSON__ !== "function") {
1870
+ throw new Error("__SCOPE_CAPTURE_JSON__ not available \u2014 Scope runtime not injected");
1871
+ }
1872
+ return w.__SCOPE_CAPTURE_JSON__({ lightweight: false });
1873
+ });
1874
+ const captureResult = JSON.parse(captureJson);
1875
+ const componentTree = captureResult.tree;
1876
+ if (componentTree === void 0 || componentTree === null) {
1877
+ throw new Error(`No component tree found for "${componentName}"`);
1878
+ }
1879
+ let instrumentRoot = convertToInstrumentNode(componentTree, 0);
1880
+ if (options.usesContext !== void 0) {
1881
+ const filtered = filterByContext(instrumentRoot, options.usesContext);
1882
+ instrumentRoot = filtered !== null ? filtered : { ...instrumentRoot, children: [] };
1883
+ }
1884
+ if (options.wastedRenders === true) {
1885
+ const filtered = filterWastedRenders(instrumentRoot);
1886
+ instrumentRoot = filtered !== null ? filtered : { ...instrumentRoot, children: [] };
1887
+ }
1888
+ if (options.sortBy !== void 0) {
1889
+ instrumentRoot = sortTree(instrumentRoot, options.sortBy);
1890
+ }
1891
+ if (options.providerDepth === true) {
1892
+ instrumentRoot = annotateProviderDepth(instrumentRoot, 0);
1893
+ }
1894
+ if (options.limit !== void 0 && options.limit > 0) {
1895
+ instrumentRoot = limitNodes(instrumentRoot, options.limit);
1896
+ }
1897
+ return instrumentRoot;
1898
+ } finally {
1899
+ pool.release(slot);
1900
+ }
1901
+ }
1902
+ function createInstrumentTreeCommand() {
1903
+ return new Command3("tree").description("Render a component via BrowserPool and output a structured instrumentation tree").argument("<component>", "Component name to instrument (must exist in the manifest)").option("--sort-by <field>", "Sort nodes by field: renderCount | depth").option("--limit <n>", "Limit output to the first N nodes (depth-first)").option("--uses-context <name>", "Filter to components that use a specific context").option("--provider-depth", "Annotate each node with its context-provider nesting depth", false).option(
1904
+ "--wasted-renders",
1905
+ "Filter to components with wasted renders (no prop/state/context changes, not memoized)",
1906
+ false
1907
+ ).option("--format <fmt>", "Output format: json | tree (default: auto)").option("--manifest <path>", "Path to manifest.json", MANIFEST_PATH4).action(async (componentName, opts) => {
1908
+ try {
1909
+ const manifest = loadManifest(opts.manifest);
1910
+ const descriptor = manifest.components[componentName];
1911
+ if (descriptor === void 0) {
1912
+ const available = Object.keys(manifest.components).slice(0, 5).join(", ");
1913
+ throw new Error(
1914
+ `Component "${componentName}" not found in manifest.
1915
+ Available: ${available}`
1916
+ );
1917
+ }
1918
+ if (opts.sortBy !== void 0) {
1919
+ const allowed = ["renderCount", "depth"];
1920
+ if (!allowed.includes(opts.sortBy)) {
1921
+ throw new Error(
1922
+ `Unknown --sort-by value "${opts.sortBy}". Allowed: ${allowed.join(", ")}`
1923
+ );
1924
+ }
1925
+ }
1926
+ const rootDir = process.cwd();
1927
+ const filePath = resolve4(rootDir, descriptor.filePath);
1928
+ process.stderr.write(`Instrumenting ${componentName}\u2026
1929
+ `);
1930
+ const instrumentRoot = await runInstrumentTree({
1931
+ componentName,
1932
+ filePath,
1933
+ sortBy: opts.sortBy,
1934
+ limit: opts.limit !== void 0 ? Math.max(1, parseInt(opts.limit, 10)) : void 0,
1935
+ usesContext: opts.usesContext,
1936
+ providerDepth: opts.providerDepth,
1937
+ wastedRenders: opts.wastedRenders
1938
+ });
1939
+ await shutdownPool();
1940
+ const fmt = resolveFormat2(opts.format);
1941
+ if (fmt === "json") {
1942
+ process.stdout.write(`${JSON.stringify(instrumentRoot, null, 2)}
1943
+ `);
1944
+ } else {
1945
+ const tree = formatInstrumentTree(instrumentRoot, opts.providerDepth ?? false);
1946
+ process.stdout.write(`${tree}
1947
+ `);
1948
+ }
1949
+ } catch (err) {
1950
+ await shutdownPool();
1951
+ process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
1952
+ `);
1953
+ process.exit(1);
1954
+ }
1955
+ });
1956
+ }
1957
+ function resolveFormat2(formatFlag) {
1958
+ if (formatFlag !== void 0) {
1959
+ const lower = formatFlag.toLowerCase();
1960
+ if (lower !== "json" && lower !== "tree") {
1961
+ throw new Error(`Unknown format "${formatFlag}". Allowed: json, tree`);
1962
+ }
1963
+ return lower;
1964
+ }
1965
+ return isTTY() ? "tree" : "json";
1966
+ }
1967
+
1968
+ // src/instrument/renders.ts
1969
+ var MANIFEST_PATH5 = ".reactscope/manifest.json";
1607
1970
  function determineTrigger(event) {
1608
1971
  if (event.forceUpdate) return "force_update";
1609
1972
  if (event.stateChanged) return "state_change";
@@ -1904,26 +2267,26 @@ async function replayInteraction2(page, steps) {
1904
2267
  }
1905
2268
  }
1906
2269
  }
1907
- var _pool = null;
1908
- async function getPool() {
1909
- if (_pool === null) {
1910
- _pool = new BrowserPool({
2270
+ var _pool2 = null;
2271
+ async function getPool2() {
2272
+ if (_pool2 === null) {
2273
+ _pool2 = new BrowserPool2({
1911
2274
  size: { browsers: 1, pagesPerBrowser: 2 },
1912
2275
  viewportWidth: 1280,
1913
2276
  viewportHeight: 800
1914
2277
  });
1915
- await _pool.init();
2278
+ await _pool2.init();
1916
2279
  }
1917
- return _pool;
2280
+ return _pool2;
1918
2281
  }
1919
- async function shutdownPool() {
1920
- if (_pool !== null) {
1921
- await _pool.close();
1922
- _pool = null;
2282
+ async function shutdownPool2() {
2283
+ if (_pool2 !== null) {
2284
+ await _pool2.close();
2285
+ _pool2 = null;
1923
2286
  }
1924
2287
  }
1925
2288
  async function analyzeRenders(options) {
1926
- const manifestPath = options.manifestPath ?? MANIFEST_PATH4;
2289
+ const manifestPath = options.manifestPath ?? MANIFEST_PATH5;
1927
2290
  const manifest = loadManifest(manifestPath);
1928
2291
  const descriptor = manifest.components[options.componentName];
1929
2292
  if (descriptor === void 0) {
@@ -1934,9 +2297,9 @@ Available: ${available}`
1934
2297
  );
1935
2298
  }
1936
2299
  const rootDir = process.cwd();
1937
- const filePath = resolve4(rootDir, descriptor.filePath);
2300
+ const filePath = resolve5(rootDir, descriptor.filePath);
1938
2301
  const htmlHarness = await buildComponentHarness(filePath, options.componentName, {}, 1280);
1939
- const pool = await getPool();
2302
+ const pool = await getPool2();
1940
2303
  const slot = await pool.acquire();
1941
2304
  const { page } = slot;
1942
2305
  const startMs = performance.now();
@@ -2017,11 +2380,11 @@ function formatRendersTable(result) {
2017
2380
  return lines.join("\n");
2018
2381
  }
2019
2382
  function createInstrumentRendersCommand() {
2020
- return new Command3("renders").description("Trace re-render causality chains for a component during an interaction sequence").argument("<component>", "Component name to instrument (must be in manifest)").option(
2383
+ return new Command4("renders").description("Trace re-render causality chains for a component during an interaction sequence").argument("<component>", "Component name to instrument (must be in manifest)").option(
2021
2384
  "--interaction <json>",
2022
2385
  `Interaction sequence JSON, e.g. '[{"action":"click","target":"button"}]'`,
2023
2386
  "[]"
2024
- ).option("--json", "Output as JSON regardless of TTY", false).option("--manifest <path>", "Path to manifest.json", MANIFEST_PATH4).action(
2387
+ ).option("--json", "Output as JSON regardless of TTY", false).option("--manifest <path>", "Path to manifest.json", MANIFEST_PATH5).action(
2025
2388
  async (componentName, opts) => {
2026
2389
  let interaction = [];
2027
2390
  try {
@@ -2044,7 +2407,7 @@ function createInstrumentRendersCommand() {
2044
2407
  interaction,
2045
2408
  manifestPath: opts.manifest
2046
2409
  });
2047
- await shutdownPool();
2410
+ await shutdownPool2();
2048
2411
  if (opts.json || !isTTY()) {
2049
2412
  process.stdout.write(`${JSON.stringify(result, null, 2)}
2050
2413
  `);
@@ -2053,7 +2416,7 @@ function createInstrumentRendersCommand() {
2053
2416
  `);
2054
2417
  }
2055
2418
  } catch (err) {
2056
- await shutdownPool();
2419
+ await shutdownPool2();
2057
2420
  process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
2058
2421
  `);
2059
2422
  process.exit(1);
@@ -2062,34 +2425,35 @@ function createInstrumentRendersCommand() {
2062
2425
  );
2063
2426
  }
2064
2427
  function createInstrumentCommand() {
2065
- const instrumentCmd = new Command3("instrument").description(
2428
+ const instrumentCmd = new Command4("instrument").description(
2066
2429
  "Structured instrumentation commands for React component analysis"
2067
2430
  );
2068
2431
  instrumentCmd.addCommand(createInstrumentRendersCommand());
2069
2432
  instrumentCmd.addCommand(createInstrumentHooksCommand());
2070
2433
  instrumentCmd.addCommand(createInstrumentProfileCommand());
2434
+ instrumentCmd.addCommand(createInstrumentTreeCommand());
2071
2435
  return instrumentCmd;
2072
2436
  }
2073
2437
 
2074
2438
  // src/render-commands.ts
2075
2439
  import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
2076
- import { resolve as resolve6 } from "path";
2440
+ import { resolve as resolve7 } from "path";
2077
2441
  import {
2078
2442
  ALL_CONTEXT_IDS,
2079
2443
  ALL_STRESS_IDS,
2080
- BrowserPool as BrowserPool2,
2444
+ BrowserPool as BrowserPool3,
2081
2445
  contextAxis,
2082
2446
  RenderMatrix,
2083
2447
  SatoriRenderer,
2084
2448
  safeRender,
2085
2449
  stressAxis
2086
2450
  } from "@agent-scope/render";
2087
- import { Command as Command4 } from "commander";
2451
+ import { Command as Command5 } from "commander";
2088
2452
 
2089
2453
  // src/tailwind-css.ts
2090
2454
  import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
2091
2455
  import { createRequire } from "module";
2092
- import { resolve as resolve5 } from "path";
2456
+ import { resolve as resolve6 } from "path";
2093
2457
  var CONFIG_FILENAMES = [
2094
2458
  ".reactscope/config.json",
2095
2459
  ".reactscope/config.js",
@@ -2106,14 +2470,14 @@ var STYLE_ENTRY_CANDIDATES = [
2106
2470
  var TAILWIND_IMPORT = /@import\s+["']tailwindcss["']\s*;?/;
2107
2471
  var compilerCache = null;
2108
2472
  function getCachedBuild(cwd) {
2109
- if (compilerCache !== null && resolve5(compilerCache.cwd) === resolve5(cwd)) {
2473
+ if (compilerCache !== null && resolve6(compilerCache.cwd) === resolve6(cwd)) {
2110
2474
  return compilerCache.build;
2111
2475
  }
2112
2476
  return null;
2113
2477
  }
2114
2478
  function findStylesEntry(cwd) {
2115
2479
  for (const name of CONFIG_FILENAMES) {
2116
- const p = resolve5(cwd, name);
2480
+ const p = resolve6(cwd, name);
2117
2481
  if (!existsSync4(p)) continue;
2118
2482
  try {
2119
2483
  if (name.endsWith(".json")) {
@@ -2122,28 +2486,28 @@ function findStylesEntry(cwd) {
2122
2486
  const scope = data.scope;
2123
2487
  const entry = scope?.stylesEntry ?? data.stylesEntry;
2124
2488
  if (typeof entry === "string") {
2125
- const full = resolve5(cwd, entry);
2489
+ const full = resolve6(cwd, entry);
2126
2490
  if (existsSync4(full)) return full;
2127
2491
  }
2128
2492
  }
2129
2493
  } catch {
2130
2494
  }
2131
2495
  }
2132
- const pkgPath = resolve5(cwd, "package.json");
2496
+ const pkgPath = resolve6(cwd, "package.json");
2133
2497
  if (existsSync4(pkgPath)) {
2134
2498
  try {
2135
2499
  const raw = readFileSync4(pkgPath, "utf-8");
2136
2500
  const pkg = JSON.parse(raw);
2137
2501
  const entry = pkg.scope?.stylesEntry;
2138
2502
  if (typeof entry === "string") {
2139
- const full = resolve5(cwd, entry);
2503
+ const full = resolve6(cwd, entry);
2140
2504
  if (existsSync4(full)) return full;
2141
2505
  }
2142
2506
  } catch {
2143
2507
  }
2144
2508
  }
2145
2509
  for (const candidate of STYLE_ENTRY_CANDIDATES) {
2146
- const full = resolve5(cwd, candidate);
2510
+ const full = resolve6(cwd, candidate);
2147
2511
  if (existsSync4(full)) {
2148
2512
  try {
2149
2513
  const content = readFileSync4(full, "utf-8");
@@ -2161,7 +2525,7 @@ async function getTailwindCompiler(cwd) {
2161
2525
  if (entryPath === null) return null;
2162
2526
  let compile;
2163
2527
  try {
2164
- const require2 = createRequire(resolve5(cwd, "package.json"));
2528
+ const require2 = createRequire(resolve6(cwd, "package.json"));
2165
2529
  const tailwind = require2("tailwindcss");
2166
2530
  const fn = tailwind.compile;
2167
2531
  if (typeof fn !== "function") return null;
@@ -2172,8 +2536,8 @@ async function getTailwindCompiler(cwd) {
2172
2536
  const entryContent = readFileSync4(entryPath, "utf-8");
2173
2537
  const loadStylesheet = async (id, base) => {
2174
2538
  if (id === "tailwindcss") {
2175
- const nodeModules = resolve5(cwd, "node_modules");
2176
- const tailwindCssPath = resolve5(nodeModules, "tailwindcss", "index.css");
2539
+ const nodeModules = resolve6(cwd, "node_modules");
2540
+ const tailwindCssPath = resolve6(nodeModules, "tailwindcss", "index.css");
2177
2541
  if (!existsSync4(tailwindCssPath)) {
2178
2542
  throw new Error(
2179
2543
  `Tailwind v4: tailwindcss package not found at ${tailwindCssPath}. Install with: npm install tailwindcss`
@@ -2182,10 +2546,10 @@ async function getTailwindCompiler(cwd) {
2182
2546
  const content = readFileSync4(tailwindCssPath, "utf-8");
2183
2547
  return { path: "virtual:tailwindcss/index.css", base, content };
2184
2548
  }
2185
- const full = resolve5(base, id);
2549
+ const full = resolve6(base, id);
2186
2550
  if (existsSync4(full)) {
2187
2551
  const content = readFileSync4(full, "utf-8");
2188
- return { path: full, base: resolve5(full, ".."), content };
2552
+ return { path: full, base: resolve6(full, ".."), content };
2189
2553
  }
2190
2554
  throw new Error(`Tailwind v4: could not load stylesheet: ${id} (base: ${base})`);
2191
2555
  };
@@ -2207,24 +2571,24 @@ async function getCompiledCssForClasses(cwd, classes) {
2207
2571
  }
2208
2572
 
2209
2573
  // src/render-commands.ts
2210
- var MANIFEST_PATH5 = ".reactscope/manifest.json";
2574
+ var MANIFEST_PATH6 = ".reactscope/manifest.json";
2211
2575
  var DEFAULT_OUTPUT_DIR = ".reactscope/renders";
2212
- var _pool2 = null;
2213
- async function getPool2(viewportWidth, viewportHeight) {
2214
- if (_pool2 === null) {
2215
- _pool2 = new BrowserPool2({
2576
+ var _pool3 = null;
2577
+ async function getPool3(viewportWidth, viewportHeight) {
2578
+ if (_pool3 === null) {
2579
+ _pool3 = new BrowserPool3({
2216
2580
  size: { browsers: 1, pagesPerBrowser: 4 },
2217
2581
  viewportWidth,
2218
2582
  viewportHeight
2219
2583
  });
2220
- await _pool2.init();
2584
+ await _pool3.init();
2221
2585
  }
2222
- return _pool2;
2586
+ return _pool3;
2223
2587
  }
2224
- async function shutdownPool2() {
2225
- if (_pool2 !== null) {
2226
- await _pool2.close();
2227
- _pool2 = null;
2588
+ async function shutdownPool3() {
2589
+ if (_pool3 !== null) {
2590
+ await _pool3.close();
2591
+ _pool3 = null;
2228
2592
  }
2229
2593
  }
2230
2594
  function buildRenderer(filePath, componentName, viewportWidth, viewportHeight) {
@@ -2235,7 +2599,7 @@ function buildRenderer(filePath, componentName, viewportWidth, viewportHeight) {
2235
2599
  _satori: satori,
2236
2600
  async renderCell(props, _complexityClass) {
2237
2601
  const startMs = performance.now();
2238
- const pool = await getPool2(viewportWidth, viewportHeight);
2602
+ const pool = await getPool3(viewportWidth, viewportHeight);
2239
2603
  const htmlHarness = await buildComponentHarness(
2240
2604
  filePath,
2241
2605
  componentName,
@@ -2332,7 +2696,7 @@ function buildRenderer(filePath, componentName, viewportWidth, viewportHeight) {
2332
2696
  };
2333
2697
  }
2334
2698
  function registerRenderSingle(renderCmd) {
2335
- renderCmd.command("component <component>", { isDefault: true }).description("Render a single component to PNG or JSON").option("--props <json>", `Inline props JSON, e.g. '{"variant":"primary"}'`).option("--viewport <WxH>", "Viewport size e.g. 1280x720", "375x812").option("--theme <name>", "Theme name from the token system").option("-o, --output <path>", "Write PNG to file instead of stdout").option("--format <fmt>", "Output format: png or json (default: auto)").option("--manifest <path>", "Path to manifest.json", MANIFEST_PATH5).action(
2699
+ renderCmd.command("component <component>", { isDefault: true }).description("Render a single component to PNG or JSON").option("--props <json>", `Inline props JSON, e.g. '{"variant":"primary"}'`).option("--viewport <WxH>", "Viewport size e.g. 1280x720", "375x812").option("--theme <name>", "Theme name from the token system").option("-o, --output <path>", "Write PNG to file instead of stdout").option("--format <fmt>", "Output format: png or json (default: auto)").option("--manifest <path>", "Path to manifest.json", MANIFEST_PATH6).action(
2336
2700
  async (componentName, opts) => {
2337
2701
  try {
2338
2702
  const manifest = loadManifest(opts.manifest);
@@ -2354,7 +2718,7 @@ Available: ${available}`
2354
2718
  }
2355
2719
  const { width, height } = parseViewport(opts.viewport);
2356
2720
  const rootDir = process.cwd();
2357
- const filePath = resolve6(rootDir, descriptor.filePath);
2721
+ const filePath = resolve7(rootDir, descriptor.filePath);
2358
2722
  const renderer = buildRenderer(filePath, componentName, width, height);
2359
2723
  process.stderr.write(
2360
2724
  `Rendering ${componentName} [${descriptor.complexityClass}] at ${width}\xD7${height}\u2026
@@ -2371,7 +2735,7 @@ Available: ${available}`
2371
2735
  }
2372
2736
  }
2373
2737
  );
2374
- await shutdownPool2();
2738
+ await shutdownPool3();
2375
2739
  if (outcome.crashed) {
2376
2740
  process.stderr.write(`\u2717 Render failed: ${outcome.error.message}
2377
2741
  `);
@@ -2384,7 +2748,7 @@ Available: ${available}`
2384
2748
  }
2385
2749
  const result = outcome.result;
2386
2750
  if (opts.output !== void 0) {
2387
- const outPath = resolve6(process.cwd(), opts.output);
2751
+ const outPath = resolve7(process.cwd(), opts.output);
2388
2752
  writeFileSync4(outPath, result.screenshot);
2389
2753
  process.stdout.write(
2390
2754
  `\u2713 ${componentName} \u2192 ${opts.output} (${result.width}\xD7${result.height}, ${result.renderTimeMs.toFixed(0)}ms)
@@ -2398,9 +2762,9 @@ Available: ${available}`
2398
2762
  process.stdout.write(`${JSON.stringify(json, null, 2)}
2399
2763
  `);
2400
2764
  } else if (fmt === "file") {
2401
- const dir = resolve6(process.cwd(), DEFAULT_OUTPUT_DIR);
2765
+ const dir = resolve7(process.cwd(), DEFAULT_OUTPUT_DIR);
2402
2766
  mkdirSync3(dir, { recursive: true });
2403
- const outPath = resolve6(dir, `${componentName}.png`);
2767
+ const outPath = resolve7(dir, `${componentName}.png`);
2404
2768
  writeFileSync4(outPath, result.screenshot);
2405
2769
  const relPath = `${DEFAULT_OUTPUT_DIR}/${componentName}.png`;
2406
2770
  process.stdout.write(
@@ -2408,9 +2772,9 @@ Available: ${available}`
2408
2772
  `
2409
2773
  );
2410
2774
  } else {
2411
- const dir = resolve6(process.cwd(), DEFAULT_OUTPUT_DIR);
2775
+ const dir = resolve7(process.cwd(), DEFAULT_OUTPUT_DIR);
2412
2776
  mkdirSync3(dir, { recursive: true });
2413
- const outPath = resolve6(dir, `${componentName}.png`);
2777
+ const outPath = resolve7(dir, `${componentName}.png`);
2414
2778
  writeFileSync4(outPath, result.screenshot);
2415
2779
  const relPath = `${DEFAULT_OUTPUT_DIR}/${componentName}.png`;
2416
2780
  process.stdout.write(
@@ -2419,7 +2783,7 @@ Available: ${available}`
2419
2783
  );
2420
2784
  }
2421
2785
  } catch (err) {
2422
- await shutdownPool2();
2786
+ await shutdownPool3();
2423
2787
  process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
2424
2788
  `);
2425
2789
  process.exit(1);
@@ -2431,7 +2795,7 @@ function registerRenderMatrix(renderCmd) {
2431
2795
  renderCmd.command("matrix <component>").description("Render a component across a matrix of prop axes").option("--axes <spec>", "Axis definitions e.g. 'variant:primary,secondary size:sm,md,lg'").option(
2432
2796
  "--contexts <ids>",
2433
2797
  "Composition context IDs, comma-separated (e.g. centered,rtl,sidebar)"
2434
- ).option("--stress <ids>", "Stress preset IDs, comma-separated (e.g. text.long,text.unicode)").option("--sprite <path>", "Write sprite sheet PNG to file").option("--format <fmt>", "Output format: json|png|html|csv (default: auto)").option("--concurrency <n>", "Max parallel renders", "8").option("--manifest <path>", "Path to manifest.json", MANIFEST_PATH5).action(
2798
+ ).option("--stress <ids>", "Stress preset IDs, comma-separated (e.g. text.long,text.unicode)").option("--sprite <path>", "Write sprite sheet PNG to file").option("--format <fmt>", "Output format: json|png|html|csv (default: auto)").option("--concurrency <n>", "Max parallel renders", "8").option("--manifest <path>", "Path to manifest.json", MANIFEST_PATH6).action(
2435
2799
  async (componentName, opts) => {
2436
2800
  try {
2437
2801
  const manifest = loadManifest(opts.manifest);
@@ -2446,7 +2810,7 @@ Available: ${available}`
2446
2810
  const concurrency = Math.max(1, parseInt(opts.concurrency, 10) || 8);
2447
2811
  const { width, height } = { width: 375, height: 812 };
2448
2812
  const rootDir = process.cwd();
2449
- const filePath = resolve6(rootDir, descriptor.filePath);
2813
+ const filePath = resolve7(rootDir, descriptor.filePath);
2450
2814
  const renderer = buildRenderer(filePath, componentName, width, height);
2451
2815
  const axes = [];
2452
2816
  if (opts.axes !== void 0) {
@@ -2504,7 +2868,7 @@ Available: ${available}`
2504
2868
  concurrency
2505
2869
  });
2506
2870
  const result = await matrix.render();
2507
- await shutdownPool2();
2871
+ await shutdownPool3();
2508
2872
  process.stderr.write(
2509
2873
  `Done. ${result.stats.totalCells} cells, avg ${result.stats.avgRenderTimeMs.toFixed(1)}ms
2510
2874
  `
@@ -2513,7 +2877,7 @@ Available: ${available}`
2513
2877
  const { SpriteSheetGenerator } = await import("@agent-scope/render");
2514
2878
  const gen = new SpriteSheetGenerator();
2515
2879
  const sheet = await gen.generate(result);
2516
- const spritePath = resolve6(process.cwd(), opts.sprite);
2880
+ const spritePath = resolve7(process.cwd(), opts.sprite);
2517
2881
  writeFileSync4(spritePath, sheet.png);
2518
2882
  process.stderr.write(`Sprite sheet saved to ${spritePath}
2519
2883
  `);
@@ -2523,9 +2887,9 @@ Available: ${available}`
2523
2887
  const { SpriteSheetGenerator } = await import("@agent-scope/render");
2524
2888
  const gen = new SpriteSheetGenerator();
2525
2889
  const sheet = await gen.generate(result);
2526
- const dir = resolve6(process.cwd(), DEFAULT_OUTPUT_DIR);
2890
+ const dir = resolve7(process.cwd(), DEFAULT_OUTPUT_DIR);
2527
2891
  mkdirSync3(dir, { recursive: true });
2528
- const outPath = resolve6(dir, `${componentName}-matrix.png`);
2892
+ const outPath = resolve7(dir, `${componentName}-matrix.png`);
2529
2893
  writeFileSync4(outPath, sheet.png);
2530
2894
  const relPath = `${DEFAULT_OUTPUT_DIR}/${componentName}-matrix.png`;
2531
2895
  process.stdout.write(
@@ -2549,7 +2913,7 @@ Available: ${available}`
2549
2913
  process.stdout.write(formatMatrixCsv(componentName, result));
2550
2914
  }
2551
2915
  } catch (err) {
2552
- await shutdownPool2();
2916
+ await shutdownPool3();
2553
2917
  process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
2554
2918
  `);
2555
2919
  process.exit(1);
@@ -2558,7 +2922,7 @@ Available: ${available}`
2558
2922
  );
2559
2923
  }
2560
2924
  function registerRenderAll(renderCmd) {
2561
- renderCmd.command("all").description("Render all components from the manifest").option("--concurrency <n>", "Max parallel renders", "4").option("--output-dir <dir>", "Output directory for renders", DEFAULT_OUTPUT_DIR).option("--manifest <path>", "Path to manifest.json", MANIFEST_PATH5).option("--format <fmt>", "Output format: json|png (default: png)", "png").action(
2925
+ renderCmd.command("all").description("Render all components from the manifest").option("--concurrency <n>", "Max parallel renders", "4").option("--output-dir <dir>", "Output directory for renders", DEFAULT_OUTPUT_DIR).option("--manifest <path>", "Path to manifest.json", MANIFEST_PATH6).option("--format <fmt>", "Output format: json|png (default: png)", "png").action(
2562
2926
  async (opts) => {
2563
2927
  try {
2564
2928
  const manifest = loadManifest(opts.manifest);
@@ -2569,7 +2933,7 @@ function registerRenderAll(renderCmd) {
2569
2933
  return;
2570
2934
  }
2571
2935
  const concurrency = Math.max(1, parseInt(opts.concurrency, 10) || 4);
2572
- const outputDir = resolve6(process.cwd(), opts.outputDir);
2936
+ const outputDir = resolve7(process.cwd(), opts.outputDir);
2573
2937
  mkdirSync3(outputDir, { recursive: true });
2574
2938
  const rootDir = process.cwd();
2575
2939
  process.stderr.write(`Rendering ${total} components (concurrency: ${concurrency})\u2026
@@ -2579,7 +2943,7 @@ function registerRenderAll(renderCmd) {
2579
2943
  const renderOne = async (name) => {
2580
2944
  const descriptor = manifest.components[name];
2581
2945
  if (descriptor === void 0) return;
2582
- const filePath = resolve6(rootDir, descriptor.filePath);
2946
+ const filePath = resolve7(rootDir, descriptor.filePath);
2583
2947
  const renderer = buildRenderer(filePath, name, 375, 812);
2584
2948
  const outcome = await safeRender(
2585
2949
  () => renderer.renderCell({}, descriptor.complexityClass),
@@ -2602,7 +2966,7 @@ function registerRenderAll(renderCmd) {
2602
2966
  success: false,
2603
2967
  errorMessage: outcome.error.message
2604
2968
  });
2605
- const errPath = resolve6(outputDir, `${name}.error.json`);
2969
+ const errPath = resolve7(outputDir, `${name}.error.json`);
2606
2970
  writeFileSync4(
2607
2971
  errPath,
2608
2972
  JSON.stringify(
@@ -2620,9 +2984,9 @@ function registerRenderAll(renderCmd) {
2620
2984
  }
2621
2985
  const result = outcome.result;
2622
2986
  results.push({ name, renderTimeMs: result.renderTimeMs, success: true });
2623
- const pngPath = resolve6(outputDir, `${name}.png`);
2987
+ const pngPath = resolve7(outputDir, `${name}.png`);
2624
2988
  writeFileSync4(pngPath, result.screenshot);
2625
- const jsonPath = resolve6(outputDir, `${name}.json`);
2989
+ const jsonPath = resolve7(outputDir, `${name}.json`);
2626
2990
  writeFileSync4(jsonPath, JSON.stringify(formatRenderJson(name, {}, result), null, 2));
2627
2991
  if (isTTY()) {
2628
2992
  process.stdout.write(
@@ -2646,13 +3010,13 @@ function registerRenderAll(renderCmd) {
2646
3010
  workers.push(worker());
2647
3011
  }
2648
3012
  await Promise.all(workers);
2649
- await shutdownPool2();
3013
+ await shutdownPool3();
2650
3014
  process.stderr.write("\n");
2651
3015
  const summary = formatSummaryText(results, outputDir);
2652
3016
  process.stderr.write(`${summary}
2653
3017
  `);
2654
3018
  } catch (err) {
2655
- await shutdownPool2();
3019
+ await shutdownPool3();
2656
3020
  process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
2657
3021
  `);
2658
3022
  process.exit(1);
@@ -2685,7 +3049,7 @@ function resolveMatrixFormat(formatFlag, spriteAlreadyWritten) {
2685
3049
  return "json";
2686
3050
  }
2687
3051
  function createRenderCommand() {
2688
- const renderCmd = new Command4("render").description(
3052
+ const renderCmd = new Command5("render").description(
2689
3053
  "Render components to PNG or JSON via esbuild + BrowserPool"
2690
3054
  );
2691
3055
  registerRenderSingle(renderCmd);
@@ -2696,31 +3060,31 @@ function createRenderCommand() {
2696
3060
 
2697
3061
  // src/report/baseline.ts
2698
3062
  import { existsSync as existsSync5, mkdirSync as mkdirSync4, rmSync, writeFileSync as writeFileSync5 } from "fs";
2699
- import { resolve as resolve7 } from "path";
3063
+ import { resolve as resolve8 } from "path";
2700
3064
  import { generateManifest as generateManifest2 } from "@agent-scope/manifest";
2701
- import { BrowserPool as BrowserPool3, safeRender as safeRender2 } from "@agent-scope/render";
3065
+ import { BrowserPool as BrowserPool4, safeRender as safeRender2 } from "@agent-scope/render";
2702
3066
  import { ComplianceEngine, TokenResolver } from "@agent-scope/tokens";
2703
3067
  var DEFAULT_BASELINE_DIR = ".reactscope/baseline";
2704
- var _pool3 = null;
2705
- async function getPool3(viewportWidth, viewportHeight) {
2706
- if (_pool3 === null) {
2707
- _pool3 = new BrowserPool3({
3068
+ var _pool4 = null;
3069
+ async function getPool4(viewportWidth, viewportHeight) {
3070
+ if (_pool4 === null) {
3071
+ _pool4 = new BrowserPool4({
2708
3072
  size: { browsers: 1, pagesPerBrowser: 4 },
2709
3073
  viewportWidth,
2710
3074
  viewportHeight
2711
3075
  });
2712
- await _pool3.init();
3076
+ await _pool4.init();
2713
3077
  }
2714
- return _pool3;
3078
+ return _pool4;
2715
3079
  }
2716
- async function shutdownPool3() {
2717
- if (_pool3 !== null) {
2718
- await _pool3.close();
2719
- _pool3 = null;
3080
+ async function shutdownPool4() {
3081
+ if (_pool4 !== null) {
3082
+ await _pool4.close();
3083
+ _pool4 = null;
2720
3084
  }
2721
3085
  }
2722
3086
  async function renderComponent(filePath, componentName, props, viewportWidth, viewportHeight) {
2723
- const pool = await getPool3(viewportWidth, viewportHeight);
3087
+ const pool = await getPool4(viewportWidth, viewportHeight);
2724
3088
  const htmlHarness = await buildComponentHarness(filePath, componentName, props, viewportWidth);
2725
3089
  const slot = await pool.acquire();
2726
3090
  const { page } = slot;
@@ -2845,8 +3209,8 @@ async function runBaseline(options = {}) {
2845
3209
  } = options;
2846
3210
  const startTime = performance.now();
2847
3211
  const rootDir = process.cwd();
2848
- const baselineDir = resolve7(rootDir, outputDir);
2849
- const rendersDir = resolve7(baselineDir, "renders");
3212
+ const baselineDir = resolve8(rootDir, outputDir);
3213
+ const rendersDir = resolve8(baselineDir, "renders");
2850
3214
  if (existsSync5(baselineDir)) {
2851
3215
  rmSync(baselineDir, { recursive: true, force: true });
2852
3216
  }
@@ -2854,7 +3218,7 @@ async function runBaseline(options = {}) {
2854
3218
  let manifest;
2855
3219
  if (manifestPath !== void 0) {
2856
3220
  const { readFileSync: readFileSync8 } = await import("fs");
2857
- const absPath = resolve7(rootDir, manifestPath);
3221
+ const absPath = resolve8(rootDir, manifestPath);
2858
3222
  if (!existsSync5(absPath)) {
2859
3223
  throw new Error(`Manifest not found at ${absPath}.`);
2860
3224
  }
@@ -2868,7 +3232,7 @@ async function runBaseline(options = {}) {
2868
3232
  process.stderr.write(`Found ${count} components.
2869
3233
  `);
2870
3234
  }
2871
- writeFileSync5(resolve7(baselineDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
3235
+ writeFileSync5(resolve8(baselineDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
2872
3236
  let componentNames = Object.keys(manifest.components);
2873
3237
  if (componentsGlob !== void 0) {
2874
3238
  componentNames = componentNames.filter((name) => matchGlob(componentsGlob, name));
@@ -2889,7 +3253,7 @@ async function runBaseline(options = {}) {
2889
3253
  auditedAt: (/* @__PURE__ */ new Date()).toISOString()
2890
3254
  };
2891
3255
  writeFileSync5(
2892
- resolve7(baselineDir, "compliance.json"),
3256
+ resolve8(baselineDir, "compliance.json"),
2893
3257
  JSON.stringify(emptyReport, null, 2),
2894
3258
  "utf-8"
2895
3259
  );
@@ -2910,7 +3274,7 @@ async function runBaseline(options = {}) {
2910
3274
  const renderOne = async (name) => {
2911
3275
  const descriptor = manifest.components[name];
2912
3276
  if (descriptor === void 0) return;
2913
- const filePath = resolve7(rootDir, descriptor.filePath);
3277
+ const filePath = resolve8(rootDir, descriptor.filePath);
2914
3278
  const outcome = await safeRender2(
2915
3279
  () => renderComponent(filePath, name, {}, viewportWidth, viewportHeight),
2916
3280
  {
@@ -2929,7 +3293,7 @@ async function runBaseline(options = {}) {
2929
3293
  }
2930
3294
  if (outcome.crashed) {
2931
3295
  failureCount++;
2932
- const errPath = resolve7(rendersDir, `${name}.error.json`);
3296
+ const errPath = resolve8(rendersDir, `${name}.error.json`);
2933
3297
  writeFileSync5(
2934
3298
  errPath,
2935
3299
  JSON.stringify(
@@ -2947,10 +3311,10 @@ async function runBaseline(options = {}) {
2947
3311
  return;
2948
3312
  }
2949
3313
  const result = outcome.result;
2950
- writeFileSync5(resolve7(rendersDir, `${name}.png`), result.screenshot);
3314
+ writeFileSync5(resolve8(rendersDir, `${name}.png`), result.screenshot);
2951
3315
  const jsonOutput = formatRenderJson(name, {}, result);
2952
3316
  writeFileSync5(
2953
- resolve7(rendersDir, `${name}.json`),
3317
+ resolve8(rendersDir, `${name}.json`),
2954
3318
  JSON.stringify(jsonOutput, null, 2),
2955
3319
  "utf-8"
2956
3320
  );
@@ -2970,7 +3334,7 @@ async function runBaseline(options = {}) {
2970
3334
  workers.push(worker());
2971
3335
  }
2972
3336
  await Promise.all(workers);
2973
- await shutdownPool3();
3337
+ await shutdownPool4();
2974
3338
  if (isTTY()) {
2975
3339
  process.stderr.write("\n");
2976
3340
  }
@@ -2978,7 +3342,7 @@ async function runBaseline(options = {}) {
2978
3342
  const engine = new ComplianceEngine(resolver);
2979
3343
  const batchReport = engine.auditBatch(computedStylesMap);
2980
3344
  writeFileSync5(
2981
- resolve7(baselineDir, "compliance.json"),
3345
+ resolve8(baselineDir, "compliance.json"),
2982
3346
  JSON.stringify(batchReport, null, 2),
2983
3347
  "utf-8"
2984
3348
  );
@@ -3021,10 +3385,10 @@ function registerBaselineSubCommand(reportCmd) {
3021
3385
  }
3022
3386
 
3023
3387
  // src/tree-formatter.ts
3024
- var BRANCH = "\u251C\u2500\u2500 ";
3025
- var LAST_BRANCH = "\u2514\u2500\u2500 ";
3026
- var VERTICAL = "\u2502 ";
3027
- var EMPTY = " ";
3388
+ var BRANCH2 = "\u251C\u2500\u2500 ";
3389
+ var LAST_BRANCH2 = "\u2514\u2500\u2500 ";
3390
+ var VERTICAL2 = "\u2502 ";
3391
+ var EMPTY2 = " ";
3028
3392
  function buildLabel(node, options) {
3029
3393
  const parts = [node.name];
3030
3394
  if (node.type === "memo") {
@@ -3072,19 +3436,19 @@ function renderNode(node, prefix, isLast, depth, options, lines) {
3072
3436
  }
3073
3437
  return;
3074
3438
  }
3075
- const connector = isLast ? LAST_BRANCH : BRANCH;
3439
+ const connector = isLast ? LAST_BRANCH2 : BRANCH2;
3076
3440
  const label = buildLabel(node, options);
3077
3441
  lines.push(`${prefix}${connector}${label}`);
3078
3442
  if (options.maxDepth !== void 0 && depth >= options.maxDepth) {
3079
3443
  const childCount = countVisibleDescendants(node, options);
3080
3444
  if (childCount > 0) {
3081
- const nextPrefix2 = prefix + (isLast ? EMPTY : VERTICAL);
3082
- lines.push(`${nextPrefix2}${LAST_BRANCH}\u2026 (${childCount} more)`);
3445
+ const nextPrefix2 = prefix + (isLast ? EMPTY2 : VERTICAL2);
3446
+ lines.push(`${nextPrefix2}${LAST_BRANCH2}\u2026 (${childCount} more)`);
3083
3447
  }
3084
3448
  return;
3085
3449
  }
3086
3450
  const visibleChildren = getVisibleChildren(node, options);
3087
- const nextPrefix = prefix + (isLast ? EMPTY : VERTICAL);
3451
+ const nextPrefix = prefix + (isLast ? EMPTY2 : VERTICAL2);
3088
3452
  for (let i = 0; i < visibleChildren.length; i++) {
3089
3453
  const child = visibleChildren[i];
3090
3454
  if (child !== void 0) {
@@ -3126,7 +3490,7 @@ function formatTree(root, options = {}) {
3126
3490
  if (options.maxDepth === 0) {
3127
3491
  const childCount = countVisibleDescendants(root, options);
3128
3492
  if (childCount > 0) {
3129
- lines.push(`${LAST_BRANCH}\u2026 (${childCount} more)`);
3493
+ lines.push(`${LAST_BRANCH2}\u2026 (${childCount} more)`);
3130
3494
  }
3131
3495
  } else {
3132
3496
  const visibleChildren = getVisibleChildren(root, options);
@@ -3301,7 +3665,7 @@ function buildStructuredReport(report) {
3301
3665
 
3302
3666
  // src/tokens/commands.ts
3303
3667
  import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
3304
- import { resolve as resolve9 } from "path";
3668
+ import { resolve as resolve10 } from "path";
3305
3669
  import {
3306
3670
  parseTokenFileSync as parseTokenFileSync2,
3307
3671
  TokenParseError,
@@ -3309,41 +3673,41 @@ import {
3309
3673
  TokenValidationError,
3310
3674
  validateTokenFile
3311
3675
  } from "@agent-scope/tokens";
3312
- import { Command as Command6 } from "commander";
3676
+ import { Command as Command7 } from "commander";
3313
3677
 
3314
3678
  // src/tokens/export.ts
3315
3679
  import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync6 } from "fs";
3316
- import { resolve as resolve8 } from "path";
3680
+ import { resolve as resolve9 } from "path";
3317
3681
  import {
3318
3682
  exportTokens,
3319
3683
  parseTokenFileSync,
3320
3684
  ThemeResolver,
3321
3685
  TokenResolver as TokenResolver2
3322
3686
  } from "@agent-scope/tokens";
3323
- import { Command as Command5 } from "commander";
3687
+ import { Command as Command6 } from "commander";
3324
3688
  var DEFAULT_TOKEN_FILE = "reactscope.tokens.json";
3325
3689
  var CONFIG_FILE = "reactscope.config.json";
3326
3690
  var SUPPORTED_FORMATS = ["css", "ts", "scss", "tailwind", "flat-json", "figma"];
3327
3691
  function resolveTokenFilePath(fileFlag) {
3328
3692
  if (fileFlag !== void 0) {
3329
- return resolve8(process.cwd(), fileFlag);
3693
+ return resolve9(process.cwd(), fileFlag);
3330
3694
  }
3331
- const configPath = resolve8(process.cwd(), CONFIG_FILE);
3695
+ const configPath = resolve9(process.cwd(), CONFIG_FILE);
3332
3696
  if (existsSync6(configPath)) {
3333
3697
  try {
3334
3698
  const raw = readFileSync5(configPath, "utf-8");
3335
3699
  const config = JSON.parse(raw);
3336
3700
  if (typeof config === "object" && config !== null && "tokens" in config && typeof config.tokens === "object" && config.tokens !== null && typeof config.tokens?.file === "string") {
3337
3701
  const file = config.tokens.file;
3338
- return resolve8(process.cwd(), file);
3702
+ return resolve9(process.cwd(), file);
3339
3703
  }
3340
3704
  } catch {
3341
3705
  }
3342
3706
  }
3343
- return resolve8(process.cwd(), DEFAULT_TOKEN_FILE);
3707
+ return resolve9(process.cwd(), DEFAULT_TOKEN_FILE);
3344
3708
  }
3345
3709
  function createTokensExportCommand() {
3346
- return new Command5("export").description("Export design tokens to a downstream format").requiredOption("--format <fmt>", `Output format: ${SUPPORTED_FORMATS.join(", ")}`).option("--file <path>", "Path to token file (overrides config)").option("--out <path>", "Write output to file instead of stdout").option("--prefix <prefix>", "CSS/SCSS: prefix for variable names (e.g. 'scope')").option("--selector <selector>", "CSS: custom root selector (default: ':root')").option(
3710
+ return new Command6("export").description("Export design tokens to a downstream format").requiredOption("--format <fmt>", `Output format: ${SUPPORTED_FORMATS.join(", ")}`).option("--file <path>", "Path to token file (overrides config)").option("--out <path>", "Write output to file instead of stdout").option("--prefix <prefix>", "CSS/SCSS: prefix for variable names (e.g. 'scope')").option("--selector <selector>", "CSS: custom root selector (default: ':root')").option(
3347
3711
  "--theme <name>",
3348
3712
  "Include theme overrides for the named theme (applies to css, ts, scss, tailwind, figma)"
3349
3713
  ).action(
@@ -3404,7 +3768,7 @@ Available themes: ${themeNames.join(", ")}`
3404
3768
  themes: themesMap
3405
3769
  });
3406
3770
  if (opts.out !== void 0) {
3407
- const outPath = resolve8(process.cwd(), opts.out);
3771
+ const outPath = resolve9(process.cwd(), opts.out);
3408
3772
  writeFileSync6(outPath, output, "utf-8");
3409
3773
  process.stderr.write(`Exported ${tokens.length} tokens to ${outPath}
3410
3774
  `);
@@ -3445,21 +3809,21 @@ function buildTable2(headers, rows) {
3445
3809
  }
3446
3810
  function resolveTokenFilePath2(fileFlag) {
3447
3811
  if (fileFlag !== void 0) {
3448
- return resolve9(process.cwd(), fileFlag);
3812
+ return resolve10(process.cwd(), fileFlag);
3449
3813
  }
3450
- const configPath = resolve9(process.cwd(), CONFIG_FILE2);
3814
+ const configPath = resolve10(process.cwd(), CONFIG_FILE2);
3451
3815
  if (existsSync7(configPath)) {
3452
3816
  try {
3453
3817
  const raw = readFileSync6(configPath, "utf-8");
3454
3818
  const config = JSON.parse(raw);
3455
3819
  if (typeof config === "object" && config !== null && "tokens" in config && typeof config.tokens === "object" && config.tokens !== null && typeof config.tokens?.file === "string") {
3456
3820
  const file = config.tokens.file;
3457
- return resolve9(process.cwd(), file);
3821
+ return resolve10(process.cwd(), file);
3458
3822
  }
3459
3823
  } catch {
3460
3824
  }
3461
3825
  }
3462
- return resolve9(process.cwd(), DEFAULT_TOKEN_FILE2);
3826
+ return resolve10(process.cwd(), DEFAULT_TOKEN_FILE2);
3463
3827
  }
3464
3828
  function loadTokens(absPath) {
3465
3829
  if (!existsSync7(absPath)) {
@@ -3756,7 +4120,7 @@ function outputValidationResult(filePath, errors, useJson) {
3756
4120
  }
3757
4121
  }
3758
4122
  function createTokensCommand() {
3759
- const tokensCmd = new Command6("tokens").description(
4123
+ const tokensCmd = new Command7("tokens").description(
3760
4124
  "Query and validate design tokens from a reactscope.tokens.json file"
3761
4125
  );
3762
4126
  registerGet2(tokensCmd);
@@ -3770,7 +4134,7 @@ function createTokensCommand() {
3770
4134
 
3771
4135
  // src/program.ts
3772
4136
  function createProgram(options = {}) {
3773
- const program2 = new Command7("scope").version(options.version ?? "0.1.0").description("Scope \u2014 React instrumentation toolkit");
4137
+ const program2 = new Command8("scope").version(options.version ?? "0.1.0").description("Scope \u2014 React instrumentation toolkit");
3774
4138
  program2.command("capture <url>").description("Capture a React component tree from a live URL and output as JSON").option("-o, --output <path>", "Write JSON to file instead of stdout").option("--pretty", "Pretty-print JSON output (default: minified)", false).option("--timeout <ms>", "Max wait time for React to mount (ms)", "10000").option("--wait <ms>", "Additional wait after page load before capture (ms)", "0").action(
3775
4139
  async (url, opts) => {
3776
4140
  try {