uidex 0.5.2 → 0.7.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.
Files changed (39) hide show
  1. package/README.md +3 -3
  2. package/dist/cli/cli.cjs +1542 -1227
  3. package/dist/cli/cli.cjs.map +1 -1
  4. package/dist/cloud/index.cjs +385 -175
  5. package/dist/cloud/index.cjs.map +1 -1
  6. package/dist/cloud/index.d.cts +192 -4
  7. package/dist/cloud/index.d.ts +192 -4
  8. package/dist/cloud/index.js +377 -177
  9. package/dist/cloud/index.js.map +1 -1
  10. package/dist/headless/index.cjs +116 -251
  11. package/dist/headless/index.cjs.map +1 -1
  12. package/dist/headless/index.d.cts +6 -11
  13. package/dist/headless/index.d.ts +6 -11
  14. package/dist/headless/index.js +116 -253
  15. package/dist/headless/index.js.map +1 -1
  16. package/dist/index.cjs +776 -1055
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +152 -160
  19. package/dist/index.d.ts +152 -160
  20. package/dist/index.js +792 -1066
  21. package/dist/index.js.map +1 -1
  22. package/dist/react/index.cjs +801 -1019
  23. package/dist/react/index.cjs.map +1 -1
  24. package/dist/react/index.d.cts +102 -86
  25. package/dist/react/index.d.ts +102 -86
  26. package/dist/react/index.js +821 -1038
  27. package/dist/react/index.js.map +1 -1
  28. package/dist/scan/index.cjs +1550 -1220
  29. package/dist/scan/index.cjs.map +1 -1
  30. package/dist/scan/index.d.cts +210 -12
  31. package/dist/scan/index.d.ts +210 -12
  32. package/dist/scan/index.js +1547 -1219
  33. package/dist/scan/index.js.map +1 -1
  34. package/package.json +22 -21
  35. package/templates/claude/SKILL.md +71 -0
  36. package/templates/claude/references/audit.md +43 -0
  37. package/templates/claude/{rules.md → references/conventions.md} +25 -28
  38. package/templates/claude/audit.md +0 -43
  39. /package/templates/claude/{api.md → references/api.md} +0 -0
@@ -18,11 +18,6 @@ function isMetaEntity(entity) {
18
18
  function entityKey(entity) {
19
19
  return entity.kind === "route" ? entity.path : entity.id;
20
20
  }
21
- function sameRef(a, b) {
22
- if (a === b) return true;
23
- if (a === null || b === null) return false;
24
- return a.kind === b.kind && a.id === b.id;
25
- }
26
21
  var UnknownEntityKindError = class extends Error {
27
22
  kind;
28
23
  constructor(kind) {
@@ -67,6 +62,7 @@ function freezeEntity(entity, flows) {
67
62
  function createRegistry() {
68
63
  const store = emptyStore();
69
64
  let flowsCache = null;
65
+ const patternCache = /* @__PURE__ */ new Map();
70
66
  const getFlows = () => {
71
67
  if (flowsCache === null) flowsCache = Array.from(store.flow.values());
72
68
  return flowsCache;
@@ -76,6 +72,7 @@ function createRegistry() {
76
72
  const key = entityKey(entity);
77
73
  store[entity.kind].set(key, entity);
78
74
  flowsCache = null;
75
+ patternCache.delete(entity.kind);
79
76
  };
80
77
  const get = (kind, id) => {
81
78
  assertEntityKind(kind);
@@ -83,6 +80,51 @@ function createRegistry() {
83
80
  if (raw === void 0) return void 0;
84
81
  return freezeEntity(raw, getFlows());
85
82
  };
83
+ const getPatternsForKind = (kind) => {
84
+ const cached = patternCache.get(kind);
85
+ if (cached !== void 0) return cached;
86
+ const patterns = [];
87
+ for (const [key, entity] of store[kind]) {
88
+ if (key.includes("*")) {
89
+ const segments = key.split("*");
90
+ patterns.push({
91
+ segments,
92
+ staticLength: segments.reduce((n, s) => n + s.length, 0),
93
+ entity
94
+ });
95
+ }
96
+ }
97
+ patternCache.set(
98
+ kind,
99
+ patterns
100
+ );
101
+ return patterns;
102
+ };
103
+ const matchesSegments = (segments, id) => {
104
+ const first = segments[0];
105
+ const last = segments[segments.length - 1];
106
+ if (!id.startsWith(first)) return false;
107
+ let pos = first.length;
108
+ for (let i = 1; i < segments.length - 1; i++) {
109
+ const idx = id.indexOf(segments[i], pos);
110
+ if (idx === -1) return false;
111
+ pos = idx + segments[i].length;
112
+ }
113
+ return id.endsWith(last) && id.length - last.length >= pos;
114
+ };
115
+ const matchPattern = (kind, id) => {
116
+ assertEntityKind(kind);
117
+ const patterns = getPatternsForKind(kind);
118
+ if (patterns.length === 0) return void 0;
119
+ let best;
120
+ for (const entry of patterns) {
121
+ if (matchesSegments(entry.segments, id) && (best === void 0 || entry.staticLength > best.staticLength)) {
122
+ best = entry;
123
+ }
124
+ }
125
+ if (best === void 0) return void 0;
126
+ return freezeEntity(best.entity, getFlows());
127
+ };
86
128
  const list = (kind) => {
87
129
  assertEntityKind(kind);
88
130
  const flows = getFlows();
@@ -133,6 +175,7 @@ function createRegistry() {
133
175
  return {
134
176
  add,
135
177
  get,
178
+ matchPattern,
136
179
  list,
137
180
  query,
138
181
  byScope,
@@ -266,8 +309,7 @@ var COMMAND_PALETTE_ENTRY = {
266
309
  function createModeStore(options) {
267
310
  const { nav, bindings } = options;
268
311
  const store = createStore(() => ({
269
- mode: "idle",
270
- inspectorActive: false
312
+ mode: "idle"
271
313
  }));
272
314
  const transition = {
273
315
  openPalette() {
@@ -276,17 +318,17 @@ function createModeStore(options) {
276
318
  bindings?.destroyInspector?.();
277
319
  }
278
320
  nav.nav.reset([COMMAND_PALETTE_ENTRY]);
279
- store.setState({ mode: "palette", inspectorActive: false });
321
+ store.setState({ mode: "palette" });
280
322
  },
281
323
  openInspector() {
282
324
  bindings?.mountInspector?.();
283
325
  nav.nav.clear();
284
- store.setState({ mode: "inspecting", inspectorActive: true });
326
+ store.setState({ mode: "inspecting" });
285
327
  },
286
328
  closeInspector() {
287
329
  bindings?.destroyInspector?.();
288
330
  nav.nav.clear();
289
- store.setState({ mode: "idle", inspectorActive: false });
331
+ store.setState({ mode: "idle" });
290
332
  },
291
333
  toggleInspector() {
292
334
  if (store.getState().mode === "inspecting") {
@@ -301,7 +343,7 @@ function createModeStore(options) {
301
343
  bindings?.destroyInspector?.();
302
344
  }
303
345
  nav.nav.reset(initialStack);
304
- store.setState({ mode: "viewing", inspectorActive: false });
346
+ store.setState({ mode: "viewing" });
305
347
  },
306
348
  dismiss() {
307
349
  const prev = store.getState();
@@ -309,7 +351,7 @@ function createModeStore(options) {
309
351
  bindings?.destroyInspector?.();
310
352
  }
311
353
  nav.nav.clear();
312
- store.setState({ mode: "idle", inspectorActive: false });
354
+ store.setState({ mode: "idle" });
313
355
  },
314
356
  popOrTransition() {
315
357
  const { stack } = nav.getState();
@@ -317,12 +359,12 @@ function createModeStore(options) {
317
359
  nav.nav.pop();
318
360
  } else if (stack.length === 2 && stack[0]?.id === "command-palette") {
319
361
  nav.nav.reset([COMMAND_PALETTE_ENTRY]);
320
- store.setState({ mode: "palette", inspectorActive: false });
362
+ store.setState({ mode: "palette" });
321
363
  } else if (stack.length === 2) {
322
364
  nav.nav.pop();
323
365
  } else {
324
366
  nav.nav.clear();
325
- store.setState({ mode: "idle", inspectorActive: false });
367
+ store.setState({ mode: "idle" });
326
368
  }
327
369
  },
328
370
  pushView(entry) {
@@ -339,7 +381,7 @@ function createModeStore(options) {
339
381
  case "inspecting":
340
382
  bindings?.destroyInspector?.();
341
383
  nav.nav.reset([entry]);
342
- store.setState({ mode: "viewing", inspectorActive: false });
384
+ store.setState({ mode: "viewing" });
343
385
  break;
344
386
  case "palette":
345
387
  case "viewing":
@@ -374,14 +416,6 @@ function createNavigationStore() {
374
416
  store.setState({ stack: s.slice(0, -1) });
375
417
  }
376
418
  },
377
- replace(entry) {
378
- const s = store.getState().stack;
379
- if (s.length === 0) {
380
- store.setState({ stack: [entry] });
381
- } else {
382
- store.setState({ stack: [...s.slice(0, -1), entry] });
383
- }
384
- },
385
419
  clear() {
386
420
  store.setState({ stack: [] });
387
421
  },
@@ -396,14 +430,11 @@ function createNavigationStore() {
396
430
 
397
431
  // src/browser/session/store.ts
398
432
  var defaultSnapshot = {
399
- hover: null,
400
- selection: null,
401
433
  stack: [],
402
434
  pinnedHighlight: null,
403
- inspectorActive: false,
435
+ mode: "idle",
404
436
  theme: "auto",
405
437
  resolvedTheme: "light",
406
- ingestActive: false,
407
438
  user: null
408
439
  };
409
440
  function resolveTheme(preference, detect) {
@@ -454,7 +485,6 @@ function createSession(options = {}) {
454
485
  } else if (highlightMode === "transient") {
455
486
  onUpdateOverlay?.(hlCtx);
456
487
  }
457
- store.setState({ hover: ref });
458
488
  },
459
489
  unhover() {
460
490
  if (highlightMode === "transient") {
@@ -464,7 +494,6 @@ function createSession(options = {}) {
464
494
  hlCtx.color = null;
465
495
  onHideOverlay?.();
466
496
  }
467
- store.setState({ hover: null });
468
497
  },
469
498
  pin(ref) {
470
499
  const pinRef = ref ?? hlCtx.ref;
@@ -492,14 +521,11 @@ function createSession(options = {}) {
492
521
  };
493
522
  const store = createStore3(() => ({
494
523
  ...defaultSnapshot,
495
- hover: overrides.hover ?? null,
496
- selection: overrides.selection ?? null,
497
524
  stack: [],
498
525
  pinnedHighlight: null,
499
- inspectorActive: false,
526
+ mode: "idle",
500
527
  theme: initialPref,
501
528
  resolvedTheme: initialResolved,
502
- ingestActive: overrides.ingestActive ?? false,
503
529
  user: overrides.user ?? null
504
530
  }));
505
531
  nav.subscribe(() => {
@@ -509,29 +535,21 @@ function createSession(options = {}) {
509
535
  }
510
536
  });
511
537
  modeStore.subscribe(() => {
512
- const { inspectorActive } = modeStore.getState();
513
- if (store.getState().inspectorActive !== inspectorActive) {
514
- store.setState({ inspectorActive });
538
+ const { mode } = modeStore.getState();
539
+ if (store.getState().mode !== mode) {
540
+ store.setState({ mode });
515
541
  }
516
542
  });
517
543
  const session = store;
518
544
  session.nav = nav;
519
545
  session.mode = modeStore;
520
546
  session.highlight = highlightActions;
521
- session.select = (ref) => {
522
- if (sameRef(store.getState().selection, ref)) return;
523
- store.setState({ selection: ref });
524
- };
525
547
  session.setTheme = (theme, resolved) => {
526
548
  const state = store.getState();
527
549
  const nextResolved = resolved ?? resolveTheme(theme, detectTheme);
528
550
  if (state.theme === theme && state.resolvedTheme === nextResolved) return;
529
551
  store.setState({ theme, resolvedTheme: nextResolved });
530
552
  };
531
- session.setIngest = (active) => {
532
- if (store.getState().ingestActive === active) return;
533
- store.setState({ ingestActive: active });
534
- };
535
553
  if (initialStack.length > 0) {
536
554
  modeStore.transition.openPalette();
537
555
  for (let i = 1; i < initialStack.length; i++) {
@@ -823,6 +841,9 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
823
841
  .relative {
824
842
  position: relative;
825
843
  }
844
+ .static {
845
+ position: static;
846
+ }
826
847
  .inset-0 {
827
848
  inset: calc(var(--spacing) * 0);
828
849
  }
@@ -841,9 +862,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
841
862
  .right-0 {
842
863
  right: calc(var(--spacing) * 0);
843
864
  }
844
- .right-2 {
845
- right: calc(var(--spacing) * 2);
846
- }
847
865
  .bottom-full {
848
866
  bottom: 100%;
849
867
  }
@@ -886,9 +904,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
886
904
  .mx-2 {
887
905
  margin-inline: calc(var(--spacing) * 2);
888
906
  }
889
- .my-1 {
890
- margin-block: calc(var(--spacing) * 1);
891
- }
892
907
  .ms-auto {
893
908
  margin-inline-start: auto;
894
909
  }
@@ -925,9 +940,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
925
940
  .inline-flex {
926
941
  display: inline-flex;
927
942
  }
928
- .list-item {
929
- display: list-item;
930
- }
931
943
  .table {
932
944
  display: table;
933
945
  }
@@ -935,10 +947,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
935
947
  width: calc(var(--spacing) * 2);
936
948
  height: calc(var(--spacing) * 2);
937
949
  }
938
- .size-3 {
939
- width: calc(var(--spacing) * 3);
940
- height: calc(var(--spacing) * 3);
941
- }
942
950
  .size-3\\.5 {
943
951
  width: calc(var(--spacing) * 3.5);
944
952
  height: calc(var(--spacing) * 3.5);
@@ -996,15 +1004,9 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
996
1004
  .h-\\[26rem\\] {
997
1005
  height: 26rem;
998
1006
  }
999
- .h-auto {
1000
- height: auto;
1001
- }
1002
1007
  .h-full {
1003
1008
  height: 100%;
1004
1009
  }
1005
- .h-px {
1006
- height: 1px;
1007
- }
1008
1010
  .max-h-32 {
1009
1011
  max-height: calc(var(--spacing) * 32);
1010
1012
  }
@@ -1014,9 +1016,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1014
1016
  .min-h-0 {
1015
1017
  min-height: calc(var(--spacing) * 0);
1016
1018
  }
1017
- .min-h-7 {
1018
- min-height: calc(var(--spacing) * 7);
1019
- }
1020
1019
  .min-h-8 {
1021
1020
  min-height: calc(var(--spacing) * 8);
1022
1021
  }
@@ -1041,9 +1040,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1041
1040
  .w-56 {
1042
1041
  width: calc(var(--spacing) * 56);
1043
1042
  }
1044
- .w-auto {
1045
- width: auto;
1046
- }
1047
1043
  .w-full {
1048
1044
  width: 100%;
1049
1045
  }
@@ -1118,9 +1114,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1118
1114
  .animate-spin {
1119
1115
  animation: var(--animate-spin);
1120
1116
  }
1121
- .cursor-default {
1122
- cursor: default;
1123
- }
1124
1117
  .cursor-pointer {
1125
1118
  cursor: pointer;
1126
1119
  }
@@ -1130,9 +1123,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1130
1123
  .scroll-py-2 {
1131
1124
  scroll-padding-block: calc(var(--spacing) * 2);
1132
1125
  }
1133
- .list-none {
1134
- list-style-type: none;
1135
- }
1136
1126
  .appearance-none {
1137
1127
  appearance: none;
1138
1128
  }
@@ -1154,9 +1144,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1154
1144
  .justify-center {
1155
1145
  justify-content: center;
1156
1146
  }
1157
- .justify-start {
1158
- justify-content: flex-start;
1159
- }
1160
1147
  .gap-0 {
1161
1148
  gap: calc(var(--spacing) * 0);
1162
1149
  }
@@ -1181,9 +1168,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1181
1168
  .gap-6 {
1182
1169
  gap: calc(var(--spacing) * 6);
1183
1170
  }
1184
- .self-start {
1185
- align-self: flex-start;
1186
- }
1187
1171
  .truncate {
1188
1172
  overflow: hidden;
1189
1173
  text-overflow: ellipsis;
@@ -1398,9 +1382,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1398
1382
  .p-6 {
1399
1383
  padding: calc(var(--spacing) * 6);
1400
1384
  }
1401
- .px-0 {
1402
- padding-inline: calc(var(--spacing) * 0);
1403
- }
1404
1385
  .px-1 {
1405
1386
  padding-inline: calc(var(--spacing) * 1);
1406
1387
  }
@@ -1425,9 +1406,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1425
1406
  .px-6 {
1426
1407
  padding-inline: calc(var(--spacing) * 6);
1427
1408
  }
1428
- .py-0 {
1429
- padding-block: calc(var(--spacing) * 0);
1430
- }
1431
1409
  .py-1 {
1432
1410
  padding-block: calc(var(--spacing) * 1);
1433
1411
  }
@@ -1500,9 +1478,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1500
1478
  .text-\\[9px\\] {
1501
1479
  font-size: 9px;
1502
1480
  }
1503
- .text-\\[10px\\] {
1504
- font-size: 10px;
1505
- }
1506
1481
  .text-\\[11px\\] {
1507
1482
  font-size: 11px;
1508
1483
  }
@@ -1742,10 +1717,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1742
1717
  outline-style: var(--tw-outline-style);
1743
1718
  outline-width: 1px;
1744
1719
  }
1745
- .blur {
1746
- --tw-blur: blur(8px);
1747
- filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
1748
- }
1749
1720
  .filter {
1750
1721
  filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
1751
1722
  }
@@ -1911,25 +1882,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1911
1882
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
1912
1883
  }
1913
1884
  }
1914
- .focus-within\\:border-ring {
1915
- &:focus-within {
1916
- border-color: var(--ring);
1917
- }
1918
- }
1919
- .focus-within\\:ring-\\[3px\\] {
1920
- &:focus-within {
1921
- --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
1922
- box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
1923
- }
1924
- }
1925
- .focus-within\\:ring-ring\\/30 {
1926
- &:focus-within {
1927
- --tw-ring-color: var(--ring);
1928
- @supports (color: color-mix(in lab, red, red)) {
1929
- --tw-ring-color: color-mix(in oklab, var(--ring) 30%, transparent);
1930
- }
1931
- }
1932
- }
1933
1885
  .hover\\:border-destructive\\/30 {
1934
1886
  &:hover {
1935
1887
  @media (hover: hover) {
@@ -2073,11 +2025,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
2073
2025
  pointer-events: none;
2074
2026
  }
2075
2027
  }
2076
- .disabled\\:cursor-not-allowed {
2077
- &:disabled {
2078
- cursor: not-allowed;
2079
- }
2080
- }
2081
2028
  .disabled\\:opacity-50 {
2082
2029
  &:disabled {
2083
2030
  opacity: 50%;
@@ -2088,11 +2035,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
2088
2035
  opacity: 60%;
2089
2036
  }
2090
2037
  }
2091
- .has-disabled\\:opacity-60 {
2092
- &:has(*:disabled) {
2093
- opacity: 60%;
2094
- }
2095
- }
2096
2038
  .aria-invalid\\:border-destructive\\/40 {
2097
2039
  &[aria-invalid="true"] {
2098
2040
  border-color: var(--destructive);
@@ -2499,32 +2441,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
2499
2441
  height: calc(var(--spacing) * 4.5);
2500
2442
  }
2501
2443
  }
2502
- .\\[\\&\\>svg\\]\\:pointer-events-none {
2503
- &>svg {
2504
- pointer-events: none;
2505
- }
2506
- }
2507
- .\\[\\&\\>svg\\]\\:-mx-0\\.5 {
2508
- &>svg {
2509
- margin-inline: calc(var(--spacing) * -0.5);
2510
- }
2511
- }
2512
- .\\[\\&\\>svg\\]\\:shrink-0 {
2513
- &>svg {
2514
- flex-shrink: 0;
2515
- }
2516
- }
2517
- .\\[\\&\\>svg\\:not\\(\\[class\\*\\=\\'opacity-\\'\\]\\)\\]\\:opacity-80 {
2518
- &>svg:not([class*='opacity-']) {
2519
- opacity: 80%;
2520
- }
2521
- }
2522
- .\\[\\&\\>svg\\:not\\(\\[class\\*\\=\\'size-\\'\\]\\)\\]\\:size-4 {
2523
- &>svg:not([class*='size-']) {
2524
- width: calc(var(--spacing) * 4);
2525
- height: calc(var(--spacing) * 4);
2526
- }
2527
- }
2528
2444
  .\\[\\[data-kbd-nav\\]_\\&\\]\\:focus-within\\:bg-accent {
2529
2445
  [data-kbd-nav] & {
2530
2446
  &:focus-within {
@@ -3086,11 +3002,10 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
3086
3002
 
3087
3003
  // src/browser/surface/constants.ts
3088
3004
  var SURFACE_HOST_CLASS = "uidex-surface-host";
3089
- var SURFACE_CONTAINER_CLASS = "uidex-container";
3090
3005
  var Z_BASE = 2147483630;
3091
3006
  var Z_OVERLAY = 2147483635;
3092
3007
  var Z_CHROME = 2147483645;
3093
- var SURFACE_IGNORE_SELECTOR = `.${SURFACE_HOST_CLASS},.${SURFACE_CONTAINER_CLASS}`;
3008
+ var SURFACE_IGNORE_SELECTOR = `.${SURFACE_HOST_CLASS}`;
3094
3009
  var UIDEX_ATTR_TO_KIND = [
3095
3010
  ["data-uidex", "element"],
3096
3011
  ["data-uidex-region", "region"],
@@ -3274,7 +3189,7 @@ function createCursorTooltip(deps) {
3274
3189
  // src/browser/surface/inspector.ts
3275
3190
  function entityForRef(ref, registry) {
3276
3191
  if (registry) {
3277
- const found = registry.get(ref.kind, ref.id);
3192
+ const found = registry.get(ref.kind, ref.id) ?? registry.matchPattern?.(ref.kind, ref.id);
3278
3193
  if (found) return found;
3279
3194
  }
3280
3195
  if (ref.kind === "route") return { kind: "route", path: ref.id, page: ref.id };
@@ -3377,7 +3292,6 @@ function createInspector(options) {
3377
3292
  e.preventDefault();
3378
3293
  e.stopPropagation();
3379
3294
  const match = stack[layerIndex];
3380
- session.select(match.ref);
3381
3295
  onSelect?.(match, { x: e.clientX, y: e.clientY });
3382
3296
  };
3383
3297
  const onContextMenu = (e) => {
@@ -3426,8 +3340,6 @@ function createInspector(options) {
3426
3340
 
3427
3341
  // src/browser/surface/menu-bar.ts
3428
3342
  import {
3429
- ChevronLeft,
3430
- ChevronRight,
3431
3343
  Command,
3432
3344
  Highlighter,
3433
3345
  MapPin,
@@ -3583,49 +3495,12 @@ function createMenuBar(options) {
3583
3495
  },
3584
3496
  pinIcon
3585
3497
  );
3586
- const commitCycler = el("div", {
3587
- class: "relative z-1 inline-flex items-center gap-0.5",
3588
- attrs: { "data-uidex-menubar-commit-cycler": "" }
3589
- });
3590
- commitCycler.hidden = true;
3591
- const prevIcon = createLucideElement2(ChevronLeft);
3592
- prevIcon.setAttribute("class", "size-3");
3593
- prevIcon.setAttribute("aria-hidden", "true");
3594
- const prevBtn = el(
3595
- "button",
3596
- {
3597
- class: BUTTON_CLASS,
3598
- attrs: { type: "button", "aria-label": "Previous commit" },
3599
- style: { width: "18px", height: "18px" }
3600
- },
3601
- prevIcon
3602
- );
3603
- const commitLabel = el("span", {
3604
- class: "relative z-1 whitespace-nowrap px-1 text-[10px] font-mono text-muted-foreground",
3605
- attrs: { "data-uidex-menubar-commit-label": "" }
3606
- });
3607
- const nextIcon = createLucideElement2(ChevronRight);
3608
- nextIcon.setAttribute("class", "size-3");
3609
- nextIcon.setAttribute("aria-hidden", "true");
3610
- const nextBtn = el(
3611
- "button",
3612
- {
3613
- class: BUTTON_CLASS,
3614
- attrs: { type: "button", "aria-label": "Next commit" },
3615
- style: { width: "18px", height: "18px" }
3616
- },
3617
- nextIcon
3618
- );
3619
- commitCycler.appendChild(prevBtn);
3620
- commitCycler.appendChild(commitLabel);
3621
- commitCycler.appendChild(nextBtn);
3622
3498
  const pinWrapper = el("div", {
3623
3499
  class: "relative z-1 inline-flex items-center gap-0.5",
3624
3500
  attrs: { "data-uidex-menubar-pin-wrapper": "" }
3625
3501
  });
3626
3502
  pinWrapper.hidden = true;
3627
3503
  pinWrapper.appendChild(pinBtn);
3628
- pinWrapper.appendChild(commitCycler);
3629
3504
  root.appendChild(pinWrapper);
3630
3505
  const updatePinUI = () => {
3631
3506
  if (!activePinLayer) {
@@ -3633,16 +3508,7 @@ function createMenuBar(options) {
3633
3508
  return;
3634
3509
  }
3635
3510
  const pinsVisible = activePinLayer.visible;
3636
- const state = activePinLayer.filterState;
3637
- const hasCommits = state.commits.length > 0;
3638
3511
  pinWrapper.hidden = false;
3639
- commitCycler.hidden = !pinsVisible || !hasCommits;
3640
- if (state.commitIndex === -1 || !state.commits[state.commitIndex]) {
3641
- commitLabel.textContent = `all (${state.commits.length})`;
3642
- } else {
3643
- const sha = state.commits[state.commitIndex] ?? "";
3644
- commitLabel.textContent = sha.slice(0, 7);
3645
- }
3646
3512
  pinBtn.className = cn(BUTTON_CLASS, pinsVisible && BUTTON_ACTIVE_CLASS);
3647
3513
  };
3648
3514
  pinBtn.addEventListener("click", (e) => {
@@ -3651,14 +3517,6 @@ function createMenuBar(options) {
3651
3517
  activePinLayer.setVisible(!activePinLayer.visible);
3652
3518
  }
3653
3519
  });
3654
- prevBtn.addEventListener("click", (e) => {
3655
- e.stopPropagation();
3656
- activePinLayer?.prevCommit();
3657
- });
3658
- nextBtn.addEventListener("click", (e) => {
3659
- e.stopPropagation();
3660
- activePinLayer?.nextCommit();
3661
- });
3662
3520
  let unsubscribePinFilter = activePinLayer?.onFilterChange(() => updatePinUI());
3663
3521
  const presenceIcon = createLucideElement2(Users);
3664
3522
  presenceIcon.setAttribute("class", "size-3.5");
@@ -3752,7 +3610,7 @@ function createMenuBar(options) {
3752
3610
  container.appendChild(root);
3753
3611
  const syncButtonStates = () => {
3754
3612
  const state = session.getState();
3755
- const inspectActive = state.inspectorActive;
3613
+ const inspectActive = state.mode === "inspecting";
3756
3614
  inspectBtn.setAttribute(
3757
3615
  "data-uidex-menubar-inspect-active",
3758
3616
  inspectActive ? "true" : "false"
@@ -3871,6 +3729,49 @@ function createMenuBar(options) {
3871
3729
  };
3872
3730
  }
3873
3731
 
3732
+ // src/browser/internal/repositioner.ts
3733
+ function createRepositioner(onReflow) {
3734
+ let rafId = null;
3735
+ let attached = false;
3736
+ const schedule = () => {
3737
+ if (rafId !== null) return;
3738
+ rafId = typeof requestAnimationFrame === "function" ? requestAnimationFrame(() => {
3739
+ rafId = null;
3740
+ onReflow();
3741
+ }) : setTimeout(() => {
3742
+ rafId = null;
3743
+ onReflow();
3744
+ }, 0);
3745
+ };
3746
+ const cancel = () => {
3747
+ if (rafId === null) return;
3748
+ if (typeof cancelAnimationFrame === "function") cancelAnimationFrame(rafId);
3749
+ else clearTimeout(rafId);
3750
+ rafId = null;
3751
+ };
3752
+ const onScroll = () => schedule();
3753
+ const onResize = () => schedule();
3754
+ const attach = () => {
3755
+ if (attached) return;
3756
+ attached = true;
3757
+ window.addEventListener("resize", onResize);
3758
+ window.addEventListener("scroll", onScroll, {
3759
+ capture: true,
3760
+ passive: true
3761
+ });
3762
+ };
3763
+ const detach = () => {
3764
+ if (!attached) return;
3765
+ attached = false;
3766
+ window.removeEventListener("resize", onResize);
3767
+ window.removeEventListener("scroll", onScroll, {
3768
+ capture: true
3769
+ });
3770
+ cancel();
3771
+ };
3772
+ return { schedule, cancel, attach, detach };
3773
+ }
3774
+
3874
3775
  // src/browser/surface/overlay.ts
3875
3776
  var DEFAULT_COLOR = "#34d399";
3876
3777
  var DEFAULT_BORDER_WIDTH = 2;
@@ -3938,44 +3839,7 @@ function createOverlay(deps) {
3938
3839
  fillOpacity: DEFAULT_FILL_OPACITY,
3939
3840
  backdrop: false
3940
3841
  };
3941
- let rafId = null;
3942
- let attached = false;
3943
- const schedule = () => {
3944
- if (rafId !== null) return;
3945
- rafId = typeof requestAnimationFrame === "function" ? requestAnimationFrame(() => {
3946
- rafId = null;
3947
- updatePosition();
3948
- }) : setTimeout(() => {
3949
- rafId = null;
3950
- updatePosition();
3951
- }, 0);
3952
- };
3953
- const cancelSchedule = () => {
3954
- if (rafId === null) return;
3955
- if (typeof cancelAnimationFrame === "function") cancelAnimationFrame(rafId);
3956
- else clearTimeout(rafId);
3957
- rafId = null;
3958
- };
3959
- const onScroll = () => schedule();
3960
- const onResize = () => schedule();
3961
- const attach = () => {
3962
- if (attached) return;
3963
- attached = true;
3964
- window.addEventListener("resize", onResize);
3965
- window.addEventListener("scroll", onScroll, {
3966
- capture: true,
3967
- passive: true
3968
- });
3969
- };
3970
- const detach = () => {
3971
- if (!attached) return;
3972
- attached = false;
3973
- window.removeEventListener("resize", onResize);
3974
- window.removeEventListener("scroll", onScroll, {
3975
- capture: true
3976
- });
3977
- cancelSchedule();
3978
- };
3842
+ const repositioner = createRepositioner(() => updatePosition());
3979
3843
  function updatePosition() {
3980
3844
  if (!target) return;
3981
3845
  const rect = target.getBoundingClientRect();
@@ -4039,16 +3903,16 @@ function createOverlay(deps) {
4039
3903
  box.offsetHeight;
4040
3904
  }
4041
3905
  box.style.opacity = "1";
4042
- attach();
3906
+ repositioner.attach();
4043
3907
  },
4044
3908
  hide() {
4045
3909
  target = null;
4046
3910
  box.style.opacity = "0";
4047
3911
  backdrop.style.opacity = "0";
4048
- detach();
3912
+ repositioner.detach();
4049
3913
  },
4050
3914
  destroy() {
4051
- detach();
3915
+ repositioner.detach();
4052
3916
  box.remove();
4053
3917
  backdrop.remove();
4054
3918
  target = null;
@@ -4165,8 +4029,7 @@ function createSurfaceShell(options) {
4165
4029
  const overlay = createOverlay({ container: host.shadowRoot });
4166
4030
  cleanup.add(overlay);
4167
4031
  const tooltip = createCursorTooltip({
4168
- container: host.chromeEl,
4169
- session: options.session
4032
+ container: host.chromeEl
4170
4033
  });
4171
4034
  cleanup.add(tooltip);
4172
4035
  const afterHover = options.inspector?.onAfterHover;