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
@@ -44,11 +44,6 @@ function isMetaEntity(entity) {
44
44
  function entityKey(entity) {
45
45
  return entity.kind === "route" ? entity.path : entity.id;
46
46
  }
47
- function sameRef(a, b) {
48
- if (a === b) return true;
49
- if (a === null || b === null) return false;
50
- return a.kind === b.kind && a.id === b.id;
51
- }
52
47
  var UnknownEntityKindError = class extends Error {
53
48
  kind;
54
49
  constructor(kind) {
@@ -93,6 +88,7 @@ function freezeEntity(entity, flows) {
93
88
  function createRegistry() {
94
89
  const store = emptyStore();
95
90
  let flowsCache = null;
91
+ const patternCache = /* @__PURE__ */ new Map();
96
92
  const getFlows = () => {
97
93
  if (flowsCache === null) flowsCache = Array.from(store.flow.values());
98
94
  return flowsCache;
@@ -102,6 +98,7 @@ function createRegistry() {
102
98
  const key = entityKey(entity);
103
99
  store[entity.kind].set(key, entity);
104
100
  flowsCache = null;
101
+ patternCache.delete(entity.kind);
105
102
  };
106
103
  const get = (kind, id) => {
107
104
  assertEntityKind(kind);
@@ -109,6 +106,51 @@ function createRegistry() {
109
106
  if (raw === void 0) return void 0;
110
107
  return freezeEntity(raw, getFlows());
111
108
  };
109
+ const getPatternsForKind = (kind) => {
110
+ const cached = patternCache.get(kind);
111
+ if (cached !== void 0) return cached;
112
+ const patterns = [];
113
+ for (const [key, entity] of store[kind]) {
114
+ if (key.includes("*")) {
115
+ const segments = key.split("*");
116
+ patterns.push({
117
+ segments,
118
+ staticLength: segments.reduce((n, s) => n + s.length, 0),
119
+ entity
120
+ });
121
+ }
122
+ }
123
+ patternCache.set(
124
+ kind,
125
+ patterns
126
+ );
127
+ return patterns;
128
+ };
129
+ const matchesSegments = (segments, id) => {
130
+ const first = segments[0];
131
+ const last = segments[segments.length - 1];
132
+ if (!id.startsWith(first)) return false;
133
+ let pos = first.length;
134
+ for (let i = 1; i < segments.length - 1; i++) {
135
+ const idx = id.indexOf(segments[i], pos);
136
+ if (idx === -1) return false;
137
+ pos = idx + segments[i].length;
138
+ }
139
+ return id.endsWith(last) && id.length - last.length >= pos;
140
+ };
141
+ const matchPattern = (kind, id) => {
142
+ assertEntityKind(kind);
143
+ const patterns = getPatternsForKind(kind);
144
+ if (patterns.length === 0) return void 0;
145
+ let best;
146
+ for (const entry of patterns) {
147
+ if (matchesSegments(entry.segments, id) && (best === void 0 || entry.staticLength > best.staticLength)) {
148
+ best = entry;
149
+ }
150
+ }
151
+ if (best === void 0) return void 0;
152
+ return freezeEntity(best.entity, getFlows());
153
+ };
112
154
  const list = (kind) => {
113
155
  assertEntityKind(kind);
114
156
  const flows = getFlows();
@@ -159,6 +201,7 @@ function createRegistry() {
159
201
  return {
160
202
  add,
161
203
  get,
204
+ matchPattern,
162
205
  list,
163
206
  query,
164
207
  byScope,
@@ -283,8 +326,7 @@ var COMMAND_PALETTE_ENTRY = {
283
326
  function createModeStore(options) {
284
327
  const { nav, bindings } = options;
285
328
  const store = (0, import_vanilla.createStore)(() => ({
286
- mode: "idle",
287
- inspectorActive: false
329
+ mode: "idle"
288
330
  }));
289
331
  const transition = {
290
332
  openPalette() {
@@ -293,17 +335,17 @@ function createModeStore(options) {
293
335
  bindings?.destroyInspector?.();
294
336
  }
295
337
  nav.nav.reset([COMMAND_PALETTE_ENTRY]);
296
- store.setState({ mode: "palette", inspectorActive: false });
338
+ store.setState({ mode: "palette" });
297
339
  },
298
340
  openInspector() {
299
341
  bindings?.mountInspector?.();
300
342
  nav.nav.clear();
301
- store.setState({ mode: "inspecting", inspectorActive: true });
343
+ store.setState({ mode: "inspecting" });
302
344
  },
303
345
  closeInspector() {
304
346
  bindings?.destroyInspector?.();
305
347
  nav.nav.clear();
306
- store.setState({ mode: "idle", inspectorActive: false });
348
+ store.setState({ mode: "idle" });
307
349
  },
308
350
  toggleInspector() {
309
351
  if (store.getState().mode === "inspecting") {
@@ -318,7 +360,7 @@ function createModeStore(options) {
318
360
  bindings?.destroyInspector?.();
319
361
  }
320
362
  nav.nav.reset(initialStack);
321
- store.setState({ mode: "viewing", inspectorActive: false });
363
+ store.setState({ mode: "viewing" });
322
364
  },
323
365
  dismiss() {
324
366
  const prev = store.getState();
@@ -326,7 +368,7 @@ function createModeStore(options) {
326
368
  bindings?.destroyInspector?.();
327
369
  }
328
370
  nav.nav.clear();
329
- store.setState({ mode: "idle", inspectorActive: false });
371
+ store.setState({ mode: "idle" });
330
372
  },
331
373
  popOrTransition() {
332
374
  const { stack } = nav.getState();
@@ -334,12 +376,12 @@ function createModeStore(options) {
334
376
  nav.nav.pop();
335
377
  } else if (stack.length === 2 && stack[0]?.id === "command-palette") {
336
378
  nav.nav.reset([COMMAND_PALETTE_ENTRY]);
337
- store.setState({ mode: "palette", inspectorActive: false });
379
+ store.setState({ mode: "palette" });
338
380
  } else if (stack.length === 2) {
339
381
  nav.nav.pop();
340
382
  } else {
341
383
  nav.nav.clear();
342
- store.setState({ mode: "idle", inspectorActive: false });
384
+ store.setState({ mode: "idle" });
343
385
  }
344
386
  },
345
387
  pushView(entry) {
@@ -356,7 +398,7 @@ function createModeStore(options) {
356
398
  case "inspecting":
357
399
  bindings?.destroyInspector?.();
358
400
  nav.nav.reset([entry]);
359
- store.setState({ mode: "viewing", inspectorActive: false });
401
+ store.setState({ mode: "viewing" });
360
402
  break;
361
403
  case "palette":
362
404
  case "viewing":
@@ -391,14 +433,6 @@ function createNavigationStore() {
391
433
  store.setState({ stack: s.slice(0, -1) });
392
434
  }
393
435
  },
394
- replace(entry) {
395
- const s = store.getState().stack;
396
- if (s.length === 0) {
397
- store.setState({ stack: [entry] });
398
- } else {
399
- store.setState({ stack: [...s.slice(0, -1), entry] });
400
- }
401
- },
402
436
  clear() {
403
437
  store.setState({ stack: [] });
404
438
  },
@@ -413,14 +447,11 @@ function createNavigationStore() {
413
447
 
414
448
  // src/browser/session/store.ts
415
449
  var defaultSnapshot = {
416
- hover: null,
417
- selection: null,
418
450
  stack: [],
419
451
  pinnedHighlight: null,
420
- inspectorActive: false,
452
+ mode: "idle",
421
453
  theme: "auto",
422
454
  resolvedTheme: "light",
423
- ingestActive: false,
424
455
  user: null
425
456
  };
426
457
  function resolveTheme(preference, detect) {
@@ -471,7 +502,6 @@ function createSession(options = {}) {
471
502
  } else if (highlightMode === "transient") {
472
503
  onUpdateOverlay?.(hlCtx);
473
504
  }
474
- store.setState({ hover: ref });
475
505
  },
476
506
  unhover() {
477
507
  if (highlightMode === "transient") {
@@ -481,7 +511,6 @@ function createSession(options = {}) {
481
511
  hlCtx.color = null;
482
512
  onHideOverlay?.();
483
513
  }
484
- store.setState({ hover: null });
485
514
  },
486
515
  pin(ref) {
487
516
  const pinRef = ref ?? hlCtx.ref;
@@ -509,14 +538,11 @@ function createSession(options = {}) {
509
538
  };
510
539
  const store = (0, import_vanilla3.createStore)(() => ({
511
540
  ...defaultSnapshot,
512
- hover: overrides.hover ?? null,
513
- selection: overrides.selection ?? null,
514
541
  stack: [],
515
542
  pinnedHighlight: null,
516
- inspectorActive: false,
543
+ mode: "idle",
517
544
  theme: initialPref,
518
545
  resolvedTheme: initialResolved,
519
- ingestActive: overrides.ingestActive ?? false,
520
546
  user: overrides.user ?? null
521
547
  }));
522
548
  nav.subscribe(() => {
@@ -526,29 +552,21 @@ function createSession(options = {}) {
526
552
  }
527
553
  });
528
554
  modeStore.subscribe(() => {
529
- const { inspectorActive } = modeStore.getState();
530
- if (store.getState().inspectorActive !== inspectorActive) {
531
- store.setState({ inspectorActive });
555
+ const { mode } = modeStore.getState();
556
+ if (store.getState().mode !== mode) {
557
+ store.setState({ mode });
532
558
  }
533
559
  });
534
560
  const session = store;
535
561
  session.nav = nav;
536
562
  session.mode = modeStore;
537
563
  session.highlight = highlightActions;
538
- session.select = (ref) => {
539
- if (sameRef(store.getState().selection, ref)) return;
540
- store.setState({ selection: ref });
541
- };
542
564
  session.setTheme = (theme, resolved) => {
543
565
  const state = store.getState();
544
566
  const nextResolved = resolved ?? resolveTheme(theme, detectTheme);
545
567
  if (state.theme === theme && state.resolvedTheme === nextResolved) return;
546
568
  store.setState({ theme, resolvedTheme: nextResolved });
547
569
  };
548
- session.setIngest = (active) => {
549
- if (store.getState().ingestActive === active) return;
550
- store.setState({ ingestActive: active });
551
- };
552
570
  if (initialStack.length > 0) {
553
571
  modeStore.transition.openPalette();
554
572
  for (let i = 1; i < initialStack.length; i++) {
@@ -840,6 +858,9 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
840
858
  .relative {
841
859
  position: relative;
842
860
  }
861
+ .static {
862
+ position: static;
863
+ }
843
864
  .inset-0 {
844
865
  inset: calc(var(--spacing) * 0);
845
866
  }
@@ -858,9 +879,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
858
879
  .right-0 {
859
880
  right: calc(var(--spacing) * 0);
860
881
  }
861
- .right-2 {
862
- right: calc(var(--spacing) * 2);
863
- }
864
882
  .bottom-full {
865
883
  bottom: 100%;
866
884
  }
@@ -903,9 +921,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
903
921
  .mx-2 {
904
922
  margin-inline: calc(var(--spacing) * 2);
905
923
  }
906
- .my-1 {
907
- margin-block: calc(var(--spacing) * 1);
908
- }
909
924
  .ms-auto {
910
925
  margin-inline-start: auto;
911
926
  }
@@ -942,9 +957,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
942
957
  .inline-flex {
943
958
  display: inline-flex;
944
959
  }
945
- .list-item {
946
- display: list-item;
947
- }
948
960
  .table {
949
961
  display: table;
950
962
  }
@@ -952,10 +964,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
952
964
  width: calc(var(--spacing) * 2);
953
965
  height: calc(var(--spacing) * 2);
954
966
  }
955
- .size-3 {
956
- width: calc(var(--spacing) * 3);
957
- height: calc(var(--spacing) * 3);
958
- }
959
967
  .size-3\\.5 {
960
968
  width: calc(var(--spacing) * 3.5);
961
969
  height: calc(var(--spacing) * 3.5);
@@ -1013,15 +1021,9 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1013
1021
  .h-\\[26rem\\] {
1014
1022
  height: 26rem;
1015
1023
  }
1016
- .h-auto {
1017
- height: auto;
1018
- }
1019
1024
  .h-full {
1020
1025
  height: 100%;
1021
1026
  }
1022
- .h-px {
1023
- height: 1px;
1024
- }
1025
1027
  .max-h-32 {
1026
1028
  max-height: calc(var(--spacing) * 32);
1027
1029
  }
@@ -1031,9 +1033,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1031
1033
  .min-h-0 {
1032
1034
  min-height: calc(var(--spacing) * 0);
1033
1035
  }
1034
- .min-h-7 {
1035
- min-height: calc(var(--spacing) * 7);
1036
- }
1037
1036
  .min-h-8 {
1038
1037
  min-height: calc(var(--spacing) * 8);
1039
1038
  }
@@ -1058,9 +1057,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1058
1057
  .w-56 {
1059
1058
  width: calc(var(--spacing) * 56);
1060
1059
  }
1061
- .w-auto {
1062
- width: auto;
1063
- }
1064
1060
  .w-full {
1065
1061
  width: 100%;
1066
1062
  }
@@ -1135,9 +1131,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1135
1131
  .animate-spin {
1136
1132
  animation: var(--animate-spin);
1137
1133
  }
1138
- .cursor-default {
1139
- cursor: default;
1140
- }
1141
1134
  .cursor-pointer {
1142
1135
  cursor: pointer;
1143
1136
  }
@@ -1147,9 +1140,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1147
1140
  .scroll-py-2 {
1148
1141
  scroll-padding-block: calc(var(--spacing) * 2);
1149
1142
  }
1150
- .list-none {
1151
- list-style-type: none;
1152
- }
1153
1143
  .appearance-none {
1154
1144
  appearance: none;
1155
1145
  }
@@ -1171,9 +1161,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1171
1161
  .justify-center {
1172
1162
  justify-content: center;
1173
1163
  }
1174
- .justify-start {
1175
- justify-content: flex-start;
1176
- }
1177
1164
  .gap-0 {
1178
1165
  gap: calc(var(--spacing) * 0);
1179
1166
  }
@@ -1198,9 +1185,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1198
1185
  .gap-6 {
1199
1186
  gap: calc(var(--spacing) * 6);
1200
1187
  }
1201
- .self-start {
1202
- align-self: flex-start;
1203
- }
1204
1188
  .truncate {
1205
1189
  overflow: hidden;
1206
1190
  text-overflow: ellipsis;
@@ -1415,9 +1399,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1415
1399
  .p-6 {
1416
1400
  padding: calc(var(--spacing) * 6);
1417
1401
  }
1418
- .px-0 {
1419
- padding-inline: calc(var(--spacing) * 0);
1420
- }
1421
1402
  .px-1 {
1422
1403
  padding-inline: calc(var(--spacing) * 1);
1423
1404
  }
@@ -1442,9 +1423,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1442
1423
  .px-6 {
1443
1424
  padding-inline: calc(var(--spacing) * 6);
1444
1425
  }
1445
- .py-0 {
1446
- padding-block: calc(var(--spacing) * 0);
1447
- }
1448
1426
  .py-1 {
1449
1427
  padding-block: calc(var(--spacing) * 1);
1450
1428
  }
@@ -1517,9 +1495,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1517
1495
  .text-\\[9px\\] {
1518
1496
  font-size: 9px;
1519
1497
  }
1520
- .text-\\[10px\\] {
1521
- font-size: 10px;
1522
- }
1523
1498
  .text-\\[11px\\] {
1524
1499
  font-size: 11px;
1525
1500
  }
@@ -1759,10 +1734,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1759
1734
  outline-style: var(--tw-outline-style);
1760
1735
  outline-width: 1px;
1761
1736
  }
1762
- .blur {
1763
- --tw-blur: blur(8px);
1764
- 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,);
1765
- }
1766
1737
  .filter {
1767
1738
  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,);
1768
1739
  }
@@ -1928,25 +1899,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1928
1899
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
1929
1900
  }
1930
1901
  }
1931
- .focus-within\\:border-ring {
1932
- &:focus-within {
1933
- border-color: var(--ring);
1934
- }
1935
- }
1936
- .focus-within\\:ring-\\[3px\\] {
1937
- &:focus-within {
1938
- --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
1939
- box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
1940
- }
1941
- }
1942
- .focus-within\\:ring-ring\\/30 {
1943
- &:focus-within {
1944
- --tw-ring-color: var(--ring);
1945
- @supports (color: color-mix(in lab, red, red)) {
1946
- --tw-ring-color: color-mix(in oklab, var(--ring) 30%, transparent);
1947
- }
1948
- }
1949
- }
1950
1902
  .hover\\:border-destructive\\/30 {
1951
1903
  &:hover {
1952
1904
  @media (hover: hover) {
@@ -2090,11 +2042,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
2090
2042
  pointer-events: none;
2091
2043
  }
2092
2044
  }
2093
- .disabled\\:cursor-not-allowed {
2094
- &:disabled {
2095
- cursor: not-allowed;
2096
- }
2097
- }
2098
2045
  .disabled\\:opacity-50 {
2099
2046
  &:disabled {
2100
2047
  opacity: 50%;
@@ -2105,11 +2052,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
2105
2052
  opacity: 60%;
2106
2053
  }
2107
2054
  }
2108
- .has-disabled\\:opacity-60 {
2109
- &:has(*:disabled) {
2110
- opacity: 60%;
2111
- }
2112
- }
2113
2055
  .aria-invalid\\:border-destructive\\/40 {
2114
2056
  &[aria-invalid="true"] {
2115
2057
  border-color: var(--destructive);
@@ -2516,32 +2458,6 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
2516
2458
  height: calc(var(--spacing) * 4.5);
2517
2459
  }
2518
2460
  }
2519
- .\\[\\&\\>svg\\]\\:pointer-events-none {
2520
- &>svg {
2521
- pointer-events: none;
2522
- }
2523
- }
2524
- .\\[\\&\\>svg\\]\\:-mx-0\\.5 {
2525
- &>svg {
2526
- margin-inline: calc(var(--spacing) * -0.5);
2527
- }
2528
- }
2529
- .\\[\\&\\>svg\\]\\:shrink-0 {
2530
- &>svg {
2531
- flex-shrink: 0;
2532
- }
2533
- }
2534
- .\\[\\&\\>svg\\:not\\(\\[class\\*\\=\\'opacity-\\'\\]\\)\\]\\:opacity-80 {
2535
- &>svg:not([class*='opacity-']) {
2536
- opacity: 80%;
2537
- }
2538
- }
2539
- .\\[\\&\\>svg\\:not\\(\\[class\\*\\=\\'size-\\'\\]\\)\\]\\:size-4 {
2540
- &>svg:not([class*='size-']) {
2541
- width: calc(var(--spacing) * 4);
2542
- height: calc(var(--spacing) * 4);
2543
- }
2544
- }
2545
2461
  .\\[\\[data-kbd-nav\\]_\\&\\]\\:focus-within\\:bg-accent {
2546
2462
  [data-kbd-nav] & {
2547
2463
  &:focus-within {
@@ -3103,11 +3019,10 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
3103
3019
 
3104
3020
  // src/browser/surface/constants.ts
3105
3021
  var SURFACE_HOST_CLASS = "uidex-surface-host";
3106
- var SURFACE_CONTAINER_CLASS = "uidex-container";
3107
3022
  var Z_BASE = 2147483630;
3108
3023
  var Z_OVERLAY = 2147483635;
3109
3024
  var Z_CHROME = 2147483645;
3110
- var SURFACE_IGNORE_SELECTOR = `.${SURFACE_HOST_CLASS},.${SURFACE_CONTAINER_CLASS}`;
3025
+ var SURFACE_IGNORE_SELECTOR = `.${SURFACE_HOST_CLASS}`;
3111
3026
  var UIDEX_ATTR_TO_KIND = [
3112
3027
  ["data-uidex", "element"],
3113
3028
  ["data-uidex-region", "region"],
@@ -3291,7 +3206,7 @@ function createCursorTooltip(deps) {
3291
3206
  // src/browser/surface/inspector.ts
3292
3207
  function entityForRef(ref, registry) {
3293
3208
  if (registry) {
3294
- const found = registry.get(ref.kind, ref.id);
3209
+ const found = registry.get(ref.kind, ref.id) ?? registry.matchPattern?.(ref.kind, ref.id);
3295
3210
  if (found) return found;
3296
3211
  }
3297
3212
  if (ref.kind === "route") return { kind: "route", path: ref.id, page: ref.id };
@@ -3394,7 +3309,6 @@ function createInspector(options) {
3394
3309
  e.preventDefault();
3395
3310
  e.stopPropagation();
3396
3311
  const match = stack[layerIndex];
3397
- session.select(match.ref);
3398
3312
  onSelect?.(match, { x: e.clientX, y: e.clientY });
3399
3313
  };
3400
3314
  const onContextMenu = (e) => {
@@ -3591,49 +3505,12 @@ function createMenuBar(options) {
3591
3505
  },
3592
3506
  pinIcon
3593
3507
  );
3594
- const commitCycler = el("div", {
3595
- class: "relative z-1 inline-flex items-center gap-0.5",
3596
- attrs: { "data-uidex-menubar-commit-cycler": "" }
3597
- });
3598
- commitCycler.hidden = true;
3599
- const prevIcon = (0, import_lucide3.createElement)(import_lucide3.ChevronLeft);
3600
- prevIcon.setAttribute("class", "size-3");
3601
- prevIcon.setAttribute("aria-hidden", "true");
3602
- const prevBtn = el(
3603
- "button",
3604
- {
3605
- class: BUTTON_CLASS,
3606
- attrs: { type: "button", "aria-label": "Previous commit" },
3607
- style: { width: "18px", height: "18px" }
3608
- },
3609
- prevIcon
3610
- );
3611
- const commitLabel = el("span", {
3612
- class: "relative z-1 whitespace-nowrap px-1 text-[10px] font-mono text-muted-foreground",
3613
- attrs: { "data-uidex-menubar-commit-label": "" }
3614
- });
3615
- const nextIcon = (0, import_lucide3.createElement)(import_lucide3.ChevronRight);
3616
- nextIcon.setAttribute("class", "size-3");
3617
- nextIcon.setAttribute("aria-hidden", "true");
3618
- const nextBtn = el(
3619
- "button",
3620
- {
3621
- class: BUTTON_CLASS,
3622
- attrs: { type: "button", "aria-label": "Next commit" },
3623
- style: { width: "18px", height: "18px" }
3624
- },
3625
- nextIcon
3626
- );
3627
- commitCycler.appendChild(prevBtn);
3628
- commitCycler.appendChild(commitLabel);
3629
- commitCycler.appendChild(nextBtn);
3630
3508
  const pinWrapper = el("div", {
3631
3509
  class: "relative z-1 inline-flex items-center gap-0.5",
3632
3510
  attrs: { "data-uidex-menubar-pin-wrapper": "" }
3633
3511
  });
3634
3512
  pinWrapper.hidden = true;
3635
3513
  pinWrapper.appendChild(pinBtn);
3636
- pinWrapper.appendChild(commitCycler);
3637
3514
  root.appendChild(pinWrapper);
3638
3515
  const updatePinUI = () => {
3639
3516
  if (!activePinLayer) {
@@ -3641,16 +3518,7 @@ function createMenuBar(options) {
3641
3518
  return;
3642
3519
  }
3643
3520
  const pinsVisible = activePinLayer.visible;
3644
- const state = activePinLayer.filterState;
3645
- const hasCommits = state.commits.length > 0;
3646
3521
  pinWrapper.hidden = false;
3647
- commitCycler.hidden = !pinsVisible || !hasCommits;
3648
- if (state.commitIndex === -1 || !state.commits[state.commitIndex]) {
3649
- commitLabel.textContent = `all (${state.commits.length})`;
3650
- } else {
3651
- const sha = state.commits[state.commitIndex] ?? "";
3652
- commitLabel.textContent = sha.slice(0, 7);
3653
- }
3654
3522
  pinBtn.className = cn(BUTTON_CLASS, pinsVisible && BUTTON_ACTIVE_CLASS);
3655
3523
  };
3656
3524
  pinBtn.addEventListener("click", (e) => {
@@ -3659,14 +3527,6 @@ function createMenuBar(options) {
3659
3527
  activePinLayer.setVisible(!activePinLayer.visible);
3660
3528
  }
3661
3529
  });
3662
- prevBtn.addEventListener("click", (e) => {
3663
- e.stopPropagation();
3664
- activePinLayer?.prevCommit();
3665
- });
3666
- nextBtn.addEventListener("click", (e) => {
3667
- e.stopPropagation();
3668
- activePinLayer?.nextCommit();
3669
- });
3670
3530
  let unsubscribePinFilter = activePinLayer?.onFilterChange(() => updatePinUI());
3671
3531
  const presenceIcon = (0, import_lucide3.createElement)(import_lucide3.Users);
3672
3532
  presenceIcon.setAttribute("class", "size-3.5");
@@ -3760,7 +3620,7 @@ function createMenuBar(options) {
3760
3620
  container.appendChild(root);
3761
3621
  const syncButtonStates = () => {
3762
3622
  const state = session.getState();
3763
- const inspectActive = state.inspectorActive;
3623
+ const inspectActive = state.mode === "inspecting";
3764
3624
  inspectBtn.setAttribute(
3765
3625
  "data-uidex-menubar-inspect-active",
3766
3626
  inspectActive ? "true" : "false"
@@ -3879,6 +3739,49 @@ function createMenuBar(options) {
3879
3739
  };
3880
3740
  }
3881
3741
 
3742
+ // src/browser/internal/repositioner.ts
3743
+ function createRepositioner(onReflow) {
3744
+ let rafId = null;
3745
+ let attached = false;
3746
+ const schedule = () => {
3747
+ if (rafId !== null) return;
3748
+ rafId = typeof requestAnimationFrame === "function" ? requestAnimationFrame(() => {
3749
+ rafId = null;
3750
+ onReflow();
3751
+ }) : setTimeout(() => {
3752
+ rafId = null;
3753
+ onReflow();
3754
+ }, 0);
3755
+ };
3756
+ const cancel = () => {
3757
+ if (rafId === null) return;
3758
+ if (typeof cancelAnimationFrame === "function") cancelAnimationFrame(rafId);
3759
+ else clearTimeout(rafId);
3760
+ rafId = null;
3761
+ };
3762
+ const onScroll = () => schedule();
3763
+ const onResize = () => schedule();
3764
+ const attach = () => {
3765
+ if (attached) return;
3766
+ attached = true;
3767
+ window.addEventListener("resize", onResize);
3768
+ window.addEventListener("scroll", onScroll, {
3769
+ capture: true,
3770
+ passive: true
3771
+ });
3772
+ };
3773
+ const detach = () => {
3774
+ if (!attached) return;
3775
+ attached = false;
3776
+ window.removeEventListener("resize", onResize);
3777
+ window.removeEventListener("scroll", onScroll, {
3778
+ capture: true
3779
+ });
3780
+ cancel();
3781
+ };
3782
+ return { schedule, cancel, attach, detach };
3783
+ }
3784
+
3882
3785
  // src/browser/surface/overlay.ts
3883
3786
  var DEFAULT_COLOR = "#34d399";
3884
3787
  var DEFAULT_BORDER_WIDTH = 2;
@@ -3946,44 +3849,7 @@ function createOverlay(deps) {
3946
3849
  fillOpacity: DEFAULT_FILL_OPACITY,
3947
3850
  backdrop: false
3948
3851
  };
3949
- let rafId = null;
3950
- let attached = false;
3951
- const schedule = () => {
3952
- if (rafId !== null) return;
3953
- rafId = typeof requestAnimationFrame === "function" ? requestAnimationFrame(() => {
3954
- rafId = null;
3955
- updatePosition();
3956
- }) : setTimeout(() => {
3957
- rafId = null;
3958
- updatePosition();
3959
- }, 0);
3960
- };
3961
- const cancelSchedule = () => {
3962
- if (rafId === null) return;
3963
- if (typeof cancelAnimationFrame === "function") cancelAnimationFrame(rafId);
3964
- else clearTimeout(rafId);
3965
- rafId = null;
3966
- };
3967
- const onScroll = () => schedule();
3968
- const onResize = () => schedule();
3969
- const attach = () => {
3970
- if (attached) return;
3971
- attached = true;
3972
- window.addEventListener("resize", onResize);
3973
- window.addEventListener("scroll", onScroll, {
3974
- capture: true,
3975
- passive: true
3976
- });
3977
- };
3978
- const detach = () => {
3979
- if (!attached) return;
3980
- attached = false;
3981
- window.removeEventListener("resize", onResize);
3982
- window.removeEventListener("scroll", onScroll, {
3983
- capture: true
3984
- });
3985
- cancelSchedule();
3986
- };
3852
+ const repositioner = createRepositioner(() => updatePosition());
3987
3853
  function updatePosition() {
3988
3854
  if (!target) return;
3989
3855
  const rect = target.getBoundingClientRect();
@@ -4047,16 +3913,16 @@ function createOverlay(deps) {
4047
3913
  box.offsetHeight;
4048
3914
  }
4049
3915
  box.style.opacity = "1";
4050
- attach();
3916
+ repositioner.attach();
4051
3917
  },
4052
3918
  hide() {
4053
3919
  target = null;
4054
3920
  box.style.opacity = "0";
4055
3921
  backdrop.style.opacity = "0";
4056
- detach();
3922
+ repositioner.detach();
4057
3923
  },
4058
3924
  destroy() {
4059
- detach();
3925
+ repositioner.detach();
4060
3926
  box.remove();
4061
3927
  backdrop.remove();
4062
3928
  target = null;
@@ -4173,8 +4039,7 @@ function createSurfaceShell(options) {
4173
4039
  const overlay = createOverlay({ container: host.shadowRoot });
4174
4040
  cleanup.add(overlay);
4175
4041
  const tooltip = createCursorTooltip({
4176
- container: host.chromeEl,
4177
- session: options.session
4042
+ container: host.chromeEl
4178
4043
  });
4179
4044
  cleanup.add(tooltip);
4180
4045
  const afterHover = options.inspector?.onAfterHover;