simvyn 1.0.2 → 1.0.3

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.
@@ -89,6 +89,49 @@ function requireJsxRuntime() {
89
89
  return jsxRuntime.exports;
90
90
  }
91
91
  var jsxRuntimeExports = requireJsxRuntime();
92
+ const LOG_BUFFER_SIZE = 200;
93
+ const entries = [];
94
+ const originalLog = console.log;
95
+ const originalWarn = console.warn;
96
+ const originalError = console.error;
97
+ const originalInfo = console.info;
98
+ function capture(level, args) {
99
+ const message = args.map((a) => {
100
+ if (typeof a === "string") return a;
101
+ try {
102
+ return JSON.stringify(a);
103
+ } catch {
104
+ return String(a);
105
+ }
106
+ }).join(" ");
107
+ entries.push({ level, message, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
108
+ if (entries.length > LOG_BUFFER_SIZE) entries.shift();
109
+ }
110
+ console.log = (...args) => {
111
+ capture("log", args);
112
+ originalLog.apply(console, args);
113
+ };
114
+ console.warn = (...args) => {
115
+ capture("warn", args);
116
+ originalWarn.apply(console, args);
117
+ };
118
+ console.error = (...args) => {
119
+ capture("error", args);
120
+ originalError.apply(console, args);
121
+ };
122
+ console.info = (...args) => {
123
+ capture("info", args);
124
+ originalInfo.apply(console, args);
125
+ };
126
+ window.addEventListener("error", (e) => {
127
+ capture("error", [`Uncaught: ${e.message} at ${e.filename}:${e.lineno}:${e.colno}`]);
128
+ });
129
+ window.addEventListener("unhandledrejection", (e) => {
130
+ capture("error", [`Unhandled rejection: ${e.reason}`]);
131
+ });
132
+ function getConsoleLogs() {
133
+ return [...entries];
134
+ }
92
135
  var react = { exports: {} };
93
136
  var react_production = {};
94
137
  var hasRequiredReact_production;
@@ -14260,8 +14303,8 @@ function usePrefetchBehavior(prefetch, theirElementProps) {
14260
14303
  setShouldPrefetch(true);
14261
14304
  }
14262
14305
  if (prefetch === "viewport") {
14263
- let callback = (entries) => {
14264
- entries.forEach((entry) => {
14306
+ let callback = (entries2) => {
14307
+ entries2.forEach((entry) => {
14265
14308
  setShouldPrefetch(entry.isIntersecting);
14266
14309
  });
14267
14310
  };
@@ -18501,27 +18544,41 @@ const createLucideIcon = (iconName, iconNode) => {
18501
18544
  Component.displayName = toPascalCase(iconName);
18502
18545
  return Component;
18503
18546
  };
18504
- const __iconNode$M = [
18547
+ const __iconNode$P = [
18505
18548
  ["path", { d: "M12 5v14", key: "s699le" }],
18506
18549
  ["path", { d: "m19 12-7 7-7-7", key: "1idqje" }]
18507
18550
  ];
18508
- const ArrowDown = createLucideIcon("arrow-down", __iconNode$M);
18509
- const __iconNode$L = [
18551
+ const ArrowDown = createLucideIcon("arrow-down", __iconNode$P);
18552
+ const __iconNode$O = [
18510
18553
  ["path", { d: "m12 19-7-7 7-7", key: "1l729n" }],
18511
18554
  ["path", { d: "M19 12H5", key: "x3x0zl" }]
18512
18555
  ];
18513
- const ArrowLeft = createLucideIcon("arrow-left", __iconNode$L);
18514
- const __iconNode$K = [
18556
+ const ArrowLeft = createLucideIcon("arrow-left", __iconNode$O);
18557
+ const __iconNode$N = [
18515
18558
  ["path", { d: "m5 12 7-7 7 7", key: "hav0vg" }],
18516
18559
  ["path", { d: "M12 19V5", key: "x0mq9r" }]
18517
18560
  ];
18518
- const ArrowUp = createLucideIcon("arrow-up", __iconNode$K);
18519
- const __iconNode$J = [
18561
+ const ArrowUp = createLucideIcon("arrow-up", __iconNode$N);
18562
+ const __iconNode$M = [
18520
18563
  ["path", { d: "M 22 14 L 22 10", key: "nqc4tb" }],
18521
18564
  ["rect", { x: "2", y: "6", width: "16", height: "12", rx: "2", key: "13zb55" }]
18522
18565
  ];
18523
- const Battery = createLucideIcon("battery", __iconNode$J);
18524
- const __iconNode$I = [
18566
+ const Battery = createLucideIcon("battery", __iconNode$M);
18567
+ const __iconNode$L = [
18568
+ ["path", { d: "M12 20v-9", key: "1qisl0" }],
18569
+ ["path", { d: "M14 7a4 4 0 0 1 4 4v3a6 6 0 0 1-12 0v-3a4 4 0 0 1 4-4z", key: "uouzyp" }],
18570
+ ["path", { d: "M14.12 3.88 16 2", key: "qol33r" }],
18571
+ ["path", { d: "M21 21a4 4 0 0 0-3.81-4", key: "1b0z45" }],
18572
+ ["path", { d: "M21 5a4 4 0 0 1-3.55 3.97", key: "5cxbf6" }],
18573
+ ["path", { d: "M22 13h-4", key: "1jl80f" }],
18574
+ ["path", { d: "M3 21a4 4 0 0 1 3.81-4", key: "1fjd4g" }],
18575
+ ["path", { d: "M3 5a4 4 0 0 0 3.55 3.97", key: "1d7oge" }],
18576
+ ["path", { d: "M6 13H2", key: "82j7cp" }],
18577
+ ["path", { d: "m8 2 1.88 1.88", key: "fmnt4t" }],
18578
+ ["path", { d: "M9 7.13V6a3 3 0 1 1 6 0v1.13", key: "1vgav8" }]
18579
+ ];
18580
+ const Bug = createLucideIcon("bug", __iconNode$L);
18581
+ const __iconNode$K = [
18525
18582
  [
18526
18583
  "path",
18527
18584
  {
@@ -18531,47 +18588,47 @@ const __iconNode$I = [
18531
18588
  ],
18532
18589
  ["circle", { cx: "12", cy: "13", r: "3", key: "1vg3eu" }]
18533
18590
  ];
18534
- const Camera = createLucideIcon("camera", __iconNode$I);
18535
- const __iconNode$H = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
18536
- const Check = createLucideIcon("check", __iconNode$H);
18537
- const __iconNode$G = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
18538
- const ChevronDown = createLucideIcon("chevron-down", __iconNode$G);
18539
- const __iconNode$F = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
18540
- const ChevronLeft = createLucideIcon("chevron-left", __iconNode$F);
18541
- const __iconNode$E = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
18542
- const ChevronRight = createLucideIcon("chevron-right", __iconNode$E);
18543
- const __iconNode$D = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
18544
- const ChevronUp = createLucideIcon("chevron-up", __iconNode$D);
18545
- const __iconNode$C = [
18591
+ const Camera = createLucideIcon("camera", __iconNode$K);
18592
+ const __iconNode$J = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
18593
+ const Check = createLucideIcon("check", __iconNode$J);
18594
+ const __iconNode$I = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
18595
+ const ChevronDown = createLucideIcon("chevron-down", __iconNode$I);
18596
+ const __iconNode$H = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
18597
+ const ChevronLeft = createLucideIcon("chevron-left", __iconNode$H);
18598
+ const __iconNode$G = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
18599
+ const ChevronRight = createLucideIcon("chevron-right", __iconNode$G);
18600
+ const __iconNode$F = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
18601
+ const ChevronUp = createLucideIcon("chevron-up", __iconNode$F);
18602
+ const __iconNode$E = [
18546
18603
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
18547
18604
  ["path", { d: "M12 6v6l4 2", key: "mmk7yg" }]
18548
18605
  ];
18549
- const Clock = createLucideIcon("clock", __iconNode$C);
18550
- const __iconNode$B = [
18606
+ const Clock = createLucideIcon("clock", __iconNode$E);
18607
+ const __iconNode$D = [
18551
18608
  ["line", { x1: "15", x2: "15", y1: "12", y2: "18", key: "1p7wdc" }],
18552
18609
  ["line", { x1: "12", x2: "18", y1: "15", y2: "15", key: "1nscbv" }],
18553
18610
  ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
18554
18611
  ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
18555
18612
  ];
18556
- const CopyPlus = createLucideIcon("copy-plus", __iconNode$B);
18557
- const __iconNode$A = [
18613
+ const CopyPlus = createLucideIcon("copy-plus", __iconNode$D);
18614
+ const __iconNode$C = [
18558
18615
  ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
18559
18616
  ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
18560
18617
  ];
18561
- const Copy = createLucideIcon("copy", __iconNode$A);
18562
- const __iconNode$z = [
18618
+ const Copy = createLucideIcon("copy", __iconNode$C);
18619
+ const __iconNode$B = [
18563
18620
  ["ellipse", { cx: "12", cy: "5", rx: "9", ry: "3", key: "msslwz" }],
18564
18621
  ["path", { d: "M3 5V19A9 3 0 0 0 21 19V5", key: "1wlel7" }],
18565
18622
  ["path", { d: "M3 12A9 3 0 0 0 21 12", key: "mv7ke4" }]
18566
18623
  ];
18567
- const Database = createLucideIcon("database", __iconNode$z);
18568
- const __iconNode$y = [
18624
+ const Database = createLucideIcon("database", __iconNode$B);
18625
+ const __iconNode$A = [
18569
18626
  ["path", { d: "M12 15V3", key: "m9g1x1" }],
18570
18627
  ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
18571
18628
  ["path", { d: "m7 10 5 5 5-5", key: "brsn70" }]
18572
18629
  ];
18573
- const Download = createLucideIcon("download", __iconNode$y);
18574
- const __iconNode$x = [
18630
+ const Download = createLucideIcon("download", __iconNode$A);
18631
+ const __iconNode$z = [
18575
18632
  [
18576
18633
  "path",
18577
18634
  {
@@ -18581,14 +18638,14 @@ const __iconNode$x = [
18581
18638
  ],
18582
18639
  ["path", { d: "m5.082 11.09 8.828 8.828", key: "1wx5vj" }]
18583
18640
  ];
18584
- const Eraser = createLucideIcon("eraser", __iconNode$x);
18585
- const __iconNode$w = [
18641
+ const Eraser = createLucideIcon("eraser", __iconNode$z);
18642
+ const __iconNode$y = [
18586
18643
  ["path", { d: "M15 3h6v6", key: "1q9fwt" }],
18587
18644
  ["path", { d: "M10 14 21 3", key: "gplh6r" }],
18588
18645
  ["path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6", key: "a6xqqp" }]
18589
18646
  ];
18590
- const ExternalLink = createLucideIcon("external-link", __iconNode$w);
18591
- const __iconNode$v = [
18647
+ const ExternalLink = createLucideIcon("external-link", __iconNode$y);
18648
+ const __iconNode$x = [
18592
18649
  [
18593
18650
  "path",
18594
18651
  {
@@ -18600,8 +18657,8 @@ const __iconNode$v = [
18600
18657
  ["path", { d: "M12 18v-6", key: "17g6i2" }],
18601
18658
  ["path", { d: "m9 15 3 3 3-3", key: "1npd3o" }]
18602
18659
  ];
18603
- const FileDown = createLucideIcon("file-down", __iconNode$v);
18604
- const __iconNode$u = [
18660
+ const FileDown = createLucideIcon("file-down", __iconNode$x);
18661
+ const __iconNode$w = [
18605
18662
  [
18606
18663
  "path",
18607
18664
  {
@@ -18614,8 +18671,8 @@ const __iconNode$u = [
18614
18671
  ["path", { d: "M16 13H8", key: "t4e002" }],
18615
18672
  ["path", { d: "M16 17H8", key: "z1uh3a" }]
18616
18673
  ];
18617
- const FileText = createLucideIcon("file-text", __iconNode$u);
18618
- const __iconNode$t = [
18674
+ const FileText = createLucideIcon("file-text", __iconNode$w);
18675
+ const __iconNode$v = [
18619
18676
  [
18620
18677
  "path",
18621
18678
  {
@@ -18625,8 +18682,8 @@ const __iconNode$t = [
18625
18682
  ],
18626
18683
  ["path", { d: "M14 2v5a1 1 0 0 0 1 1h5", key: "wfsgrz" }]
18627
18684
  ];
18628
- const File = createLucideIcon("file", __iconNode$t);
18629
- const __iconNode$s = [
18685
+ const File = createLucideIcon("file", __iconNode$v);
18686
+ const __iconNode$u = [
18630
18687
  [
18631
18688
  "path",
18632
18689
  {
@@ -18635,13 +18692,34 @@ const __iconNode$s = [
18635
18692
  }
18636
18693
  ]
18637
18694
  ];
18638
- const Folder = createLucideIcon("folder", __iconNode$s);
18639
- const __iconNode$r = [
18695
+ const Folder = createLucideIcon("folder", __iconNode$u);
18696
+ const __iconNode$t = [
18697
+ [
18698
+ "path",
18699
+ {
18700
+ d: "M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4",
18701
+ key: "tonef"
18702
+ }
18703
+ ],
18704
+ ["path", { d: "M9 18c-4.51 2-5-2-7-2", key: "9comsn" }]
18705
+ ];
18706
+ const Github = createLucideIcon("github", __iconNode$t);
18707
+ const __iconNode$s = [
18640
18708
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
18641
18709
  ["path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", key: "13o1zl" }],
18642
18710
  ["path", { d: "M2 12h20", key: "9i4pu4" }]
18643
18711
  ];
18644
- const Globe = createLucideIcon("globe", __iconNode$r);
18712
+ const Globe = createLucideIcon("globe", __iconNode$s);
18713
+ const __iconNode$r = [
18714
+ [
18715
+ "path",
18716
+ {
18717
+ d: "M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5",
18718
+ key: "mvr1a0"
18719
+ }
18720
+ ]
18721
+ ];
18722
+ const Heart = createLucideIcon("heart", __iconNode$r);
18645
18723
  const __iconNode$q = [
18646
18724
  ["path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71", key: "1cjeqo" }],
18647
18725
  ["path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71", key: "19qd67" }]
@@ -24070,8 +24148,8 @@ function notifyTarget({ target, borderBoxSize }) {
24070
24148
  });
24071
24149
  });
24072
24150
  }
24073
- function notifyAll(entries) {
24074
- entries.forEach(notifyTarget);
24151
+ function notifyAll(entries2) {
24152
+ entries2.forEach(notifyTarget);
24075
24153
  }
24076
24154
  function createResizeObserver() {
24077
24155
  if (typeof ResizeObserver === "undefined")
@@ -28365,8 +28443,8 @@ const fireObserverCallback = (entry) => {
28365
28443
  const callback = observerCallbacks.get(entry.target);
28366
28444
  callback && callback(entry);
28367
28445
  };
28368
- const fireAllObserverCallbacks = (entries) => {
28369
- entries.forEach(fireObserverCallback);
28446
+ const fireAllObserverCallbacks = (entries2) => {
28447
+ entries2.forEach(fireObserverCallback);
28370
28448
  };
28371
28449
  function initIntersectionObserver({ root, ...options }) {
28372
28450
  const lookupRoot = root || document;
@@ -28953,6 +29031,19 @@ function TopBar() {
28953
29031
  }
28954
29032
  ),
28955
29033
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-4", children: [
29034
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
29035
+ "a",
29036
+ {
29037
+ href: "https://github.com/pranshuchittora/simvyn",
29038
+ target: "_blank",
29039
+ rel: "noopener noreferrer",
29040
+ className: "glass-star-button",
29041
+ children: [
29042
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Star, { size: 12 }),
29043
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Star on GitHub" })
29044
+ ]
29045
+ }
29046
+ ),
28956
29047
  /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: toggle, className: "cmdk-hint", children: [
28957
29048
  /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { size: 13 }),
28958
29049
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: isMac() ? "⌘K" : "Ctrl+K" })
@@ -45637,8 +45728,8 @@ const useLogStore = create((set) => ({
45637
45728
  setSearchPattern: (pattern) => set({ searchPattern: pattern }),
45638
45729
  setProcessFilter: (filter2) => set({ processFilter: filter2 })
45639
45730
  }));
45640
- function filterEntries(entries, enabledLevels, processFilter, searchPattern) {
45641
- let filtered = entries;
45731
+ function filterEntries(entries2, enabledLevels, processFilter, searchPattern) {
45732
+ let filtered = entries2;
45642
45733
  if (enabledLevels.length < ALL_LEVELS.length) {
45643
45734
  filtered = filtered.filter((e) => enabledLevels.includes(e.level));
45644
45735
  }
@@ -45690,18 +45781,18 @@ function LogList({ onLoadMore }) {
45690
45781
  () => filterEntries(allEntries, enabledLevels, processFilter, searchPattern),
45691
45782
  [allEntries, enabledLevels, processFilter, searchPattern]
45692
45783
  );
45693
- const entries = reactExports.useMemo(() => [...filtered].reverse(), [filtered]);
45784
+ const entries2 = reactExports.useMemo(() => [...filtered].reverse(), [filtered]);
45694
45785
  const firstItemIndex = useLogStore((s) => s.firstItemIndex);
45695
45786
  const hasMore = useLogStore((s) => s.hasMore);
45696
45787
  const isLoadingHistory = useLogStore((s) => s.isLoadingHistory);
45697
45788
  const jumpToBottom = reactExports.useCallback(() => {
45698
45789
  setLocked(true);
45699
45790
  virtuosoRef.current?.scrollToIndex({
45700
- index: entries.length - 1,
45791
+ index: entries2.length - 1,
45701
45792
  behavior: "auto"
45702
45793
  });
45703
- }, [entries.length]);
45704
- if (entries.length === 0) {
45794
+ }, [entries2.length]);
45795
+ if (entries2.length === 0) {
45705
45796
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "glass-empty-state h-full flex items-center justify-center", children: "No log entries" });
45706
45797
  }
45707
45798
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative h-full", children: [
@@ -45710,8 +45801,8 @@ function LogList({ onLoadMore }) {
45710
45801
  {
45711
45802
  ref: virtuosoRef,
45712
45803
  firstItemIndex,
45713
- initialTopMostItemIndex: entries.length - 1,
45714
- data: entries,
45804
+ initialTopMostItemIndex: entries2.length - 1,
45805
+ data: entries2,
45715
45806
  startReached: () => {
45716
45807
  if (hasMore && !isLoadingHistory) {
45717
45808
  onLoadMore();
@@ -45810,11 +45901,11 @@ function LogToolbar({ selectedDeviceId }) {
45810
45901
  const setSearchPattern = useLogStore((s) => s.setSearchPattern);
45811
45902
  const setProcessFilter = useLogStore((s) => s.setProcessFilter);
45812
45903
  const clear = useLogStore((s) => s.clear);
45813
- const entries = useLogStore((s) => s.entries);
45814
- const totalCount = entries.length;
45904
+ const entries2 = useLogStore((s) => s.entries);
45905
+ const totalCount = entries2.length;
45815
45906
  const filteredCount = reactExports.useMemo(
45816
- () => filterEntries(entries, enabledLevels, processFilter, searchPattern).length,
45817
- [entries, enabledLevels, processFilter, searchPattern]
45907
+ () => filterEntries(entries2, enabledLevels, processFilter, searchPattern).length,
45908
+ [entries2, enabledLevels, processFilter, searchPattern]
45818
45909
  );
45819
45910
  const searchTimer = reactExports.useRef(null);
45820
45911
  const handleSearch = reactExports.useCallback(
@@ -45826,16 +45917,16 @@ function LogToolbar({ selectedDeviceId }) {
45826
45917
  );
45827
45918
  const handleExport = reactExports.useCallback((format) => {
45828
45919
  const s = useLogStore.getState();
45829
- const entries2 = filterEntries(s.entries, s.enabledLevels, s.processFilter, s.searchPattern);
45920
+ const entries22 = filterEntries(s.entries, s.enabledLevels, s.processFilter, s.searchPattern);
45830
45921
  let content;
45831
45922
  let mime;
45832
45923
  let ext;
45833
45924
  if (format === "json") {
45834
- content = JSON.stringify(entries2, null, 2);
45925
+ content = JSON.stringify(entries22, null, 2);
45835
45926
  mime = "application/json";
45836
45927
  ext = "json";
45837
45928
  } else {
45838
- content = entries2.map(
45929
+ content = entries22.map(
45839
45930
  (e) => `[${e.timestamp}] [${e.level.toUpperCase().padEnd(7)}] ${e.processName}: ${e.message}`
45840
45931
  ).join("\n");
45841
45932
  mime = "text/plain";
@@ -46056,13 +46147,15 @@ function LogPanel() {
46056
46147
  ] });
46057
46148
  }
46058
46149
  registerPanel("logs", LogPanel);
46059
- const useScreenshotStore = create((set, get2) => ({
46150
+ const useScreenshotStore = create((set, _get) => ({
46060
46151
  captures: [],
46061
46152
  isRecording: {},
46062
46153
  loading: false,
46063
46154
  captureScreenshot: async (deviceId) => {
46064
46155
  try {
46065
- const res = await fetch(`/api/modules/screenshot/capture/${deviceId}`, { method: "POST" });
46156
+ const res = await fetch(`/api/modules/screenshot/capture/${deviceId}`, {
46157
+ method: "POST"
46158
+ });
46066
46159
  if (!res.ok) {
46067
46160
  const data2 = await res.json().catch(() => ({ error: "Capture failed" }));
46068
46161
  toast.error(data2.error || "Capture failed");
@@ -47160,7 +47253,7 @@ function formatDate(iso) {
47160
47253
  });
47161
47254
  }
47162
47255
  function FileBrowser({ deviceId, bundleId }) {
47163
- const entries = useFsStore((s) => s.entries);
47256
+ const entries2 = useFsStore((s) => s.entries);
47164
47257
  const currentPath = useFsStore((s) => s.currentPath);
47165
47258
  const loading = useFsStore((s) => s.loading);
47166
47259
  const error = useFsStore((s) => s.error);
@@ -47169,7 +47262,7 @@ function FileBrowser({ deviceId, bundleId }) {
47169
47262
  const uploadFile = useFsStore((s) => s.uploadFile);
47170
47263
  const openFile = useFsStore((s) => s.openFile);
47171
47264
  const fileInputRef = reactExports.useRef(null);
47172
- const sorted = [...entries].sort((a, b) => {
47265
+ const sorted = [...entries2].sort((a, b) => {
47173
47266
  if (a.isDirectory && !b.isDirectory) return -1;
47174
47267
  if (!a.isDirectory && b.isDirectory) return 1;
47175
47268
  return a.name.localeCompare(b.name);
@@ -47421,7 +47514,9 @@ const useDbStore = create((set, get2) => ({
47421
47514
  fetchTables: async (deviceId, bundleId, dbPath) => {
47422
47515
  set({ loading: true, selectedDb: dbPath });
47423
47516
  try {
47424
- const res = await fetch(`/api/modules/database/tables/${deviceId}/${bundleId}?db=${encodeURIComponent(dbPath)}`);
47517
+ const res = await fetch(
47518
+ `/api/modules/database/tables/${deviceId}/${bundleId}?db=${encodeURIComponent(dbPath)}`
47519
+ );
47425
47520
  if (!res.ok) {
47426
47521
  set({ loading: false });
47427
47522
  return;
@@ -47467,11 +47562,17 @@ const useDbStore = create((set, get2) => ({
47467
47562
  });
47468
47563
  const data = await res.json();
47469
47564
  if (!res.ok) {
47470
- set({ queryResult: { type: "error", message: data.error || "Query failed" }, loading: false });
47565
+ set({
47566
+ queryResult: { type: "error", message: data.error || "Query failed" },
47567
+ loading: false
47568
+ });
47471
47569
  return;
47472
47570
  }
47473
47571
  if (data.rows) {
47474
- set({ queryResult: { type: "rows", rows: data.rows, columns: data.columns }, loading: false });
47572
+ set({
47573
+ queryResult: { type: "rows", rows: data.rows, columns: data.columns },
47574
+ loading: false
47575
+ });
47475
47576
  } else {
47476
47577
  set({ queryResult: { type: "run", changes: data.changes ?? 0 }, loading: false });
47477
47578
  }
@@ -47617,8 +47718,8 @@ function PrefsViewer() {
47617
47718
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "glass-empty-state h-full flex items-center justify-center", children: "No preferences found" });
47618
47719
  }
47619
47720
  if (prefs.platform === "ios") {
47620
- const entries = Object.entries(prefs.prefs || {});
47621
- if (entries.length === 0) {
47721
+ const entries2 = Object.entries(prefs.prefs || {});
47722
+ if (entries2.length === 0) {
47622
47723
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "glass-empty-state", children: "No preferences found" });
47623
47724
  }
47624
47725
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "glass-table", children: [
@@ -47626,7 +47727,7 @@ function PrefsViewer() {
47626
47727
  /* @__PURE__ */ jsxRuntimeExports.jsx("th", { children: "Key" }),
47627
47728
  /* @__PURE__ */ jsxRuntimeExports.jsx("th", { children: "Value" })
47628
47729
  ] }) }),
47629
- /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: entries.map(([key, value]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { children: [
47730
+ /* @__PURE__ */ jsxRuntimeExports.jsx("tbody", { children: entries2.map(([key, value]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { children: [
47630
47731
  /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "text-text-primary text-xs font-mono", children: key }),
47631
47732
  /* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleValue, { value }) })
47632
47733
  ] }, key)) })
@@ -49910,6 +50011,12 @@ function ToolSettingsPanel() {
49910
50011
  });
49911
50012
  const [storage, setStorage] = reactExports.useState(null);
49912
50013
  const [saving, setSaving] = reactExports.useState(false);
50014
+ const [debugOpen, setDebugOpen] = reactExports.useState(false);
50015
+ const [consoleLogs, setConsoleLogs] = reactExports.useState([]);
50016
+ const [copied, setCopied] = reactExports.useState(false);
50017
+ const devices = useDeviceStore((s) => s.devices);
50018
+ const modules = useModuleStore((s) => s.modules);
50019
+ const version = modules[0]?.version ?? "unknown";
49913
50020
  const fetchStorage = reactExports.useCallback(() => {
49914
50021
  fetch("/api/tool-settings/storage").then((r) => r.json()).then((data) => setStorage(data)).catch(() => {
49915
50022
  });
@@ -49919,6 +50026,12 @@ function ToolSettingsPanel() {
49919
50026
  });
49920
50027
  fetchStorage();
49921
50028
  }, [fetchStorage]);
50029
+ reactExports.useEffect(() => {
50030
+ if (!debugOpen) return;
50031
+ setConsoleLogs(getConsoleLogs());
50032
+ const interval = setInterval(() => setConsoleLogs(getConsoleLogs()), 2e3);
50033
+ return () => clearInterval(interval);
50034
+ }, [debugOpen]);
49922
50035
  const saveConfig = async () => {
49923
50036
  setSaving(true);
49924
50037
  try {
@@ -49948,7 +50061,57 @@ function ToolSettingsPanel() {
49948
50061
  toast.error(err.message);
49949
50062
  }
49950
50063
  };
49951
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6 space-y-4", children: [
50064
+ const debugReport = reactExports.useMemo(() => {
50065
+ const ua = navigator.userAgent;
50066
+ const lines = [
50067
+ "## simvyn Debug Report",
50068
+ "",
50069
+ "### Environment",
50070
+ `- **simvyn version**: ${version}`,
50071
+ `- **Dashboard URL**: ${window.location.href}`,
50072
+ `- **User Agent**: ${ua}`,
50073
+ `- **Viewport**: ${window.innerWidth}x${window.innerHeight}`,
50074
+ `- **Server port**: ${config.port}`,
50075
+ `- **Polling interval**: ${config.pollInterval / 1e3}s`,
50076
+ "",
50077
+ "### Connected Devices"
50078
+ ];
50079
+ if (devices.length === 0) {
50080
+ lines.push("_No devices connected_");
50081
+ } else {
50082
+ lines.push("| Name | Platform | OS | State | Type |");
50083
+ lines.push("|------|----------|----|-------|------|");
50084
+ for (const d of devices) {
50085
+ lines.push(`| ${d.name} | ${d.platform} | ${d.osVersion} | ${d.state} | ${d.deviceType} |`);
50086
+ }
50087
+ }
50088
+ lines.push("", "### Loaded Modules");
50089
+ lines.push(modules.map((m2) => m2.name).join(", ") || "_None_");
50090
+ lines.push("", "### Console Logs (last 50)");
50091
+ lines.push("```");
50092
+ const recent = consoleLogs.slice(-50);
50093
+ for (const entry of recent) {
50094
+ const ts = entry.timestamp.split("T")[1]?.slice(0, 12) ?? entry.timestamp;
50095
+ lines.push(`[${ts}] [${entry.level.toUpperCase()}] ${entry.message}`);
50096
+ }
50097
+ if (recent.length === 0) lines.push("(no logs captured)");
50098
+ lines.push("```");
50099
+ return lines.join("\n");
50100
+ }, [version, config, devices, modules, consoleLogs]);
50101
+ const copyDebugReport = () => {
50102
+ navigator.clipboard.writeText(debugReport).then(() => {
50103
+ setCopied(true);
50104
+ toast.success("Debug report copied to clipboard");
50105
+ setTimeout(() => setCopied(false), 2e3);
50106
+ });
50107
+ };
50108
+ const logLevelColor = {
50109
+ error: "text-red-400",
50110
+ warn: "text-yellow-400",
50111
+ info: "text-blue-400",
50112
+ log: "text-text-muted"
50113
+ };
50114
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6 space-y-4 overflow-y-auto max-h-full", children: [
49952
50115
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-base font-medium text-text-primary", children: "Tool Settings" }) }),
49953
50116
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "glass-panel rounded-xl p-4 space-y-3", children: [
49954
50117
  /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-sm font-medium text-text-secondary uppercase tracking-wide", children: "Server Configuration" }),
@@ -49998,7 +50161,10 @@ function ToolSettingsPanel() {
49998
50161
  max: 30,
49999
50162
  step: 1,
50000
50163
  value: config.pollInterval / 1e3,
50001
- onChange: (e) => setConfig((c) => ({ ...c, pollInterval: Number(e.target.value) * 1e3 })),
50164
+ onChange: (e) => setConfig((c) => ({
50165
+ ...c,
50166
+ pollInterval: Number(e.target.value) * 1e3
50167
+ })),
50002
50168
  className: "w-28 accent-accent"
50003
50169
  }
50004
50170
  ),
@@ -50032,6 +50198,206 @@ function ToolSettingsPanel() {
50032
50198
  /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-sm font-medium text-text-secondary uppercase tracking-wide", children: "Data Management" }),
50033
50199
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-text-muted", children: "Delete all saved favorites, history, preferences, and captures" }),
50034
50200
  /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", onClick: wipeData, className: "glass-button-destructive", children: "Wipe All Data" })
50201
+ ] }),
50202
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "glass-panel rounded-xl p-4 space-y-3", children: [
50203
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-sm font-medium text-text-secondary uppercase tracking-wide", children: "About" }),
50204
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
50205
+ /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: "/icon-512.png", alt: "", className: "w-10 h-10 rounded-lg", draggable: false }),
50206
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
50207
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-text-primary", children: "simvyn" }),
50208
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-text-muted", children: [
50209
+ "v",
50210
+ version,
50211
+ " · MIT License"
50212
+ ] })
50213
+ ] })
50214
+ ] }),
50215
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-text-secondary", children: "Universal devtool for iOS Simulators & Android Emulators." }),
50216
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-text-muted", children: [
50217
+ "Built by",
50218
+ " ",
50219
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
50220
+ "a",
50221
+ {
50222
+ href: "https://github.com/pranshuchittora",
50223
+ target: "_blank",
50224
+ rel: "noopener noreferrer",
50225
+ className: "text-accent-blue hover:underline",
50226
+ children: "Pranshu Chittora"
50227
+ }
50228
+ )
50229
+ ] }),
50230
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 pt-1 flex-wrap", children: [
50231
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
50232
+ "a",
50233
+ {
50234
+ href: "https://github.com/pranshuchittora/simvyn",
50235
+ target: "_blank",
50236
+ rel: "noopener noreferrer",
50237
+ className: "glass-button inline-flex items-center gap-1.5",
50238
+ children: [
50239
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Github, { size: 12 }),
50240
+ "GitHub",
50241
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { size: 10, className: "opacity-50" })
50242
+ ]
50243
+ }
50244
+ ),
50245
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
50246
+ "a",
50247
+ {
50248
+ href: "https://github.com/pranshuchittora/simvyn/issues/new",
50249
+ target: "_blank",
50250
+ rel: "noopener noreferrer",
50251
+ className: "glass-button inline-flex items-center gap-1.5",
50252
+ children: [
50253
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Bug, { size: 12 }),
50254
+ "File an Issue",
50255
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { size: 10, className: "opacity-50" })
50256
+ ]
50257
+ }
50258
+ ),
50259
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
50260
+ "a",
50261
+ {
50262
+ href: "https://github.com/pranshuchittora/simvyn",
50263
+ target: "_blank",
50264
+ rel: "noopener noreferrer",
50265
+ className: "glass-button inline-flex items-center gap-1.5",
50266
+ children: [
50267
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Heart, { size: 12 }),
50268
+ "Star on GitHub",
50269
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { size: 10, className: "opacity-50" })
50270
+ ]
50271
+ }
50272
+ )
50273
+ ] })
50274
+ ] }),
50275
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "glass-panel rounded-xl overflow-hidden", children: [
50276
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
50277
+ "button",
50278
+ {
50279
+ type: "button",
50280
+ onClick: () => setDebugOpen((o) => !o),
50281
+ className: "w-full flex items-center justify-between p-4 hover:bg-white/[0.02] transition-colors cursor-pointer bg-transparent border-none text-left",
50282
+ children: [
50283
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-sm font-medium text-text-secondary uppercase tracking-wide", children: "Debug Information" }),
50284
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
50285
+ ChevronDown,
50286
+ {
50287
+ size: 14,
50288
+ className: `text-text-muted transition-transform duration-200 ${debugOpen ? "rotate-180" : ""}`
50289
+ }
50290
+ )
50291
+ ]
50292
+ }
50293
+ ),
50294
+ debugOpen && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 pb-4 space-y-4 border-t border-glass-border", children: [
50295
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] text-text-muted pt-3", children: "Useful when filing a bug report. Copy and paste into the issue." }),
50296
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5", children: [
50297
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-xs font-medium text-text-secondary", children: "Environment" }),
50298
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-[auto_1fr] gap-x-4 gap-y-1 text-xs", children: [
50299
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-text-muted", children: "Version" }),
50300
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-text-primary font-mono", children: [
50301
+ "v",
50302
+ version
50303
+ ] }),
50304
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-text-muted", children: "Browser" }),
50305
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-text-primary font-mono truncate", children: navigator.userAgent }),
50306
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-text-muted", children: "Viewport" }),
50307
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-text-primary font-mono", children: [
50308
+ window.innerWidth,
50309
+ "x",
50310
+ window.innerHeight
50311
+ ] }),
50312
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-text-muted", children: "Server" }),
50313
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-text-primary font-mono", children: [
50314
+ ":",
50315
+ config.port,
50316
+ " (poll: ",
50317
+ config.pollInterval / 1e3,
50318
+ "s)"
50319
+ ] })
50320
+ ] })
50321
+ ] }),
50322
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5", children: [
50323
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-xs font-medium text-text-secondary", children: [
50324
+ "Connected Devices (",
50325
+ devices.length,
50326
+ ")"
50327
+ ] }),
50328
+ devices.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-text-muted italic", children: "No devices connected" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1", children: devices.map((d) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
50329
+ "div",
50330
+ {
50331
+ className: "flex items-center gap-2 text-xs bg-white/[0.02] rounded-lg px-2.5 py-1.5",
50332
+ children: [
50333
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
50334
+ "span",
50335
+ {
50336
+ className: `h-1.5 w-1.5 rounded-full ${d.state === "booted" ? "bg-green-500" : "bg-text-muted"}`
50337
+ }
50338
+ ),
50339
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-text-primary font-medium", children: d.name }),
50340
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-text-muted", children: [
50341
+ d.platform,
50342
+ " ",
50343
+ d.osVersion
50344
+ ] }),
50345
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-text-muted ml-auto", children: d.deviceType })
50346
+ ]
50347
+ },
50348
+ d.id
50349
+ )) })
50350
+ ] }),
50351
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5", children: [
50352
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-xs font-medium text-text-secondary", children: [
50353
+ "Loaded Modules (",
50354
+ modules.length,
50355
+ ")"
50356
+ ] }),
50357
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-1", children: modules.map((m2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
50358
+ "span",
50359
+ {
50360
+ className: "glass-badge border-glass-border text-text-muted bg-white/[0.03]",
50361
+ children: m2.name
50362
+ },
50363
+ m2.name
50364
+ )) })
50365
+ ] }),
50366
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5", children: [
50367
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-xs font-medium text-text-secondary", children: [
50368
+ "Console Logs (",
50369
+ consoleLogs.length,
50370
+ ")"
50371
+ ] }),
50372
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-h-48 overflow-y-auto rounded-lg bg-black/20 p-2 font-mono text-[10px] leading-relaxed space-y-px", children: consoleLogs.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-text-muted italic p-2", children: "No logs captured" }) : consoleLogs.slice(-100).map((entry) => {
50373
+ const ts = entry.timestamp.split("T")[1]?.slice(0, 12) ?? entry.timestamp;
50374
+ const key = `${entry.timestamp}-${entry.level}-${entry.message.slice(0, 40)}`;
50375
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1.5 hover:bg-white/[0.02]", children: [
50376
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-text-muted shrink-0", children: ts }),
50377
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
50378
+ "span",
50379
+ {
50380
+ className: `shrink-0 uppercase w-10 ${logLevelColor[entry.level] ?? "text-text-muted"}`,
50381
+ children: entry.level
50382
+ }
50383
+ ),
50384
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-text-primary break-all", children: entry.message })
50385
+ ] }, key);
50386
+ }) })
50387
+ ] }),
50388
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
50389
+ "button",
50390
+ {
50391
+ type: "button",
50392
+ onClick: copyDebugReport,
50393
+ className: "glass-button-primary inline-flex items-center gap-1.5",
50394
+ children: [
50395
+ copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 12 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 12 }),
50396
+ copied ? "Copied!" : "Copy Debug Report"
50397
+ ]
50398
+ }
50399
+ )
50400
+ ] })
50035
50401
  ] })
50036
50402
  ] });
50037
50403
  }
@@ -50122,4 +50488,4 @@ function App() {
50122
50488
  clientExports.createRoot(document.getElementById("root")).render(
50123
50489
  /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.StrictMode, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(App, {}) })
50124
50490
  );
50125
- //# sourceMappingURL=index-CDbr1wGz.js.map
50491
+ //# sourceMappingURL=index-Du0XWZXh.js.map