@flowsterix/react 0.10.1 → 0.11.1

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 (62) hide show
  1. package/dist/chunk-AJZMUYBN.mjs +21 -0
  2. package/dist/chunk-D5LQLRSU.cjs +289 -0
  3. package/dist/chunk-FCOKCGV3.cjs +21 -0
  4. package/dist/chunk-HPVLOLCD.cjs +1 -0
  5. package/dist/components/TourPopoverPortal.d.ts +1 -1
  6. package/dist/components/TourPopoverPortal.d.ts.map +1 -1
  7. package/dist/context.d.ts +6 -0
  8. package/dist/context.d.ts.map +1 -1
  9. package/dist/devtools/DevToolsContext.d.ts +31 -0
  10. package/dist/devtools/DevToolsContext.d.ts.map +1 -0
  11. package/dist/devtools/DevToolsProvider.d.ts +9 -0
  12. package/dist/devtools/DevToolsProvider.d.ts.map +1 -0
  13. package/dist/devtools/components/FlowEditModal.d.ts +11 -0
  14. package/dist/devtools/components/FlowEditModal.d.ts.map +1 -0
  15. package/dist/devtools/components/FlowItem.d.ts +8 -0
  16. package/dist/devtools/components/FlowItem.d.ts.map +1 -0
  17. package/dist/devtools/components/FlowsTab.d.ts +5 -0
  18. package/dist/devtools/components/FlowsTab.d.ts.map +1 -0
  19. package/dist/devtools/components/GrabberOverlay.d.ts +8 -0
  20. package/dist/devtools/components/GrabberOverlay.d.ts.map +1 -0
  21. package/dist/devtools/components/ShadowRoot.d.ts +7 -0
  22. package/dist/devtools/components/ShadowRoot.d.ts.map +1 -0
  23. package/dist/devtools/components/StepItem.d.ts +16 -0
  24. package/dist/devtools/components/StepItem.d.ts.map +1 -0
  25. package/dist/devtools/components/StepList.d.ts +17 -0
  26. package/dist/devtools/components/StepList.d.ts.map +1 -0
  27. package/dist/devtools/components/TabNav.d.ts +9 -0
  28. package/dist/devtools/components/TabNav.d.ts.map +1 -0
  29. package/dist/devtools/components/Toolbar.d.ts +11 -0
  30. package/dist/devtools/components/Toolbar.d.ts.map +1 -0
  31. package/dist/devtools/globalBridge.d.ts +24 -0
  32. package/dist/devtools/globalBridge.d.ts.map +1 -0
  33. package/dist/devtools/hooks/useElementInfo.d.ts +7 -0
  34. package/dist/devtools/hooks/useElementInfo.d.ts.map +1 -0
  35. package/dist/devtools/hooks/useFlowsData.d.ts +16 -0
  36. package/dist/devtools/hooks/useFlowsData.d.ts.map +1 -0
  37. package/dist/devtools/hooks/useGrabMode.d.ts +16 -0
  38. package/dist/devtools/hooks/useGrabMode.d.ts.map +1 -0
  39. package/dist/devtools/hooks/useStepStore.d.ts +22 -0
  40. package/dist/devtools/hooks/useStepStore.d.ts.map +1 -0
  41. package/dist/devtools/index.cjs +2715 -0
  42. package/dist/devtools/index.d.ts +32 -0
  43. package/dist/devtools/index.d.ts.map +1 -0
  44. package/dist/devtools/index.mjs +2715 -0
  45. package/dist/devtools/types.d.ts +66 -0
  46. package/dist/devtools/types.d.ts.map +1 -0
  47. package/dist/devtools/utils/selectorGenerator.d.ts +11 -0
  48. package/dist/devtools/utils/selectorGenerator.d.ts.map +1 -0
  49. package/dist/devtools/utils/sourceExtractor.d.ts +45 -0
  50. package/dist/devtools/utils/sourceExtractor.d.ts.map +1 -0
  51. package/dist/devtools/utils/storage.d.ts +5 -0
  52. package/dist/devtools/utils/storage.d.ts.map +1 -0
  53. package/dist/hooks/useHiddenTargetFallback.d.ts.map +1 -1
  54. package/dist/hooks/useTourOverlay.d.ts.map +1 -1
  55. package/dist/index.cjs +724 -892
  56. package/dist/index.mjs +145 -16
  57. package/dist/router/index.cjs +13 -202
  58. package/dist/router/nextAppRouterAdapter.cjs +11 -200
  59. package/dist/router/nextPagesRouterAdapter.cjs +10 -199
  60. package/dist/router/reactRouterAdapter.cjs +10 -199
  61. package/dist/router/tanstackRouterAdapter.cjs +22 -214
  62. package/package.json +10 -1
@@ -0,0 +1,2715 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+
5
+ var _chunkFCOKCGV3cjs = require('../chunk-FCOKCGV3.cjs');
6
+
7
+ // src/devtools/DevToolsProvider.tsx
8
+ var _react = require('react');
9
+ var _reactdom = require('react-dom');
10
+ var _react3 = require('motion/react');
11
+
12
+ // src/devtools/components/GrabberOverlay.tsx
13
+
14
+
15
+
16
+ // src/devtools/utils/sourceExtractor.ts
17
+ function getReactFiber(element) {
18
+ const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
19
+ if (_optionalChain([hook, 'optionalAccess', _ => _.renderers])) {
20
+ for (const renderer of hook.renderers.values()) {
21
+ if (renderer.findFiberByHostInstance) {
22
+ const fiber = renderer.findFiberByHostInstance(element);
23
+ if (fiber) return fiber;
24
+ }
25
+ }
26
+ }
27
+ const keys = Object.keys(element);
28
+ for (const key of keys) {
29
+ if (key.startsWith("__reactFiber$") || key.startsWith("__reactInternalInstance$")) {
30
+ return element[key];
31
+ }
32
+ }
33
+ return null;
34
+ }
35
+ function getFiberName(fiber) {
36
+ const type = fiber.type || fiber.elementType;
37
+ if (!type) return null;
38
+ if (typeof type === "string") {
39
+ return type;
40
+ }
41
+ if (typeof type === "object") {
42
+ return type.displayName || type.name || null;
43
+ }
44
+ if (typeof type === "function") {
45
+ return type.displayName || type.name || null;
46
+ }
47
+ return null;
48
+ }
49
+ function findDebugSource(fiber) {
50
+ let current = fiber;
51
+ let depth = 0;
52
+ const maxDepth = 50;
53
+ while (current && depth < maxDepth) {
54
+ if (current._debugSource) {
55
+ const source = current._debugSource;
56
+ return {
57
+ fileName: source.fileName,
58
+ lineNumber: source.lineNumber,
59
+ columnNumber: _nullishCoalesce(source.columnNumber, () => ( 0))
60
+ };
61
+ }
62
+ current = _nullishCoalesce(current.return, () => ( null));
63
+ depth++;
64
+ }
65
+ return null;
66
+ }
67
+ function extractSource(params) {
68
+ const { element } = params;
69
+ if (typeof window === "undefined") return null;
70
+ try {
71
+ const fiber = getReactFiber(element);
72
+ if (!fiber) return null;
73
+ return findDebugSource(fiber);
74
+ } catch (e2) {
75
+ return null;
76
+ }
77
+ }
78
+ function extractComponentHierarchy(params) {
79
+ const { element } = params;
80
+ const hierarchy = [];
81
+ if (typeof window === "undefined") return hierarchy;
82
+ try {
83
+ const fiber = getReactFiber(element);
84
+ if (!fiber) return hierarchy;
85
+ let current = fiber;
86
+ let depth = 0;
87
+ const maxDepth = 20;
88
+ while (current && depth < maxDepth) {
89
+ const name = getFiberName(current);
90
+ if (name && !hierarchy.includes(name)) {
91
+ hierarchy.push(name);
92
+ }
93
+ current = _nullishCoalesce(current.return, () => ( null));
94
+ depth++;
95
+ }
96
+ return hierarchy;
97
+ } catch (e3) {
98
+ return hierarchy;
99
+ }
100
+ }
101
+ function formatSourcePath(params) {
102
+ const { source } = params;
103
+ const fileName = source.fileName.replace(/^.*\/src\//, "src/");
104
+ return `${fileName}:${source.lineNumber}`;
105
+ }
106
+ function getVSCodeLink(params) {
107
+ const { source } = params;
108
+ return `vscode://file${source.fileName}:${source.lineNumber}:${source.columnNumber}`;
109
+ }
110
+
111
+ // src/devtools/components/GrabberOverlay.tsx
112
+ var _jsxruntime = require('react/jsx-runtime');
113
+ var styles = {
114
+ root: {
115
+ position: "fixed",
116
+ inset: 0,
117
+ pointerEvents: "none",
118
+ zIndex: 99999
119
+ },
120
+ highlight: {
121
+ position: "absolute",
122
+ border: "2px solid hsl(217 91% 60%)",
123
+ backgroundColor: "hsl(217 91% 60% / 0.08)",
124
+ borderRadius: 6,
125
+ pointerEvents: "none",
126
+ boxShadow: "0 0 0 4px hsl(217 91% 60% / 0.15), 0 4px 20px hsl(217 91% 60% / 0.2)"
127
+ },
128
+ label: {
129
+ position: "absolute",
130
+ bottom: "100%",
131
+ left: 0,
132
+ marginBottom: 6,
133
+ display: "flex",
134
+ flexDirection: "column",
135
+ gap: 4,
136
+ padding: "8px 10px",
137
+ backgroundColor: "hsl(222 47% 11%)",
138
+ border: "1px solid hsl(215 20% 22%)",
139
+ color: "hsl(215 20% 75%)",
140
+ fontSize: 11,
141
+ fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
142
+ borderRadius: 8,
143
+ boxShadow: "0 8px 24px rgba(0, 0, 0, 0.4)",
144
+ maxWidth: 280
145
+ },
146
+ labelTop: {
147
+ display: "flex",
148
+ alignItems: "center",
149
+ gap: 6
150
+ },
151
+ tagBadge: {
152
+ display: "inline-flex",
153
+ alignItems: "center",
154
+ padding: "2px 6px",
155
+ backgroundColor: "hsl(215 20% 22%)",
156
+ color: "hsl(217 91% 70%)",
157
+ fontFamily: "ui-monospace, monospace",
158
+ fontSize: 10,
159
+ fontWeight: 500,
160
+ borderRadius: 4
161
+ },
162
+ selector: {
163
+ color: "hsl(265 83% 78%)",
164
+ fontFamily: "ui-monospace, monospace",
165
+ fontSize: 10,
166
+ overflow: "hidden",
167
+ textOverflow: "ellipsis",
168
+ whiteSpace: "nowrap",
169
+ padding: "4px 6px",
170
+ backgroundColor: "hsl(215 20% 15%)",
171
+ borderRadius: 4,
172
+ border: "1px solid hsl(215 20% 20%)"
173
+ },
174
+ source: {
175
+ display: "flex",
176
+ alignItems: "center",
177
+ gap: 4,
178
+ color: "hsl(142 71% 55%)",
179
+ fontFamily: "ui-monospace, monospace",
180
+ fontSize: 10
181
+ },
182
+ hint: {
183
+ position: "fixed",
184
+ bottom: 20,
185
+ left: "50%",
186
+ transform: "translateX(-50%)",
187
+ display: "flex",
188
+ alignItems: "center",
189
+ gap: 12,
190
+ padding: "10px 16px",
191
+ backgroundColor: "hsl(222 47% 11%)",
192
+ border: "1px solid hsl(215 20% 22%)",
193
+ color: "hsl(215 20% 70%)",
194
+ fontSize: 12,
195
+ fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
196
+ borderRadius: 10,
197
+ boxShadow: "0 8px 32px rgba(0, 0, 0, 0.5)"
198
+ },
199
+ hintItem: {
200
+ display: "flex",
201
+ alignItems: "center",
202
+ gap: 6,
203
+ color: "hsl(215 20% 65%)"
204
+ },
205
+ kbd: {
206
+ display: "inline-flex",
207
+ alignItems: "center",
208
+ padding: "2px 5px",
209
+ backgroundColor: "hsl(215 20% 15%)",
210
+ border: "1px solid hsl(215 20% 22%)",
211
+ borderRadius: 4,
212
+ fontSize: 10,
213
+ fontFamily: "ui-monospace, monospace",
214
+ color: "hsl(215 20% 60%)",
215
+ fontWeight: 500
216
+ },
217
+ divider: {
218
+ width: 1,
219
+ height: 16,
220
+ backgroundColor: "hsl(215 20% 25%)"
221
+ }
222
+ };
223
+ var springTransition = {
224
+ type: "spring",
225
+ damping: 30,
226
+ stiffness: 400,
227
+ mass: 0.8
228
+ };
229
+ function GrabberOverlay(props) {
230
+ const { isGrabbing, hoveredInfo, container } = props;
231
+ if (typeof window === "undefined") return null;
232
+ const portalContainer = _nullishCoalesce(container, () => ( document.body));
233
+ const labelStyle = {
234
+ ...styles.label
235
+ };
236
+ if (hoveredInfo && hoveredInfo.rect.top < 80) {
237
+ labelStyle.bottom = "auto";
238
+ labelStyle.top = "100%";
239
+ labelStyle.marginBottom = 0;
240
+ labelStyle.marginTop = 6;
241
+ }
242
+ if (hoveredInfo && hoveredInfo.rect.left > window.innerWidth - 300) {
243
+ labelStyle.left = "auto";
244
+ labelStyle.right = 0;
245
+ }
246
+ return _reactdom.createPortal.call(void 0,
247
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles.root, "data-devtools-panel": "", children: [
248
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.AnimatePresence, { children: isGrabbing && hoveredInfo && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
249
+ _react3.motion.div,
250
+ {
251
+ style: styles.highlight,
252
+ initial: {
253
+ top: hoveredInfo.rect.top,
254
+ left: hoveredInfo.rect.left,
255
+ width: hoveredInfo.rect.width,
256
+ height: hoveredInfo.rect.height,
257
+ opacity: 0
258
+ },
259
+ animate: {
260
+ top: hoveredInfo.rect.top,
261
+ left: hoveredInfo.rect.left,
262
+ width: hoveredInfo.rect.width,
263
+ height: hoveredInfo.rect.height,
264
+ opacity: 1
265
+ },
266
+ exit: {
267
+ opacity: 0
268
+ },
269
+ transition: springTransition,
270
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
271
+ _react3.motion.div,
272
+ {
273
+ style: labelStyle,
274
+ initial: { opacity: 0, y: 4 },
275
+ animate: { opacity: 1, y: 0 },
276
+ transition: { delay: 0.03, duration: 0.12 },
277
+ children: [
278
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles.labelTop, children: [
279
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { style: styles.tagBadge, children: [
280
+ "<",
281
+ hoveredInfo.tag,
282
+ ">"
283
+ ] }),
284
+ hoveredInfo.text && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
285
+ "span",
286
+ {
287
+ style: {
288
+ color: "hsl(215 20% 65%)",
289
+ overflow: "hidden",
290
+ textOverflow: "ellipsis",
291
+ whiteSpace: "nowrap",
292
+ maxWidth: 150,
293
+ fontSize: 11
294
+ },
295
+ children: hoveredInfo.text
296
+ }
297
+ )
298
+ ] }),
299
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles.selector, children: hoveredInfo.selector }),
300
+ hoveredInfo.source && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles.source, children: [
301
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z" }) }),
302
+ formatSourcePath({ source: hoveredInfo.source })
303
+ ] })
304
+ ]
305
+ }
306
+ )
307
+ },
308
+ "grabber-highlight"
309
+ ) }),
310
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.AnimatePresence, { children: isGrabbing && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
311
+ _react3.motion.div,
312
+ {
313
+ style: styles.hint,
314
+ initial: { opacity: 0, y: 10, scale: 0.95 },
315
+ animate: { opacity: 1, y: 0, scale: 1 },
316
+ exit: { opacity: 0, y: 10, scale: 0.95 },
317
+ transition: { duration: 0.2, ease: [0.16, 1, 0.3, 1] },
318
+ children: [
319
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles.hintItem, children: [
320
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles.kbd, children: "Click" }),
321
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Add step" })
322
+ ] }),
323
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles.divider }),
324
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles.hintItem, children: [
325
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles.kbd, children: "ESC" }),
326
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Cancel" })
327
+ ] }),
328
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles.divider }),
329
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles.hintItem, children: [
330
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles.kbd, children: "Ctrl+Shift+G" }),
331
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Toggle" })
332
+ ] })
333
+ ]
334
+ },
335
+ "grabber-hint"
336
+ ) })
337
+ ] }),
338
+ portalContainer
339
+ );
340
+ }
341
+
342
+ // src/devtools/components/StepList.tsx
343
+
344
+
345
+
346
+
347
+
348
+
349
+
350
+
351
+
352
+ var _core = require('@dnd-kit/core');
353
+
354
+
355
+
356
+
357
+ var _sortable = require('@dnd-kit/sortable');
358
+
359
+ // src/devtools/components/StepItem.tsx
360
+
361
+ var _utilities = require('@dnd-kit/utilities');
362
+
363
+ var styles2 = {
364
+ card: {
365
+ display: "flex",
366
+ alignItems: "stretch",
367
+ gap: 0,
368
+ backgroundColor: "hsl(215 20% 16%)",
369
+ borderRadius: 8,
370
+ border: "1px solid hsl(215 20% 22%)",
371
+ fontSize: 12,
372
+ fontFamily: "inherit",
373
+ overflow: "hidden"
374
+ },
375
+ cardGhost: {
376
+ opacity: 0.4,
377
+ border: "1px dashed hsl(217 91% 60%)",
378
+ backgroundColor: "hsl(217 91% 60% / 0.05)"
379
+ },
380
+ cardOverlay: {
381
+ boxShadow: "0 12px 24px rgba(0, 0, 0, 0.4)",
382
+ border: "1px solid hsl(217 91% 60%)"
383
+ },
384
+ dragHandle: {
385
+ display: "flex",
386
+ alignItems: "center",
387
+ justifyContent: "center",
388
+ width: 28,
389
+ cursor: "grab",
390
+ color: "hsl(215 20% 40%)",
391
+ flexShrink: 0,
392
+ backgroundColor: "hsl(215 20% 13%)",
393
+ borderRight: "1px solid hsl(215 20% 20%)",
394
+ transition: "color 0.15s ease, background-color 0.15s ease"
395
+ },
396
+ dragHandleActive: {
397
+ cursor: "grabbing",
398
+ backgroundColor: "hsl(217 91% 60% / 0.15)",
399
+ color: "hsl(217 91% 60%)"
400
+ },
401
+ content: {
402
+ flex: 1,
403
+ minWidth: 0,
404
+ display: "flex",
405
+ flexDirection: "column",
406
+ gap: 4,
407
+ padding: 10
408
+ },
409
+ header: {
410
+ display: "flex",
411
+ alignItems: "center",
412
+ gap: 6
413
+ },
414
+ order: {
415
+ display: "flex",
416
+ alignItems: "center",
417
+ justifyContent: "center",
418
+ width: 18,
419
+ height: 18,
420
+ backgroundColor: "hsl(217 91% 55% / 0.2)",
421
+ color: "hsl(217 91% 70%)",
422
+ fontSize: 10,
423
+ fontWeight: 600,
424
+ borderRadius: 5,
425
+ flexShrink: 0
426
+ },
427
+ tagBadge: {
428
+ display: "inline-flex",
429
+ alignItems: "center",
430
+ padding: "2px 6px",
431
+ backgroundColor: "hsl(215 20% 22%)",
432
+ color: "hsl(217 91% 70%)",
433
+ fontFamily: "ui-monospace, monospace",
434
+ fontSize: 10,
435
+ fontWeight: 500,
436
+ borderRadius: 4
437
+ },
438
+ text: {
439
+ color: "hsl(215 20% 65%)",
440
+ overflow: "hidden",
441
+ textOverflow: "ellipsis",
442
+ whiteSpace: "nowrap",
443
+ maxWidth: 140,
444
+ fontSize: 11
445
+ },
446
+ selector: {
447
+ display: "block",
448
+ color: "hsl(265 83% 75%)",
449
+ fontFamily: "ui-monospace, monospace",
450
+ fontSize: 10,
451
+ overflow: "hidden",
452
+ textOverflow: "ellipsis",
453
+ whiteSpace: "nowrap",
454
+ padding: "4px 6px",
455
+ backgroundColor: "hsl(215 20% 12%)",
456
+ borderRadius: 4,
457
+ border: "1px solid hsl(215 20% 18%)"
458
+ },
459
+ sourceRow: {
460
+ display: "flex",
461
+ alignItems: "center",
462
+ gap: 4,
463
+ marginTop: 2
464
+ },
465
+ sourceLink: {
466
+ display: "inline-flex",
467
+ alignItems: "center",
468
+ gap: 4,
469
+ color: "hsl(142 71% 55%)",
470
+ fontSize: 10,
471
+ fontFamily: "ui-monospace, monospace",
472
+ textDecoration: "none",
473
+ padding: "2px 0",
474
+ transition: "color 0.15s ease"
475
+ },
476
+ copyButton: {
477
+ display: "flex",
478
+ alignItems: "center",
479
+ justifyContent: "center",
480
+ width: 18,
481
+ height: 18,
482
+ backgroundColor: "transparent",
483
+ border: "none",
484
+ color: "hsl(215 20% 50%)",
485
+ cursor: "pointer",
486
+ padding: 0,
487
+ borderRadius: 4,
488
+ transition: "color 0.15s ease, background-color 0.15s ease",
489
+ outline: "none"
490
+ },
491
+ deleteButton: {
492
+ display: "flex",
493
+ alignItems: "center",
494
+ justifyContent: "center",
495
+ width: 22,
496
+ height: 22,
497
+ backgroundColor: "transparent",
498
+ border: "none",
499
+ color: "hsl(215 20% 45%)",
500
+ cursor: "pointer",
501
+ padding: 0,
502
+ borderRadius: 5,
503
+ flexShrink: 0,
504
+ alignSelf: "flex-start",
505
+ marginTop: 2,
506
+ transition: "color 0.15s ease, background-color 0.15s ease",
507
+ outline: "none"
508
+ }
509
+ };
510
+ function SortableStepItem(props) {
511
+ const { step, index, onDelete, isBeingDragged = false } = props;
512
+ const {
513
+ attributes,
514
+ listeners,
515
+ setNodeRef,
516
+ transform,
517
+ transition,
518
+ isDragging
519
+ } = _sortable.useSortable.call(void 0, { id: step.id });
520
+ const handleCopySource = async () => {
521
+ if (step.source) {
522
+ const path = formatSourcePath({ source: step.source });
523
+ await navigator.clipboard.writeText(path);
524
+ }
525
+ };
526
+ const isGhost = isDragging || isBeingDragged;
527
+ const wrapperStyle = {
528
+ transform: _utilities.CSS.Transform.toString(transform),
529
+ transition: _nullishCoalesce(transition, () => ( "transform 200ms ease"))
530
+ };
531
+ const cardStyle = {
532
+ ...styles2.card,
533
+ ...isGhost && styles2.cardGhost
534
+ };
535
+ const handleStyle = {
536
+ ...styles2.dragHandle
537
+ };
538
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: setNodeRef, style: wrapperStyle, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: cardStyle, children: [
539
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: handleStyle, ...attributes, ...listeners, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "svg", { width: "10", height: "16", viewBox: "0 0 10 16", fill: "currentColor", children: [
540
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "3", cy: "2", r: "1.5" }),
541
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "7", cy: "2", r: "1.5" }),
542
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "3", cy: "8", r: "1.5" }),
543
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "7", cy: "8", r: "1.5" }),
544
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "3", cy: "14", r: "1.5" }),
545
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "7", cy: "14", r: "1.5" })
546
+ ] }) }),
547
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles2.content, children: [
548
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles2.header, children: [
549
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles2.order, children: index + 1 }),
550
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { style: styles2.tagBadge, children: [
551
+ "<",
552
+ step.elementTag,
553
+ ">"
554
+ ] }),
555
+ step.elementText && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles2.text, children: step.elementText })
556
+ ] }),
557
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles2.selector, children: step.selector }),
558
+ step.source && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles2.sourceRow, children: [
559
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
560
+ "svg",
561
+ {
562
+ width: "10",
563
+ height: "10",
564
+ viewBox: "0 0 16 16",
565
+ fill: "hsl(142 71% 55%)",
566
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z" })
567
+ }
568
+ ),
569
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
570
+ "a",
571
+ {
572
+ href: getVSCodeLink({ source: step.source }),
573
+ style: styles2.sourceLink,
574
+ title: "Open in VS Code",
575
+ children: formatSourcePath({ source: step.source })
576
+ }
577
+ ),
578
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
579
+ "button",
580
+ {
581
+ type: "button",
582
+ style: styles2.copyButton,
583
+ onClick: handleCopySource,
584
+ title: "Copy path",
585
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
586
+ "svg",
587
+ {
588
+ width: "10",
589
+ height: "10",
590
+ viewBox: "0 0 16 16",
591
+ fill: "currentColor",
592
+ children: [
593
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zM4 1h6a3 3 0 0 1 3 3v8a3 3 0 0 1-3 3H4a3 3 0 0 1-3-3V4a3 3 0 0 1 3-3z" }),
594
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M14 5a1 1 0 0 1 1 1v8a2 2 0 0 1-2 2H6a1 1 0 0 1 0-2h7V6a1 1 0 0 1 1-1z" })
595
+ ]
596
+ }
597
+ )
598
+ }
599
+ )
600
+ ] })
601
+ ] }),
602
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
603
+ "button",
604
+ {
605
+ type: "button",
606
+ style: styles2.deleteButton,
607
+ onClick: onDelete,
608
+ title: "Delete step",
609
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" }) })
610
+ }
611
+ )
612
+ ] }) });
613
+ }
614
+ function StepItemDragPreview(props) {
615
+ const { step, index } = props;
616
+ const cardStyle = {
617
+ ...styles2.card,
618
+ ...styles2.cardOverlay,
619
+ width: 298
620
+ // Fixed width for overlay
621
+ };
622
+ const handleStyle = {
623
+ ...styles2.dragHandle,
624
+ ...styles2.dragHandleActive
625
+ };
626
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: cardStyle, children: [
627
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: handleStyle, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "svg", { width: "10", height: "16", viewBox: "0 0 10 16", fill: "currentColor", children: [
628
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "3", cy: "2", r: "1.5" }),
629
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "7", cy: "2", r: "1.5" }),
630
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "3", cy: "8", r: "1.5" }),
631
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "7", cy: "8", r: "1.5" }),
632
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "3", cy: "14", r: "1.5" }),
633
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "circle", { cx: "7", cy: "14", r: "1.5" })
634
+ ] }) }),
635
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles2.content, children: [
636
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles2.header, children: [
637
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles2.order, children: index + 1 }),
638
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { style: styles2.tagBadge, children: [
639
+ "<",
640
+ step.elementTag,
641
+ ">"
642
+ ] }),
643
+ step.elementText && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles2.text, children: step.elementText })
644
+ ] }),
645
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles2.selector, children: step.selector }),
646
+ step.source && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles2.sourceRow, children: [
647
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
648
+ "svg",
649
+ {
650
+ width: "10",
651
+ height: "10",
652
+ viewBox: "0 0 16 16",
653
+ fill: "hsl(142 71% 55%)",
654
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z" })
655
+ }
656
+ ),
657
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles2.sourceLink, children: formatSourcePath({ source: step.source }) })
658
+ ] })
659
+ ] }),
660
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { ...styles2.deleteButton, visibility: "hidden" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" }) }) })
661
+ ] });
662
+ }
663
+
664
+ // src/devtools/components/Toolbar.tsx
665
+
666
+
667
+
668
+ var styles3 = {
669
+ toolbar: {
670
+ display: "flex",
671
+ flexDirection: "column",
672
+ gap: 8,
673
+ padding: "10px 10px 0"
674
+ },
675
+ grabRow: {
676
+ display: "flex",
677
+ gap: 6
678
+ },
679
+ grabButton: {
680
+ flex: 1,
681
+ display: "flex",
682
+ alignItems: "center",
683
+ justifyContent: "center",
684
+ gap: 6,
685
+ padding: "8px 12px",
686
+ backgroundColor: "#252a35",
687
+ border: "1px solid #353d4a",
688
+ borderRadius: 8,
689
+ color: "#a3adc2",
690
+ fontSize: 12,
691
+ fontWeight: 500,
692
+ fontFamily: "inherit",
693
+ cursor: "pointer",
694
+ transition: "all 0.15s ease",
695
+ outline: "none"
696
+ },
697
+ grabButtonActive: {
698
+ backgroundColor: "rgba(59, 130, 246, 0.15)",
699
+ borderColor: "rgba(59, 130, 246, 0.4)",
700
+ color: "#60a5fa",
701
+ boxShadow: "0 0 0 2px rgba(59, 130, 246, 0.1)"
702
+ },
703
+ actionRow: {
704
+ display: "flex",
705
+ gap: 6
706
+ },
707
+ actionButton: {
708
+ flex: 1,
709
+ display: "flex",
710
+ alignItems: "center",
711
+ justifyContent: "center",
712
+ gap: 5,
713
+ padding: "7px 8px",
714
+ backgroundColor: "transparent",
715
+ border: "1px solid #2d3544",
716
+ borderRadius: 6,
717
+ color: "#8b96a9",
718
+ fontSize: 11,
719
+ fontWeight: 500,
720
+ fontFamily: "inherit",
721
+ cursor: "pointer",
722
+ transition: "all 0.15s ease",
723
+ whiteSpace: "nowrap",
724
+ position: "relative",
725
+ outline: "none"
726
+ },
727
+ actionButtonDisabled: {
728
+ opacity: 0.4,
729
+ cursor: "not-allowed"
730
+ },
731
+ actionButtonDanger: {
732
+ borderColor: "#7a2c2c",
733
+ color: "#e05555"
734
+ },
735
+ kbd: {
736
+ display: "inline-flex",
737
+ alignItems: "center",
738
+ padding: "1px 4px",
739
+ marginLeft: 6,
740
+ backgroundColor: "#1e232c",
741
+ border: "1px solid #2d3544",
742
+ borderRadius: 3,
743
+ fontSize: 10,
744
+ fontFamily: "ui-monospace, monospace",
745
+ color: "#6b7685"
746
+ },
747
+ copiedBadge: {
748
+ position: "absolute",
749
+ top: -6,
750
+ right: -6,
751
+ padding: "2px 5px",
752
+ backgroundColor: "#166534",
753
+ color: "#86efac",
754
+ fontSize: 9,
755
+ fontWeight: 600,
756
+ borderRadius: 4,
757
+ boxShadow: "0 2px 8px rgba(0, 0, 0, 0.3)"
758
+ }
759
+ };
760
+ function Toolbar(props) {
761
+ const { mode, stepCount, onToggleGrab, onExport, onCopyForAI, onReset } = props;
762
+ const [copied, setCopied] = _react.useState.call(void 0, false);
763
+ const isGrabbing = mode === "grabbing";
764
+ const hasSteps = stepCount > 0;
765
+ const handleCopy = async () => {
766
+ await onCopyForAI();
767
+ setCopied(true);
768
+ setTimeout(() => setCopied(false), 1500);
769
+ };
770
+ const grabButtonStyle = {
771
+ ...styles3.grabButton,
772
+ ...isGrabbing && styles3.grabButtonActive
773
+ };
774
+ const exportButtonStyle = {
775
+ ...styles3.actionButton,
776
+ ...!hasSteps && styles3.actionButtonDisabled
777
+ };
778
+ const copyButtonStyle = {
779
+ ...styles3.actionButton,
780
+ ...!hasSteps && styles3.actionButtonDisabled
781
+ };
782
+ const resetButtonStyle = {
783
+ ...styles3.actionButton,
784
+ ...!hasSteps && styles3.actionButtonDisabled,
785
+ ...hasSteps && styles3.actionButtonDanger
786
+ };
787
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles3.toolbar, children: [
788
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles3.grabRow, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
789
+ _react3.motion.button,
790
+ {
791
+ type: "button",
792
+ style: grabButtonStyle,
793
+ onClick: onToggleGrab,
794
+ whileHover: { scale: 1.01 },
795
+ whileTap: { scale: 0.98 },
796
+ children: isGrabbing ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
797
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
798
+ "svg",
799
+ {
800
+ width: "14",
801
+ height: "14",
802
+ viewBox: "0 0 16 16",
803
+ fill: "currentColor",
804
+ children: [
805
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "circle", { cx: "8", cy: "8", r: "3", children: [
806
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
807
+ "animate",
808
+ {
809
+ attributeName: "r",
810
+ values: "3;4;3",
811
+ dur: "1s",
812
+ repeatCount: "indefinite"
813
+ }
814
+ ),
815
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
816
+ "animate",
817
+ {
818
+ attributeName: "opacity",
819
+ values: "1;0.5;1",
820
+ dur: "1s",
821
+ repeatCount: "indefinite"
822
+ }
823
+ )
824
+ ] }),
825
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
826
+ "circle",
827
+ {
828
+ cx: "8",
829
+ cy: "8",
830
+ r: "6",
831
+ fill: "none",
832
+ stroke: "currentColor",
833
+ strokeWidth: "1",
834
+ opacity: "0.3",
835
+ children: [
836
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
837
+ "animate",
838
+ {
839
+ attributeName: "r",
840
+ values: "4;7;4",
841
+ dur: "1.5s",
842
+ repeatCount: "indefinite"
843
+ }
844
+ ),
845
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
846
+ "animate",
847
+ {
848
+ attributeName: "opacity",
849
+ values: "0.3;0;0.3",
850
+ dur: "1.5s",
851
+ repeatCount: "indefinite"
852
+ }
853
+ )
854
+ ]
855
+ }
856
+ )
857
+ ]
858
+ }
859
+ ),
860
+ "Grabbing..."
861
+ ] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
862
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
863
+ "svg",
864
+ {
865
+ width: "14",
866
+ height: "14",
867
+ viewBox: "0 0 16 16",
868
+ fill: "currentColor",
869
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M14 0a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12zM5.904 10.803L10 6.707v2.768a.5.5 0 0 0 1 0V5.5a.5.5 0 0 0-.5-.5H6.525a.5.5 0 1 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 .707.707z" })
870
+ }
871
+ ),
872
+ "Grab Element",
873
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles3.kbd, children: "Ctrl+Shift+G" })
874
+ ] })
875
+ }
876
+ ) }),
877
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles3.actionRow, children: [
878
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
879
+ _react3.motion.button,
880
+ {
881
+ type: "button",
882
+ style: exportButtonStyle,
883
+ onClick: onExport,
884
+ disabled: !hasSteps,
885
+ whileHover: hasSteps ? { scale: 1.02 } : {},
886
+ whileTap: hasSteps ? { scale: 0.98 } : {},
887
+ title: "Download JSON file",
888
+ children: [
889
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "svg", { width: "11", height: "11", viewBox: "0 0 16 16", fill: "currentColor", children: [
890
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z" }),
891
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z" })
892
+ ] }),
893
+ "Export"
894
+ ]
895
+ }
896
+ ),
897
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
898
+ _react3.motion.button,
899
+ {
900
+ type: "button",
901
+ style: copyButtonStyle,
902
+ onClick: handleCopy,
903
+ disabled: !hasSteps,
904
+ whileHover: hasSteps ? { scale: 1.02 } : {},
905
+ whileTap: hasSteps ? { scale: 0.98 } : {},
906
+ title: "Copy JSON to clipboard",
907
+ children: [
908
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "svg", { width: "11", height: "11", viewBox: "0 0 16 16", fill: "currentColor", children: [
909
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zM4 1h6a3 3 0 0 1 3 3v8a3 3 0 0 1-3 3H4a3 3 0 0 1-3-3V4a3 3 0 0 1 3-3z" }),
910
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M14 5a1 1 0 0 1 1 1v8a2 2 0 0 1-2 2H6a1 1 0 0 1 0-2h7V6a1 1 0 0 1 1-1z" })
911
+ ] }),
912
+ "Copy",
913
+ copied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
914
+ _react3.motion.span,
915
+ {
916
+ style: styles3.copiedBadge,
917
+ initial: { opacity: 0, scale: 0.8, y: 4 },
918
+ animate: { opacity: 1, scale: 1, y: 0 },
919
+ exit: { opacity: 0, scale: 0.8 },
920
+ children: "Copied!"
921
+ }
922
+ )
923
+ ]
924
+ }
925
+ ),
926
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
927
+ _react3.motion.button,
928
+ {
929
+ type: "button",
930
+ style: resetButtonStyle,
931
+ onClick: onReset,
932
+ disabled: !hasSteps,
933
+ whileHover: hasSteps ? { scale: 1.02 } : {},
934
+ whileTap: hasSteps ? { scale: 0.98 } : {},
935
+ title: "Clear all steps",
936
+ children: [
937
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "svg", { width: "11", height: "11", viewBox: "0 0 16 16", fill: "currentColor", children: [
938
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" }),
939
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
940
+ "path",
941
+ {
942
+ fillRule: "evenodd",
943
+ d: "M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4L4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"
944
+ }
945
+ )
946
+ ] }),
947
+ "Reset"
948
+ ]
949
+ }
950
+ )
951
+ ] })
952
+ ] });
953
+ }
954
+
955
+ // src/devtools/components/StepList.tsx
956
+
957
+ var styles4 = {
958
+ scrollArea: {
959
+ flex: 1,
960
+ overflowY: "auto",
961
+ overflowX: "hidden",
962
+ padding: 10
963
+ },
964
+ stepList: {
965
+ display: "flex",
966
+ flexDirection: "column",
967
+ gap: 6
968
+ },
969
+ empty: {
970
+ display: "flex",
971
+ flexDirection: "column",
972
+ alignItems: "center",
973
+ justifyContent: "center",
974
+ gap: 8,
975
+ padding: "32px 16px",
976
+ textAlign: "center",
977
+ color: "hsl(215 20% 55%)"
978
+ },
979
+ emptyIcon: {
980
+ width: 40,
981
+ height: 40,
982
+ borderRadius: 10,
983
+ backgroundColor: "hsl(215 20% 18%)",
984
+ display: "flex",
985
+ alignItems: "center",
986
+ justifyContent: "center",
987
+ marginBottom: 4
988
+ },
989
+ emptyText: {
990
+ fontSize: 13,
991
+ lineHeight: 1.5
992
+ },
993
+ kbd: {
994
+ display: "inline-flex",
995
+ alignItems: "center",
996
+ padding: "2px 5px",
997
+ backgroundColor: "hsl(215 20% 15%)",
998
+ border: "1px solid hsl(215 20% 22%)",
999
+ borderRadius: 4,
1000
+ fontSize: 11,
1001
+ fontFamily: "ui-monospace, monospace",
1002
+ color: "hsl(215 20% 55%)"
1003
+ }
1004
+ };
1005
+ function StepList(props) {
1006
+ const {
1007
+ steps,
1008
+ mode,
1009
+ onToggleGrab,
1010
+ onDeleteStep,
1011
+ onReorderSteps,
1012
+ onClearAll,
1013
+ onExport
1014
+ } = props;
1015
+ const [activeId, setActiveId] = _react.useState.call(void 0, null);
1016
+ const activeStep = activeId ? steps.find((s) => s.id === activeId) : null;
1017
+ const activeIndex = activeId ? steps.findIndex((s) => s.id === activeId) : -1;
1018
+ const sensors = _core.useSensors.call(void 0,
1019
+ _core.useSensor.call(void 0, _core.PointerSensor, {
1020
+ activationConstraint: {
1021
+ distance: 4
1022
+ }
1023
+ }),
1024
+ _core.useSensor.call(void 0, _core.KeyboardSensor, {
1025
+ coordinateGetter: _sortable.sortableKeyboardCoordinates
1026
+ })
1027
+ );
1028
+ const handleDragStart = _react.useCallback.call(void 0, (event) => {
1029
+ setActiveId(event.active.id);
1030
+ }, []);
1031
+ const handleDragEnd = _react.useCallback.call(void 0,
1032
+ (event) => {
1033
+ const { active, over } = event;
1034
+ setActiveId(null);
1035
+ if (over && active.id !== over.id) {
1036
+ const oldIndex = steps.findIndex((s) => s.id === active.id);
1037
+ const newIndex = steps.findIndex((s) => s.id === over.id);
1038
+ if (oldIndex !== -1 && newIndex !== -1) {
1039
+ onReorderSteps({ fromIndex: oldIndex, toIndex: newIndex });
1040
+ }
1041
+ }
1042
+ },
1043
+ [steps, onReorderSteps]
1044
+ );
1045
+ const handleDragCancel = _react.useCallback.call(void 0, () => {
1046
+ setActiveId(null);
1047
+ }, []);
1048
+ const handleExportClick = _react.useCallback.call(void 0, () => {
1049
+ const data = onExport();
1050
+ const blob = new Blob([JSON.stringify(data, null, 2)], {
1051
+ type: "application/json"
1052
+ });
1053
+ const url = URL.createObjectURL(blob);
1054
+ const a = document.createElement("a");
1055
+ a.href = url;
1056
+ a.download = `flowsterix-steps-${Date.now()}.json`;
1057
+ a.click();
1058
+ URL.revokeObjectURL(url);
1059
+ }, [onExport]);
1060
+ const handleCopyForAI = _react.useCallback.call(void 0, async () => {
1061
+ const data = onExport();
1062
+ await navigator.clipboard.writeText(JSON.stringify(data, null, 2));
1063
+ }, [onExport]);
1064
+ const handleReset = _react.useCallback.call(void 0, () => {
1065
+ if (confirm("Clear all steps? This cannot be undone.")) {
1066
+ onClearAll();
1067
+ }
1068
+ }, [onClearAll]);
1069
+ if (typeof window === "undefined") return null;
1070
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1071
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1072
+ Toolbar,
1073
+ {
1074
+ mode,
1075
+ stepCount: steps.length,
1076
+ onToggleGrab,
1077
+ onExport: handleExportClick,
1078
+ onCopyForAI: handleCopyForAI,
1079
+ onReset: handleReset
1080
+ }
1081
+ ),
1082
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles4.scrollArea, children: steps.length === 0 ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles4.empty, children: [
1083
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles4.emptyIcon, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1084
+ "svg",
1085
+ {
1086
+ width: "20",
1087
+ height: "20",
1088
+ viewBox: "0 0 16 16",
1089
+ fill: "hsl(215 20% 45%)",
1090
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M14 0a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12zM5.904 10.803L10 6.707v2.768a.5.5 0 0 0 1 0V5.5a.5.5 0 0 0-.5-.5H6.525a.5.5 0 1 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 .707.707z" })
1091
+ }
1092
+ ) }),
1093
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles4.emptyText, children: [
1094
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { children: "No steps captured yet." }),
1095
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { marginTop: 6 }, children: [
1096
+ "Press ",
1097
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles4.kbd, children: "Ctrl+Shift+G" }),
1098
+ " to grab"
1099
+ ] })
1100
+ ] })
1101
+ ] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1102
+ _core.DndContext,
1103
+ {
1104
+ sensors,
1105
+ collisionDetection: _core.closestCenter,
1106
+ onDragStart: handleDragStart,
1107
+ onDragEnd: handleDragEnd,
1108
+ onDragCancel: handleDragCancel,
1109
+ children: [
1110
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1111
+ _sortable.SortableContext,
1112
+ {
1113
+ items: steps.map((s) => s.id),
1114
+ strategy: _sortable.verticalListSortingStrategy,
1115
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles4.stepList, children: steps.map((step, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1116
+ SortableStepItem,
1117
+ {
1118
+ step,
1119
+ index,
1120
+ onDelete: () => onDeleteStep({ id: step.id }),
1121
+ isDragActive: activeId !== null,
1122
+ isBeingDragged: step.id === activeId
1123
+ },
1124
+ step.id
1125
+ )) })
1126
+ }
1127
+ ),
1128
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _core.DragOverlay, { dropAnimation: null, children: activeStep && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StepItemDragPreview, { step: activeStep, index: activeIndex }) })
1129
+ ]
1130
+ }
1131
+ ) })
1132
+ ] });
1133
+ }
1134
+
1135
+ // src/devtools/components/TabNav.tsx
1136
+
1137
+ var styles5 = {
1138
+ container: {
1139
+ display: "flex",
1140
+ gap: 2,
1141
+ padding: "8px 10px 0",
1142
+ borderBottom: "1px solid hsl(215 20% 20%)"
1143
+ },
1144
+ tab: {
1145
+ flex: 1,
1146
+ display: "flex",
1147
+ alignItems: "center",
1148
+ justifyContent: "center",
1149
+ gap: 6,
1150
+ padding: "8px 12px",
1151
+ backgroundColor: "transparent",
1152
+ border: "none",
1153
+ borderBottom: "2px solid transparent",
1154
+ color: "hsl(215 20% 55%)",
1155
+ fontSize: 12,
1156
+ fontWeight: 500,
1157
+ fontFamily: "inherit",
1158
+ cursor: "pointer",
1159
+ transition: "all 0.15s ease",
1160
+ outline: "none",
1161
+ marginBottom: -1
1162
+ },
1163
+ tabActive: {
1164
+ color: "hsl(217 91% 70%)",
1165
+ borderBottomColor: "hsl(217 91% 60%)"
1166
+ },
1167
+ badge: {
1168
+ display: "inline-flex",
1169
+ alignItems: "center",
1170
+ justifyContent: "center",
1171
+ minWidth: 18,
1172
+ height: 18,
1173
+ padding: "0 5px",
1174
+ backgroundColor: "hsl(215 20% 22%)",
1175
+ color: "hsl(215 20% 60%)",
1176
+ fontSize: 10,
1177
+ fontWeight: 600,
1178
+ borderRadius: 9
1179
+ },
1180
+ badgeActive: {
1181
+ backgroundColor: "hsl(217 91% 55% / 0.2)",
1182
+ color: "hsl(217 91% 70%)"
1183
+ }
1184
+ };
1185
+ function TabNav(props) {
1186
+ const { activeTab, onTabChange, stepCount, flowCount } = props;
1187
+ const stepsTabStyle = {
1188
+ ...styles5.tab,
1189
+ ...activeTab === "steps" && styles5.tabActive
1190
+ };
1191
+ const flowsTabStyle = {
1192
+ ...styles5.tab,
1193
+ ...activeTab === "flows" && styles5.tabActive
1194
+ };
1195
+ const stepsBadgeStyle = {
1196
+ ...styles5.badge,
1197
+ ...activeTab === "steps" && styles5.badgeActive
1198
+ };
1199
+ const flowsBadgeStyle = {
1200
+ ...styles5.badge,
1201
+ ...activeTab === "flows" && styles5.badgeActive
1202
+ };
1203
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles5.container, children: [
1204
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1205
+ "button",
1206
+ {
1207
+ type: "button",
1208
+ style: stepsTabStyle,
1209
+ onClick: () => onTabChange("steps"),
1210
+ children: [
1211
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M14 0a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12zM5.904 10.803L10 6.707v2.768a.5.5 0 0 0 1 0V5.5a.5.5 0 0 0-.5-.5H6.525a.5.5 0 1 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 .707.707z" }) }),
1212
+ "Steps",
1213
+ stepCount > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: stepsBadgeStyle, children: stepCount })
1214
+ ]
1215
+ }
1216
+ ),
1217
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1218
+ "button",
1219
+ {
1220
+ type: "button",
1221
+ style: flowsTabStyle,
1222
+ onClick: () => onTabChange("flows"),
1223
+ children: [
1224
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M6 3.5A1.5 1.5 0 0 1 7.5 2h1A1.5 1.5 0 0 1 10 3.5v1A1.5 1.5 0 0 1 8.5 6v1H14a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0v-1A.5.5 0 0 1 2 7h5.5V6A1.5 1.5 0 0 1 6 4.5v-1zm-3 8A1.5 1.5 0 0 1 4.5 10h1A1.5 1.5 0 0 1 7 11.5v1A1.5 1.5 0 0 1 5.5 14h-1A1.5 1.5 0 0 1 3 12.5v-1zm6 0a1.5 1.5 0 0 1 1.5-1.5h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1A1.5 1.5 0 0 1 9 12.5v-1z" }) }),
1225
+ "Flows",
1226
+ flowCount > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: flowsBadgeStyle, children: flowCount })
1227
+ ]
1228
+ }
1229
+ )
1230
+ ] });
1231
+ }
1232
+
1233
+ // src/devtools/components/FlowsTab.tsx
1234
+
1235
+
1236
+
1237
+ // src/devtools/hooks/useFlowsData.ts
1238
+
1239
+
1240
+ // src/devtools/globalBridge.ts
1241
+ var BRIDGE_KEY = "__FLOWSTERIX_DEVTOOLS_BRIDGE__";
1242
+ function getBridge() {
1243
+ if (typeof window === "undefined") {
1244
+ return { value: null, listeners: /* @__PURE__ */ new Set() };
1245
+ }
1246
+ const w = window;
1247
+ if (!w[BRIDGE_KEY]) {
1248
+ w[BRIDGE_KEY] = { value: null, listeners: /* @__PURE__ */ new Set() };
1249
+ }
1250
+ return w[BRIDGE_KEY];
1251
+ }
1252
+ function getDevToolsBridge() {
1253
+ return getBridge().value;
1254
+ }
1255
+ function subscribeDevToolsBridge(listener) {
1256
+ const bridge = getBridge();
1257
+ bridge.listeners.add(listener);
1258
+ return () => {
1259
+ bridge.listeners.delete(listener);
1260
+ };
1261
+ }
1262
+
1263
+ // src/devtools/hooks/useFlowsData.ts
1264
+ function useBridge() {
1265
+ return _react.useSyncExternalStore.call(void 0,
1266
+ subscribeDevToolsBridge,
1267
+ getDevToolsBridge,
1268
+ () => null
1269
+ // Server snapshot
1270
+ );
1271
+ }
1272
+ function useFlowsData() {
1273
+ const bridge = useBridge();
1274
+ const [flowsData, setFlowsData] = _react.useState.call(void 0, []);
1275
+ const loadFlowStates = _react.useCallback.call(void 0, async () => {
1276
+ if (!bridge) {
1277
+ setFlowsData([]);
1278
+ return;
1279
+ }
1280
+ const { flows, activeFlowId, state: activeState, getFlowState } = bridge;
1281
+ const flowDataPromises = [];
1282
+ for (const [flowId, definition] of flows) {
1283
+ const isActive = flowId === activeFlowId;
1284
+ flowDataPromises.push(
1285
+ (async () => {
1286
+ const flowState = isActive ? activeState : await getFlowState(flowId);
1287
+ return {
1288
+ flowId,
1289
+ definition,
1290
+ state: flowState,
1291
+ isActive
1292
+ };
1293
+ })()
1294
+ );
1295
+ }
1296
+ const results = await Promise.all(flowDataPromises);
1297
+ setFlowsData(results);
1298
+ }, [bridge]);
1299
+ _react.useEffect.call(void 0, () => {
1300
+ void loadFlowStates();
1301
+ }, [loadFlowStates]);
1302
+ const deleteFlow = _react.useCallback.call(void 0,
1303
+ async (flowId) => {
1304
+ if (!bridge) return;
1305
+ if (bridge.activeFlowId === flowId) {
1306
+ bridge.cancel();
1307
+ }
1308
+ await bridge.deleteFlowStorage(flowId);
1309
+ await loadFlowStates();
1310
+ },
1311
+ [bridge, loadFlowStates]
1312
+ );
1313
+ const updateFlow = _react.useCallback.call(void 0,
1314
+ async (flowId, newState) => {
1315
+ if (!bridge) return;
1316
+ await bridge.updateFlowStorage(flowId, newState);
1317
+ await loadFlowStates();
1318
+ },
1319
+ [bridge, loadFlowStates]
1320
+ );
1321
+ return {
1322
+ flows: flowsData,
1323
+ refreshFlows: loadFlowStates,
1324
+ deleteFlow,
1325
+ updateFlow
1326
+ };
1327
+ }
1328
+
1329
+ // src/devtools/components/FlowItem.tsx
1330
+
1331
+
1332
+
1333
+ var styles6 = {
1334
+ card: {
1335
+ display: "flex",
1336
+ flexDirection: "column",
1337
+ gap: 8,
1338
+ padding: 12,
1339
+ backgroundColor: "hsl(215 20% 16%)",
1340
+ borderRadius: 8,
1341
+ border: "1px solid hsl(215 20% 22%)",
1342
+ fontSize: 12,
1343
+ fontFamily: "inherit"
1344
+ },
1345
+ cardActive: {
1346
+ borderColor: "hsl(217 91% 55% / 0.5)",
1347
+ backgroundColor: "hsl(217 91% 55% / 0.05)"
1348
+ },
1349
+ header: {
1350
+ display: "flex",
1351
+ alignItems: "center",
1352
+ justifyContent: "space-between",
1353
+ gap: 8
1354
+ },
1355
+ titleGroup: {
1356
+ display: "flex",
1357
+ alignItems: "center",
1358
+ gap: 8,
1359
+ minWidth: 0
1360
+ },
1361
+ flowId: {
1362
+ fontWeight: 600,
1363
+ color: "hsl(215 20% 85%)",
1364
+ overflow: "hidden",
1365
+ textOverflow: "ellipsis",
1366
+ whiteSpace: "nowrap"
1367
+ },
1368
+ statusBadge: {
1369
+ display: "inline-flex",
1370
+ alignItems: "center",
1371
+ padding: "2px 6px",
1372
+ fontSize: 10,
1373
+ fontWeight: 500,
1374
+ borderRadius: 4,
1375
+ flexShrink: 0
1376
+ },
1377
+ statusIdle: {
1378
+ backgroundColor: "hsl(215 20% 22%)",
1379
+ color: "hsl(215 20% 60%)"
1380
+ },
1381
+ statusRunning: {
1382
+ backgroundColor: "hsl(142 71% 45% / 0.2)",
1383
+ color: "hsl(142 71% 60%)"
1384
+ },
1385
+ statusPaused: {
1386
+ backgroundColor: "hsl(45 93% 47% / 0.2)",
1387
+ color: "hsl(45 93% 60%)"
1388
+ },
1389
+ statusCompleted: {
1390
+ backgroundColor: "hsl(217 91% 55% / 0.2)",
1391
+ color: "hsl(217 91% 70%)"
1392
+ },
1393
+ statusCancelled: {
1394
+ backgroundColor: "hsl(0 70% 50% / 0.2)",
1395
+ color: "hsl(0 70% 65%)"
1396
+ },
1397
+ activeBadge: {
1398
+ backgroundColor: "hsl(142 71% 45% / 0.2)",
1399
+ color: "hsl(142 71% 60%)"
1400
+ },
1401
+ infoRow: {
1402
+ display: "flex",
1403
+ alignItems: "center",
1404
+ gap: 12,
1405
+ color: "hsl(215 20% 55%)",
1406
+ fontSize: 11
1407
+ },
1408
+ infoItem: {
1409
+ display: "flex",
1410
+ alignItems: "center",
1411
+ gap: 4
1412
+ },
1413
+ label: {
1414
+ color: "hsl(215 20% 45%)"
1415
+ },
1416
+ value: {
1417
+ fontFamily: "ui-monospace, monospace",
1418
+ color: "hsl(215 20% 65%)"
1419
+ },
1420
+ actions: {
1421
+ display: "flex",
1422
+ gap: 6,
1423
+ marginTop: 4
1424
+ },
1425
+ actionButton: {
1426
+ display: "flex",
1427
+ alignItems: "center",
1428
+ justifyContent: "center",
1429
+ gap: 4,
1430
+ padding: "6px 10px",
1431
+ backgroundColor: "transparent",
1432
+ border: "1px solid hsl(215 20% 25%)",
1433
+ borderRadius: 5,
1434
+ color: "hsl(215 20% 60%)",
1435
+ fontSize: 10,
1436
+ fontWeight: 500,
1437
+ fontFamily: "inherit",
1438
+ cursor: "pointer",
1439
+ transition: "all 0.15s ease",
1440
+ outline: "none"
1441
+ },
1442
+ actionButtonDanger: {
1443
+ borderColor: "hsl(0 70% 40%)",
1444
+ color: "hsl(0 70% 60%)"
1445
+ },
1446
+ noState: {
1447
+ padding: "8px 0",
1448
+ color: "hsl(215 20% 45%)",
1449
+ fontSize: 11,
1450
+ fontStyle: "italic"
1451
+ }
1452
+ };
1453
+ var statusStyles = {
1454
+ idle: styles6.statusIdle,
1455
+ running: styles6.statusRunning,
1456
+ paused: styles6.statusPaused,
1457
+ completed: styles6.statusCompleted,
1458
+ cancelled: styles6.statusCancelled
1459
+ };
1460
+ function FlowItem(props) {
1461
+ const { flow, onEdit, onDelete } = props;
1462
+ const { flowId, definition, state, isActive } = flow;
1463
+ const [confirmDelete, setConfirmDelete] = _react.useState.call(void 0, false);
1464
+ const handleDelete = () => {
1465
+ if (confirmDelete) {
1466
+ onDelete();
1467
+ setConfirmDelete(false);
1468
+ } else {
1469
+ setConfirmDelete(true);
1470
+ setTimeout(() => setConfirmDelete(false), 3e3);
1471
+ }
1472
+ };
1473
+ const cardStyle = {
1474
+ ...styles6.card,
1475
+ ...isActive && styles6.cardActive
1476
+ };
1477
+ const statusBadgeStyle = {
1478
+ ...styles6.statusBadge,
1479
+ ...state ? statusStyles[state.status] || styles6.statusIdle : styles6.statusIdle
1480
+ };
1481
+ const deleteButtonStyle = {
1482
+ ...styles6.actionButton,
1483
+ ...confirmDelete && styles6.actionButtonDanger
1484
+ };
1485
+ const stepInfo = state ? `Step ${state.stepIndex + 1}/${definition.steps.length}` : null;
1486
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: cardStyle, children: [
1487
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles6.header, children: [
1488
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles6.titleGroup, children: [
1489
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles6.flowId, children: flowId }),
1490
+ isActive && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { ...styles6.statusBadge, ...styles6.activeBadge }, children: "Active" })
1491
+ ] }),
1492
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: statusBadgeStyle, children: _nullishCoalesce(_optionalChain([state, 'optionalAccess', _2 => _2.status]), () => ( "no state")) })
1493
+ ] }),
1494
+ state ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles6.infoRow, children: [
1495
+ stepInfo && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles6.infoItem, children: [
1496
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles6.label, children: "Step:" }),
1497
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles6.value, children: stepInfo })
1498
+ ] }),
1499
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles6.infoItem, children: [
1500
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles6.label, children: "Version:" }),
1501
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles6.value, children: state.version })
1502
+ ] }),
1503
+ state.stepId && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles6.infoItem, children: [
1504
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles6.label, children: "ID:" }),
1505
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles6.value, children: state.stepId })
1506
+ ] })
1507
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles6.noState, children: "No stored state" }),
1508
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles6.actions, children: [
1509
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1510
+ _react3.motion.button,
1511
+ {
1512
+ type: "button",
1513
+ style: styles6.actionButton,
1514
+ onClick: onEdit,
1515
+ disabled: !state,
1516
+ whileHover: state ? { scale: 1.02 } : {},
1517
+ whileTap: state ? { scale: 0.98 } : {},
1518
+ title: state ? "Edit flow state" : "No state to edit",
1519
+ children: [
1520
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5L13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175l-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z" }) }),
1521
+ "Edit"
1522
+ ]
1523
+ }
1524
+ ),
1525
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1526
+ _react3.motion.button,
1527
+ {
1528
+ type: "button",
1529
+ style: deleteButtonStyle,
1530
+ onClick: handleDelete,
1531
+ disabled: !state,
1532
+ whileHover: state ? { scale: 1.02 } : {},
1533
+ whileTap: state ? { scale: 0.98 } : {},
1534
+ title: confirmDelete ? "Click again to confirm deletion" : state ? "Delete flow state" : "No state to delete",
1535
+ children: [
1536
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "currentColor", children: [
1537
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" }),
1538
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1539
+ "path",
1540
+ {
1541
+ fillRule: "evenodd",
1542
+ d: "M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4L4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"
1543
+ }
1544
+ )
1545
+ ] }),
1546
+ confirmDelete ? "Confirm?" : "Delete"
1547
+ ]
1548
+ }
1549
+ )
1550
+ ] })
1551
+ ] });
1552
+ }
1553
+
1554
+ // src/devtools/components/FlowEditModal.tsx
1555
+
1556
+
1557
+
1558
+
1559
+ var styles7 = {
1560
+ overlay: {
1561
+ position: "fixed",
1562
+ inset: 0,
1563
+ backgroundColor: "rgba(0, 0, 0, 0.6)",
1564
+ display: "flex",
1565
+ alignItems: "center",
1566
+ justifyContent: "center",
1567
+ zIndex: 1e5,
1568
+ padding: 20
1569
+ },
1570
+ modal: {
1571
+ width: "100%",
1572
+ maxWidth: 500,
1573
+ maxHeight: "calc(100vh - 40px)",
1574
+ backgroundColor: "hsl(222 47% 11%)",
1575
+ borderRadius: 12,
1576
+ border: "1px solid hsl(215 20% 25%)",
1577
+ boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.5)",
1578
+ display: "flex",
1579
+ flexDirection: "column",
1580
+ overflow: "hidden",
1581
+ fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"
1582
+ },
1583
+ header: {
1584
+ display: "flex",
1585
+ alignItems: "center",
1586
+ justifyContent: "space-between",
1587
+ padding: "14px 16px",
1588
+ borderBottom: "1px solid hsl(215 20% 20%)"
1589
+ },
1590
+ title: {
1591
+ fontSize: 14,
1592
+ fontWeight: 600,
1593
+ color: "hsl(215 20% 85%)"
1594
+ },
1595
+ closeButton: {
1596
+ display: "flex",
1597
+ alignItems: "center",
1598
+ justifyContent: "center",
1599
+ width: 28,
1600
+ height: 28,
1601
+ backgroundColor: "transparent",
1602
+ border: "none",
1603
+ color: "hsl(215 20% 55%)",
1604
+ cursor: "pointer",
1605
+ borderRadius: 6,
1606
+ transition: "all 0.15s ease",
1607
+ outline: "none"
1608
+ },
1609
+ body: {
1610
+ flex: 1,
1611
+ padding: 16,
1612
+ overflowY: "auto"
1613
+ },
1614
+ textarea: {
1615
+ width: "100%",
1616
+ minHeight: 300,
1617
+ padding: 12,
1618
+ backgroundColor: "hsl(215 20% 8%)",
1619
+ border: "1px solid hsl(215 20% 20%)",
1620
+ borderRadius: 8,
1621
+ color: "hsl(215 20% 85%)",
1622
+ fontSize: 12,
1623
+ fontFamily: "ui-monospace, monospace",
1624
+ resize: "vertical",
1625
+ outline: "none",
1626
+ lineHeight: 1.5
1627
+ },
1628
+ textareaError: {
1629
+ borderColor: "hsl(0 70% 50%)"
1630
+ },
1631
+ error: {
1632
+ marginTop: 8,
1633
+ padding: "8px 10px",
1634
+ backgroundColor: "hsl(0 70% 50% / 0.15)",
1635
+ border: "1px solid hsl(0 70% 50% / 0.3)",
1636
+ borderRadius: 6,
1637
+ color: "hsl(0 70% 70%)",
1638
+ fontSize: 11,
1639
+ fontFamily: "ui-monospace, monospace"
1640
+ },
1641
+ footer: {
1642
+ display: "flex",
1643
+ alignItems: "center",
1644
+ justifyContent: "flex-end",
1645
+ gap: 8,
1646
+ padding: "12px 16px",
1647
+ borderTop: "1px solid hsl(215 20% 20%)"
1648
+ },
1649
+ button: {
1650
+ display: "flex",
1651
+ alignItems: "center",
1652
+ justifyContent: "center",
1653
+ gap: 6,
1654
+ padding: "8px 16px",
1655
+ backgroundColor: "hsl(215 20% 20%)",
1656
+ border: "1px solid hsl(215 20% 28%)",
1657
+ borderRadius: 6,
1658
+ color: "hsl(215 20% 75%)",
1659
+ fontSize: 12,
1660
+ fontWeight: 500,
1661
+ fontFamily: "inherit",
1662
+ cursor: "pointer",
1663
+ transition: "all 0.15s ease",
1664
+ outline: "none"
1665
+ },
1666
+ buttonPrimary: {
1667
+ backgroundColor: "hsl(217 91% 55%)",
1668
+ borderColor: "hsl(217 91% 60%)",
1669
+ color: "white"
1670
+ },
1671
+ buttonDisabled: {
1672
+ opacity: 0.5,
1673
+ cursor: "not-allowed"
1674
+ }
1675
+ };
1676
+ function FlowEditModal(props) {
1677
+ const { isOpen, flowId, initialState, onClose, onSave, container } = props;
1678
+ const [jsonValue, setJsonValue] = _react.useState.call(void 0, "");
1679
+ const [error, setError] = _react.useState.call(void 0, null);
1680
+ _react.useEffect.call(void 0, () => {
1681
+ if (isOpen && initialState) {
1682
+ setJsonValue(JSON.stringify(initialState, null, 2));
1683
+ setError(null);
1684
+ }
1685
+ }, [isOpen, initialState]);
1686
+ const handleSave = _react.useCallback.call(void 0, () => {
1687
+ try {
1688
+ const parsed = JSON.parse(jsonValue);
1689
+ if (typeof parsed.status !== "string") {
1690
+ throw new Error('Missing or invalid "status" field');
1691
+ }
1692
+ if (typeof parsed.stepIndex !== "number") {
1693
+ throw new Error('Missing or invalid "stepIndex" field');
1694
+ }
1695
+ if (typeof parsed.version !== "string") {
1696
+ throw new Error('Missing or invalid "version" field');
1697
+ }
1698
+ onSave(parsed);
1699
+ onClose();
1700
+ } catch (err) {
1701
+ setError(err instanceof Error ? err.message : "Invalid JSON");
1702
+ }
1703
+ }, [jsonValue, onSave, onClose]);
1704
+ const handleKeyDown = _react.useCallback.call(void 0,
1705
+ (e) => {
1706
+ if (e.key === "Escape") {
1707
+ onClose();
1708
+ }
1709
+ if (e.key === "s" && (e.metaKey || e.ctrlKey)) {
1710
+ e.preventDefault();
1711
+ handleSave();
1712
+ }
1713
+ },
1714
+ [onClose, handleSave]
1715
+ );
1716
+ if (typeof window === "undefined") return null;
1717
+ const portalContainer = _nullishCoalesce(container, () => ( document.body));
1718
+ const textareaStyle = {
1719
+ ...styles7.textarea,
1720
+ ...error && styles7.textareaError
1721
+ };
1722
+ const saveButtonStyle = {
1723
+ ...styles7.button,
1724
+ ...styles7.buttonPrimary,
1725
+ ...error && styles7.buttonDisabled
1726
+ };
1727
+ return _reactdom.createPortal.call(void 0,
1728
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.AnimatePresence, { children: isOpen && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1729
+ _react3.motion.div,
1730
+ {
1731
+ style: styles7.overlay,
1732
+ initial: { opacity: 0 },
1733
+ animate: { opacity: 1 },
1734
+ exit: { opacity: 0 },
1735
+ transition: { duration: 0.15 },
1736
+ onClick: (e) => {
1737
+ if (e.target === e.currentTarget) onClose();
1738
+ },
1739
+ onKeyDown: handleKeyDown,
1740
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1741
+ _react3.motion.div,
1742
+ {
1743
+ style: styles7.modal,
1744
+ initial: { opacity: 0, scale: 0.95, y: 10 },
1745
+ animate: { opacity: 1, scale: 1, y: 0 },
1746
+ exit: { opacity: 0, scale: 0.95, y: 10 },
1747
+ transition: { duration: 0.15, ease: [0.16, 1, 0.3, 1] },
1748
+ onClick: (e) => e.stopPropagation(),
1749
+ children: [
1750
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles7.header, children: [
1751
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { style: styles7.title, children: [
1752
+ "Edit Flow: ",
1753
+ flowId
1754
+ ] }),
1755
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1756
+ "button",
1757
+ {
1758
+ type: "button",
1759
+ style: styles7.closeButton,
1760
+ onClick: onClose,
1761
+ title: "Close",
1762
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" }) })
1763
+ }
1764
+ )
1765
+ ] }),
1766
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles7.body, children: [
1767
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1768
+ "textarea",
1769
+ {
1770
+ style: textareaStyle,
1771
+ value: jsonValue,
1772
+ onChange: (e) => {
1773
+ setJsonValue(e.target.value);
1774
+ setError(null);
1775
+ },
1776
+ spellCheck: false,
1777
+ autoFocus: true
1778
+ }
1779
+ ),
1780
+ error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles7.error, children: error })
1781
+ ] }),
1782
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles7.footer, children: [
1783
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1784
+ "button",
1785
+ {
1786
+ type: "button",
1787
+ style: styles7.button,
1788
+ onClick: onClose,
1789
+ children: "Cancel"
1790
+ }
1791
+ ),
1792
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1793
+ _react3.motion.button,
1794
+ {
1795
+ type: "button",
1796
+ style: saveButtonStyle,
1797
+ onClick: handleSave,
1798
+ disabled: !!error,
1799
+ whileHover: !error ? { scale: 1.02 } : {},
1800
+ whileTap: !error ? { scale: 0.98 } : {},
1801
+ children: "Save"
1802
+ }
1803
+ )
1804
+ ] })
1805
+ ]
1806
+ }
1807
+ )
1808
+ }
1809
+ ) }),
1810
+ portalContainer
1811
+ );
1812
+ }
1813
+
1814
+ // src/devtools/components/FlowsTab.tsx
1815
+
1816
+ var styles8 = {
1817
+ container: {
1818
+ display: "flex",
1819
+ flexDirection: "column",
1820
+ gap: 10,
1821
+ padding: 10,
1822
+ flex: 1,
1823
+ overflowY: "auto"
1824
+ },
1825
+ toolbar: {
1826
+ display: "flex",
1827
+ alignItems: "center",
1828
+ justifyContent: "space-between",
1829
+ gap: 8,
1830
+ marginBottom: 4
1831
+ },
1832
+ refreshButton: {
1833
+ display: "flex",
1834
+ alignItems: "center",
1835
+ justifyContent: "center",
1836
+ gap: 6,
1837
+ padding: "6px 10px",
1838
+ backgroundColor: "transparent",
1839
+ border: "1px solid hsl(215 20% 25%)",
1840
+ borderRadius: 5,
1841
+ color: "hsl(215 20% 60%)",
1842
+ fontSize: 11,
1843
+ fontWeight: 500,
1844
+ fontFamily: "inherit",
1845
+ cursor: "pointer",
1846
+ transition: "all 0.15s ease",
1847
+ outline: "none"
1848
+ },
1849
+ flowList: {
1850
+ display: "flex",
1851
+ flexDirection: "column",
1852
+ gap: 8
1853
+ },
1854
+ empty: {
1855
+ display: "flex",
1856
+ flexDirection: "column",
1857
+ alignItems: "center",
1858
+ justifyContent: "center",
1859
+ gap: 8,
1860
+ padding: "32px 16px",
1861
+ textAlign: "center",
1862
+ color: "hsl(215 20% 55%)"
1863
+ },
1864
+ emptyIcon: {
1865
+ width: 40,
1866
+ height: 40,
1867
+ borderRadius: 10,
1868
+ backgroundColor: "hsl(215 20% 18%)",
1869
+ display: "flex",
1870
+ alignItems: "center",
1871
+ justifyContent: "center",
1872
+ marginBottom: 4
1873
+ },
1874
+ emptyText: {
1875
+ fontSize: 13,
1876
+ lineHeight: 1.5
1877
+ },
1878
+ noContext: {
1879
+ padding: "20px 16px",
1880
+ textAlign: "center",
1881
+ color: "hsl(215 20% 50%)",
1882
+ fontSize: 12
1883
+ }
1884
+ };
1885
+ function FlowsTab(props) {
1886
+ const { container } = props;
1887
+ const { flows, refreshFlows, deleteFlow, updateFlow } = useFlowsData();
1888
+ const [editModal, setEditModal] = _react.useState.call(void 0, {
1889
+ isOpen: false,
1890
+ flowId: "",
1891
+ state: null
1892
+ });
1893
+ const handleEdit = _react.useCallback.call(void 0, (flowId, state) => {
1894
+ if (!state) return;
1895
+ setEditModal({
1896
+ isOpen: true,
1897
+ flowId,
1898
+ state
1899
+ });
1900
+ }, []);
1901
+ const handleCloseModal = _react.useCallback.call(void 0, () => {
1902
+ setEditModal((prev) => ({ ...prev, isOpen: false }));
1903
+ }, []);
1904
+ const handleSave = _react.useCallback.call(void 0,
1905
+ async (newState) => {
1906
+ await updateFlow(editModal.flowId, newState);
1907
+ },
1908
+ [editModal.flowId, updateFlow]
1909
+ );
1910
+ const handleDelete = _react.useCallback.call(void 0,
1911
+ async (flowId) => {
1912
+ await deleteFlow(flowId);
1913
+ },
1914
+ [deleteFlow]
1915
+ );
1916
+ if (flows.length === 0) {
1917
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles8.container, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles8.empty, children: [
1918
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles8.emptyIcon, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1919
+ "svg",
1920
+ {
1921
+ width: "20",
1922
+ height: "20",
1923
+ viewBox: "0 0 16 16",
1924
+ fill: "hsl(215 20% 45%)",
1925
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M6 3.5A1.5 1.5 0 0 1 7.5 2h1A1.5 1.5 0 0 1 10 3.5v1A1.5 1.5 0 0 1 8.5 6v1H14a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0v-1A.5.5 0 0 1 2 7h5.5V6A1.5 1.5 0 0 1 6 4.5v-1zm-3 8A1.5 1.5 0 0 1 4.5 10h1A1.5 1.5 0 0 1 7 11.5v1A1.5 1.5 0 0 1 5.5 14h-1A1.5 1.5 0 0 1 3 12.5v-1zm6 0a1.5 1.5 0 0 1 1.5-1.5h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1A1.5 1.5 0 0 1 9 12.5v-1z" })
1926
+ }
1927
+ ) }),
1928
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles8.emptyText, children: [
1929
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { children: "No flows registered." }),
1930
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { marginTop: 6, fontSize: 11, color: "hsl(215 20% 45%)" }, children: "Add flows to TourProvider to see them here." })
1931
+ ] })
1932
+ ] }) });
1933
+ }
1934
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles8.container, children: [
1935
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles8.toolbar, children: [
1936
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { style: { fontSize: 11, color: "hsl(215 20% 50%)" }, children: [
1937
+ flows.length,
1938
+ " flow",
1939
+ flows.length !== 1 ? "s" : "",
1940
+ " registered"
1941
+ ] }),
1942
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1943
+ _react3.motion.button,
1944
+ {
1945
+ type: "button",
1946
+ style: styles8.refreshButton,
1947
+ onClick: () => void refreshFlows(),
1948
+ whileHover: { scale: 1.02 },
1949
+ whileTap: { scale: 0.98 },
1950
+ title: "Refresh flow states",
1951
+ children: [
1952
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "currentColor", children: [
1953
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1954
+ "path",
1955
+ {
1956
+ fillRule: "evenodd",
1957
+ d: "M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z"
1958
+ }
1959
+ ),
1960
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z" })
1961
+ ] }),
1962
+ "Refresh"
1963
+ ]
1964
+ }
1965
+ )
1966
+ ] }),
1967
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles8.flowList, children: flows.map((flow) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1968
+ FlowItem,
1969
+ {
1970
+ flow,
1971
+ onEdit: () => handleEdit(flow.flowId, flow.state),
1972
+ onDelete: () => void handleDelete(flow.flowId)
1973
+ },
1974
+ flow.flowId
1975
+ )) }),
1976
+ editModal.state && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1977
+ FlowEditModal,
1978
+ {
1979
+ isOpen: editModal.isOpen,
1980
+ flowId: editModal.flowId,
1981
+ initialState: editModal.state,
1982
+ onClose: handleCloseModal,
1983
+ onSave: handleSave,
1984
+ container
1985
+ }
1986
+ )
1987
+ ] });
1988
+ }
1989
+
1990
+ // src/devtools/hooks/useGrabMode.ts
1991
+
1992
+
1993
+ // src/devtools/hooks/useElementInfo.ts
1994
+
1995
+
1996
+ // src/devtools/utils/selectorGenerator.ts
1997
+ function generateSemanticName(element) {
1998
+ const tag = element.tagName.toLowerCase();
1999
+ const text = _optionalChain([element, 'access', _3 => _3.textContent, 'optionalAccess', _4 => _4.trim, 'call', _5 => _5(), 'access', _6 => _6.slice, 'call', _7 => _7(0, 20), 'access', _8 => _8.toLowerCase, 'call', _9 => _9()]) || "";
2000
+ const className = element.className;
2001
+ const id = element.id;
2002
+ if (text) {
2003
+ const words = text.replace(/[^a-z0-9\s]/gi, "").split(/\s+/).filter(Boolean).slice(0, 3);
2004
+ if (words.length > 0) {
2005
+ return `${tag}-${words.join("-")}`;
2006
+ }
2007
+ }
2008
+ if (id) {
2009
+ return id;
2010
+ }
2011
+ if (typeof className === "string" && className) {
2012
+ const firstClass = className.split(/\s+/)[0];
2013
+ if (firstClass && !firstClass.startsWith("_") && firstClass.length < 30) {
2014
+ return `${tag}-${firstClass}`;
2015
+ }
2016
+ }
2017
+ return `${tag}-${Math.random().toString(36).slice(2, 6)}`;
2018
+ }
2019
+ function getExistingDataAttrs(element) {
2020
+ const attrs = [];
2021
+ for (const attr of element.attributes) {
2022
+ if (attr.name.startsWith("data-")) {
2023
+ attrs.push(attr.name);
2024
+ }
2025
+ }
2026
+ return attrs;
2027
+ }
2028
+ function isUnique(params) {
2029
+ try {
2030
+ return document.querySelectorAll(params.selector).length === 1;
2031
+ } catch (e4) {
2032
+ return false;
2033
+ }
2034
+ }
2035
+ function generateSelector(params) {
2036
+ const { element } = params;
2037
+ const existingAttrs = getExistingDataAttrs(element);
2038
+ const tourTarget = element.getAttribute("data-tour-target");
2039
+ if (tourTarget) {
2040
+ return {
2041
+ selector: `[data-tour-target="${tourTarget}"]`,
2042
+ selectorType: "data-attr",
2043
+ suggestedAttrName: tourTarget,
2044
+ existingAttrs
2045
+ };
2046
+ }
2047
+ if (element.id && isUnique({ selector: `#${CSS.escape(element.id)}` })) {
2048
+ return {
2049
+ selector: `#${CSS.escape(element.id)}`,
2050
+ selectorType: "auto",
2051
+ suggestedAttrName: element.id,
2052
+ existingAttrs
2053
+ };
2054
+ }
2055
+ const testId = element.getAttribute("data-testid");
2056
+ if (testId && isUnique({ selector: `[data-testid="${testId}"]` })) {
2057
+ return {
2058
+ selector: `[data-testid="${testId}"]`,
2059
+ selectorType: "data-attr",
2060
+ suggestedAttrName: testId,
2061
+ existingAttrs
2062
+ };
2063
+ }
2064
+ for (const attr of existingAttrs) {
2065
+ if (attr === "data-tour-target" || attr === "data-testid") continue;
2066
+ const value = element.getAttribute(attr);
2067
+ if (value) {
2068
+ const selector = `[${attr}="${value}"]`;
2069
+ if (isUnique({ selector })) {
2070
+ return {
2071
+ selector,
2072
+ selectorType: "data-attr",
2073
+ suggestedAttrName: value,
2074
+ existingAttrs
2075
+ };
2076
+ }
2077
+ }
2078
+ }
2079
+ const suggestedName = generateSemanticName(element);
2080
+ return {
2081
+ selector: `[data-tour-target="${suggestedName}"]`,
2082
+ selectorType: "auto",
2083
+ suggestedAttrName: suggestedName,
2084
+ existingAttrs
2085
+ };
2086
+ }
2087
+
2088
+ // src/devtools/hooks/useElementInfo.ts
2089
+ function useElementInfo() {
2090
+ const getElementInfo = _react.useCallback.call(void 0, (params) => {
2091
+ const { element } = params;
2092
+ const selectorResult = generateSelector({ element });
2093
+ const source = extractSource({ element });
2094
+ const componentHierarchy = extractComponentHierarchy({ element });
2095
+ const rect = element.getBoundingClientRect();
2096
+ const htmlElement = element;
2097
+ const styleAttr = _optionalChain([htmlElement, 'access', _10 => _10.getAttribute, 'optionalCall', _11 => _11("style")]) || void 0;
2098
+ return {
2099
+ element,
2100
+ selector: selectorResult.selector,
2101
+ selectorType: selectorResult.selectorType,
2102
+ suggestedAttrName: selectorResult.suggestedAttrName,
2103
+ tag: element.tagName.toLowerCase(),
2104
+ text: _optionalChain([element, 'access', _12 => _12.textContent, 'optionalAccess', _13 => _13.trim, 'call', _14 => _14(), 'access', _15 => _15.slice, 'call', _16 => _16(0, 50)]) || void 0,
2105
+ className: typeof element.className === "string" ? element.className : void 0,
2106
+ style: styleAttr,
2107
+ existingAttrs: selectorResult.existingAttrs,
2108
+ componentHierarchy,
2109
+ rect,
2110
+ source: _nullishCoalesce(source, () => ( void 0))
2111
+ };
2112
+ }, []);
2113
+ return { getElementInfo };
2114
+ }
2115
+
2116
+ // src/devtools/hooks/useGrabMode.ts
2117
+ function isDevToolsElement(element) {
2118
+ if (element.closest("[data-devtools-panel]")) return true;
2119
+ if (element.closest("[data-devtools-host]")) return true;
2120
+ const root = element.getRootNode();
2121
+ if (root instanceof ShadowRoot) {
2122
+ const host = root.host;
2123
+ if (_optionalChain([host, 'optionalAccess', _17 => _17.hasAttribute, 'call', _18 => _18("data-devtools-host")])) return true;
2124
+ }
2125
+ return false;
2126
+ }
2127
+ function useGrabMode() {
2128
+ const [mode, setMode] = _react.useState.call(void 0, "idle");
2129
+ const [hoveredElement, setHoveredElement] = _react.useState.call(void 0, null);
2130
+ const { getElementInfo } = useElementInfo();
2131
+ const startGrabbing = _react.useCallback.call(void 0, () => {
2132
+ setMode("grabbing");
2133
+ setHoveredElement(null);
2134
+ }, []);
2135
+ const stopGrabbing = _react.useCallback.call(void 0, () => {
2136
+ setMode("idle");
2137
+ setHoveredElement(null);
2138
+ }, []);
2139
+ const toggleGrabbing = _react.useCallback.call(void 0, () => {
2140
+ setMode((prev) => prev === "grabbing" ? "idle" : "grabbing");
2141
+ setHoveredElement(null);
2142
+ }, []);
2143
+ const selectCurrent = _react.useCallback.call(void 0, () => {
2144
+ if (!hoveredElement) return null;
2145
+ return hoveredElement.info;
2146
+ }, [hoveredElement]);
2147
+ _react.useEffect.call(void 0, () => {
2148
+ if (mode !== "grabbing") return;
2149
+ const handleMouseMove = (e) => {
2150
+ const target = document.elementFromPoint(e.clientX, e.clientY);
2151
+ if (!target) {
2152
+ setHoveredElement(null);
2153
+ return;
2154
+ }
2155
+ if (isDevToolsElement(target)) {
2156
+ setHoveredElement(null);
2157
+ return;
2158
+ }
2159
+ if (target.tagName === "HTML" || target.tagName === "BODY") {
2160
+ setHoveredElement(null);
2161
+ return;
2162
+ }
2163
+ setHoveredElement({
2164
+ element: target,
2165
+ info: getElementInfo({ element: target })
2166
+ });
2167
+ };
2168
+ document.addEventListener("mousemove", handleMouseMove, { passive: true });
2169
+ return () => document.removeEventListener("mousemove", handleMouseMove);
2170
+ }, [mode, getElementInfo]);
2171
+ _react.useEffect.call(void 0, () => {
2172
+ const handleKeyDown = (e) => {
2173
+ if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === "g") {
2174
+ e.preventDefault();
2175
+ toggleGrabbing();
2176
+ return;
2177
+ }
2178
+ if (mode !== "grabbing") return;
2179
+ if (e.key === "Escape") {
2180
+ e.preventDefault();
2181
+ stopGrabbing();
2182
+ }
2183
+ };
2184
+ document.addEventListener("keydown", handleKeyDown);
2185
+ return () => document.removeEventListener("keydown", handleKeyDown);
2186
+ }, [mode, toggleGrabbing, stopGrabbing]);
2187
+ return {
2188
+ mode,
2189
+ hoveredElement,
2190
+ startGrabbing,
2191
+ stopGrabbing,
2192
+ toggleGrabbing,
2193
+ selectCurrent
2194
+ };
2195
+ }
2196
+
2197
+ // src/devtools/hooks/useStepStore.ts
2198
+
2199
+
2200
+ // src/devtools/utils/storage.ts
2201
+ var STORAGE_KEY = "flowsterix-devtools-steps";
2202
+ function migrateStep(step) {
2203
+ return {
2204
+ ...step,
2205
+ componentHierarchy: _nullishCoalesce(step.componentHierarchy, () => ( [])),
2206
+ existingAttrs: _nullishCoalesce(step.existingAttrs, () => ( []))
2207
+ };
2208
+ }
2209
+ function loadSteps() {
2210
+ if (typeof window === "undefined") return [];
2211
+ try {
2212
+ const data = localStorage.getItem(STORAGE_KEY);
2213
+ if (!data) return [];
2214
+ const parsed = JSON.parse(data);
2215
+ if (!Array.isArray(parsed)) return [];
2216
+ return parsed.map(migrateStep);
2217
+ } catch (e5) {
2218
+ return [];
2219
+ }
2220
+ }
2221
+ function saveSteps(steps) {
2222
+ if (typeof window === "undefined") return;
2223
+ try {
2224
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(steps));
2225
+ } catch (e6) {
2226
+ }
2227
+ }
2228
+ function clearSteps() {
2229
+ if (typeof window === "undefined") return;
2230
+ try {
2231
+ localStorage.removeItem(STORAGE_KEY);
2232
+ } catch (e7) {
2233
+ }
2234
+ }
2235
+
2236
+ // src/devtools/hooks/useStepStore.ts
2237
+ var store = {
2238
+ steps: [],
2239
+ listeners: /* @__PURE__ */ new Set()
2240
+ };
2241
+ function notifyListeners() {
2242
+ for (const listener of store.listeners) {
2243
+ listener();
2244
+ }
2245
+ }
2246
+ function subscribe(listener) {
2247
+ store.listeners.add(listener);
2248
+ return () => store.listeners.delete(listener);
2249
+ }
2250
+ function getSnapshot() {
2251
+ return store.steps;
2252
+ }
2253
+ function getServerSnapshot() {
2254
+ return [];
2255
+ }
2256
+ function generateId() {
2257
+ return `step-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
2258
+ }
2259
+ function useStepStore() {
2260
+ const steps = _react.useSyncExternalStore.call(void 0, subscribe, getSnapshot, getServerSnapshot);
2261
+ _react.useEffect.call(void 0, () => {
2262
+ const saved = loadSteps();
2263
+ if (saved.length > 0) {
2264
+ store.steps = saved;
2265
+ notifyListeners();
2266
+ }
2267
+ }, []);
2268
+ _react.useEffect.call(void 0, () => {
2269
+ saveSteps(steps);
2270
+ }, [steps]);
2271
+ const addStep = _react.useCallback.call(void 0, (params) => {
2272
+ const { info } = params;
2273
+ const newStep = {
2274
+ id: generateId(),
2275
+ order: store.steps.length,
2276
+ selector: info.selector,
2277
+ selectorType: info.selectorType,
2278
+ elementTag: info.tag,
2279
+ elementText: info.text,
2280
+ elementClassName: info.className,
2281
+ elementStyle: info.style,
2282
+ existingAttrs: info.existingAttrs,
2283
+ suggestedAttrName: info.suggestedAttrName,
2284
+ componentHierarchy: info.componentHierarchy,
2285
+ rect: {
2286
+ top: info.rect.top,
2287
+ left: info.rect.left,
2288
+ width: info.rect.width,
2289
+ height: info.rect.height
2290
+ },
2291
+ source: info.source,
2292
+ createdAt: Date.now()
2293
+ };
2294
+ store.steps = [...store.steps, newStep];
2295
+ notifyListeners();
2296
+ return newStep;
2297
+ }, []);
2298
+ const removeStep = _react.useCallback.call(void 0, (params) => {
2299
+ const { id } = params;
2300
+ store.steps = store.steps.filter((s) => s.id !== id).map((s, i) => ({ ...s, order: i }));
2301
+ notifyListeners();
2302
+ }, []);
2303
+ const updateStep = _react.useCallback.call(void 0,
2304
+ (params) => {
2305
+ const { id, updates } = params;
2306
+ store.steps = store.steps.map(
2307
+ (s) => s.id === id ? { ...s, ...updates } : s
2308
+ );
2309
+ notifyListeners();
2310
+ },
2311
+ []
2312
+ );
2313
+ const reorderSteps = _react.useCallback.call(void 0,
2314
+ (params) => {
2315
+ const { fromIndex, toIndex } = params;
2316
+ const newSteps = [...store.steps];
2317
+ const [removed] = newSteps.splice(fromIndex, 1);
2318
+ newSteps.splice(toIndex, 0, removed);
2319
+ store.steps = newSteps.map((s, i) => ({ ...s, order: i }));
2320
+ notifyListeners();
2321
+ },
2322
+ []
2323
+ );
2324
+ const clearAllSteps = _react.useCallback.call(void 0, () => {
2325
+ store.steps = [];
2326
+ clearSteps();
2327
+ notifyListeners();
2328
+ }, []);
2329
+ const exportSteps = _react.useCallback.call(void 0, () => {
2330
+ return {
2331
+ version: "1.0",
2332
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2333
+ steps: store.steps.map((step) => {
2334
+ let elementStr = `<${step.elementTag}`;
2335
+ if (step.elementClassName) {
2336
+ elementStr += ` class="${step.elementClassName.slice(0, 60)}${step.elementClassName.length > 60 ? "..." : ""}"`;
2337
+ }
2338
+ if (step.elementStyle) {
2339
+ elementStr += ` style="${step.elementStyle.slice(0, 40)}${step.elementStyle.length > 40 ? "..." : ""}"`;
2340
+ }
2341
+ for (const attr of step.existingAttrs) {
2342
+ if (attr !== "class" && attr !== "style") {
2343
+ elementStr += ` ${attr}`;
2344
+ }
2345
+ }
2346
+ elementStr += ">";
2347
+ if (step.elementText) {
2348
+ elementStr += `${step.elementText.slice(0, 30)}${step.elementText.length > 30 ? "..." : ""}`;
2349
+ }
2350
+ elementStr += `</${step.elementTag}>`;
2351
+ const sourceStr = step.source ? `${step.source.fileName.replace(/^.*\/src\//, "src/")}:${step.source.lineNumber}` : void 0;
2352
+ return {
2353
+ order: step.order,
2354
+ element: elementStr,
2355
+ componentTree: step.componentHierarchy,
2356
+ source: sourceStr
2357
+ };
2358
+ })
2359
+ };
2360
+ }, []);
2361
+ return {
2362
+ steps,
2363
+ addStep,
2364
+ removeStep,
2365
+ updateStep,
2366
+ reorderSteps,
2367
+ clearAllSteps,
2368
+ exportSteps
2369
+ };
2370
+ }
2371
+
2372
+ // src/devtools/DevToolsProvider.tsx
2373
+
2374
+ var styles9 = {
2375
+ panel: {
2376
+ position: "fixed",
2377
+ width: 320,
2378
+ maxWidth: "calc(100vw - 32px)",
2379
+ maxHeight: "calc(100vh - 32px)",
2380
+ display: "flex",
2381
+ flexDirection: "column",
2382
+ zIndex: 99998,
2383
+ fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
2384
+ fontSize: 13,
2385
+ backgroundColor: "hsl(222 47% 11%)",
2386
+ borderRadius: 12,
2387
+ border: "1px solid hsl(215 20% 25%)",
2388
+ boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.05)",
2389
+ overflow: "hidden"
2390
+ },
2391
+ header: {
2392
+ display: "flex",
2393
+ alignItems: "center",
2394
+ justifyContent: "space-between",
2395
+ padding: "10px 12px",
2396
+ borderBottom: "1px solid hsl(215 20% 20%)",
2397
+ backgroundColor: "hsl(222 47% 9%)",
2398
+ cursor: "grab",
2399
+ userSelect: "none",
2400
+ touchAction: "none"
2401
+ },
2402
+ headerDragging: {
2403
+ cursor: "grabbing"
2404
+ },
2405
+ titleGroup: {
2406
+ display: "flex",
2407
+ alignItems: "center",
2408
+ gap: 8
2409
+ },
2410
+ logo: {
2411
+ display: "flex",
2412
+ alignItems: "center",
2413
+ justifyContent: "center",
2414
+ width: 24,
2415
+ height: 24,
2416
+ borderRadius: 6,
2417
+ backgroundColor: "hsl(217 91% 55% / 0.2)"
2418
+ },
2419
+ title: {
2420
+ fontSize: 13,
2421
+ fontWeight: 600,
2422
+ color: "hsl(215 20% 75%)",
2423
+ letterSpacing: "-0.01em"
2424
+ },
2425
+ headerButtons: {
2426
+ display: "flex",
2427
+ alignItems: "center",
2428
+ gap: 2
2429
+ },
2430
+ iconButton: {
2431
+ display: "flex",
2432
+ alignItems: "center",
2433
+ justifyContent: "center",
2434
+ width: 26,
2435
+ height: 26,
2436
+ backgroundColor: "transparent",
2437
+ border: "none",
2438
+ color: "hsl(215 20% 55%)",
2439
+ cursor: "pointer",
2440
+ padding: 0,
2441
+ borderRadius: 6,
2442
+ transition: "all 0.15s ease",
2443
+ outline: "none"
2444
+ },
2445
+ body: {
2446
+ flex: 1,
2447
+ minHeight: 0,
2448
+ display: "flex",
2449
+ flexDirection: "column",
2450
+ overflow: "hidden"
2451
+ }
2452
+ };
2453
+ function DevToolsProvider(props) {
2454
+ const { children, enabled = true, defaultTab = "steps" } = props;
2455
+ const [mounted, setMounted] = _react.useState.call(void 0, false);
2456
+ const [shadowRoot, setShadowRoot] = _react.useState.call(void 0, null);
2457
+ const [activeTab, setActiveTab] = _react.useState.call(void 0, defaultTab);
2458
+ _react.useEffect.call(void 0, () => {
2459
+ setMounted(true);
2460
+ const host = document.createElement("div");
2461
+ host.setAttribute("data-devtools-host", "");
2462
+ host.style.cssText = "position: fixed; top: 0; left: 0; z-index: 99999; pointer-events: none;";
2463
+ document.body.appendChild(host);
2464
+ const shadow = host.attachShadow({ mode: "open" });
2465
+ const style = document.createElement("style");
2466
+ style.textContent = `
2467
+ :host { all: initial; }
2468
+ *, *::before, *::after { box-sizing: border-box; }
2469
+ `;
2470
+ shadow.appendChild(style);
2471
+ const container = document.createElement("div");
2472
+ container.style.cssText = "pointer-events: auto;";
2473
+ shadow.appendChild(container);
2474
+ setShadowRoot(shadow);
2475
+ return () => {
2476
+ document.body.removeChild(host);
2477
+ };
2478
+ }, []);
2479
+ const { mode, hoveredElement, toggleGrabbing, selectCurrent } = useGrabMode();
2480
+ const {
2481
+ steps,
2482
+ addStep,
2483
+ removeStep,
2484
+ reorderSteps,
2485
+ clearAllSteps,
2486
+ exportSteps
2487
+ } = useStepStore();
2488
+ const { flows } = useFlowsData();
2489
+ const [collapsed, setCollapsed] = _react.useState.call(void 0, false);
2490
+ const [position, setPosition] = _react.useState.call(void 0, { x: 16, y: 16 });
2491
+ const [isPanelDragging, setIsPanelDragging] = _react.useState.call(void 0, false);
2492
+ const dragStartRef = _react.useRef.call(void 0, null);
2493
+ const handleClick = _react.useCallback.call(void 0,
2494
+ (e) => {
2495
+ if (mode !== "grabbing") return;
2496
+ const target = e.target;
2497
+ if (target.closest("[data-devtools-panel]")) return;
2498
+ if (target.closest("[data-devtools-host]")) return;
2499
+ const root = target.getRootNode();
2500
+ if (root instanceof ShadowRoot) {
2501
+ const host = root.host;
2502
+ if (_optionalChain([host, 'optionalAccess', _19 => _19.hasAttribute, 'call', _20 => _20("data-devtools-host")])) return;
2503
+ }
2504
+ e.preventDefault();
2505
+ e.stopPropagation();
2506
+ const info = selectCurrent();
2507
+ if (info) {
2508
+ addStep({ info });
2509
+ }
2510
+ },
2511
+ [mode, selectCurrent, addStep]
2512
+ );
2513
+ _react.useEffect.call(void 0, () => {
2514
+ if (mode !== "grabbing") return;
2515
+ document.addEventListener("click", handleClick, { capture: true });
2516
+ return () => document.removeEventListener("click", handleClick, { capture: true });
2517
+ }, [mode, handleClick]);
2518
+ _react.useEffect.call(void 0, () => {
2519
+ if (mode !== "grabbing") return;
2520
+ const preventDefault = (e) => {
2521
+ const target = e.target;
2522
+ if (target.closest("[data-devtools-panel]")) return;
2523
+ e.preventDefault();
2524
+ };
2525
+ document.addEventListener("submit", preventDefault, { capture: true });
2526
+ return () => {
2527
+ document.removeEventListener("submit", preventDefault, { capture: true });
2528
+ };
2529
+ }, [mode]);
2530
+ _react.useEffect.call(void 0, () => {
2531
+ const handleKeyDown = (e) => {
2532
+ if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === "m") {
2533
+ e.preventDefault();
2534
+ setCollapsed((c) => !c);
2535
+ }
2536
+ };
2537
+ document.addEventListener("keydown", handleKeyDown);
2538
+ return () => document.removeEventListener("keydown", handleKeyDown);
2539
+ }, []);
2540
+ const handlePointerDown = _react.useCallback.call(void 0,
2541
+ (e) => {
2542
+ const target = e.target;
2543
+ if (target.closest("button")) return;
2544
+ e.preventDefault();
2545
+ setIsPanelDragging(true);
2546
+ dragStartRef.current = {
2547
+ x: e.clientX,
2548
+ y: e.clientY,
2549
+ posX: position.x,
2550
+ posY: position.y
2551
+ };
2552
+ e.target.setPointerCapture(e.pointerId);
2553
+ },
2554
+ [position]
2555
+ );
2556
+ const handlePointerMove = _react.useCallback.call(void 0,
2557
+ (e) => {
2558
+ if (!dragStartRef.current || !isPanelDragging) return;
2559
+ const dx = e.clientX - dragStartRef.current.x;
2560
+ const dy = e.clientY - dragStartRef.current.y;
2561
+ const newX = Math.max(8, dragStartRef.current.posX - dx);
2562
+ const newY = Math.max(8, dragStartRef.current.posY + dy);
2563
+ setPosition({ x: newX, y: newY });
2564
+ },
2565
+ [isPanelDragging]
2566
+ );
2567
+ const handlePointerUp = _react.useCallback.call(void 0, (e) => {
2568
+ setIsPanelDragging(false);
2569
+ dragStartRef.current = null;
2570
+ e.target.releasePointerCapture(e.pointerId);
2571
+ }, []);
2572
+ if (!enabled || !mounted) {
2573
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children });
2574
+ }
2575
+ const shadowContainer = _nullishCoalesce(_optionalChain([shadowRoot, 'optionalAccess', _21 => _21.lastElementChild]), () => ( null));
2576
+ const panelStyle = {
2577
+ ...styles9.panel,
2578
+ right: position.x,
2579
+ top: position.y
2580
+ };
2581
+ const headerStyle = {
2582
+ ...styles9.header,
2583
+ ...isPanelDragging && styles9.headerDragging
2584
+ };
2585
+ const portalContainer = _nullishCoalesce(shadowContainer, () => ( document.body));
2586
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2587
+ children,
2588
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2589
+ GrabberOverlay,
2590
+ {
2591
+ isGrabbing: mode === "grabbing",
2592
+ hoveredInfo: _nullishCoalesce(_optionalChain([hoveredElement, 'optionalAccess', _22 => _22.info]), () => ( null)),
2593
+ container: shadowContainer
2594
+ }
2595
+ ),
2596
+ _reactdom.createPortal.call(void 0,
2597
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2598
+ _react3.motion.div,
2599
+ {
2600
+ style: panelStyle,
2601
+ initial: { opacity: 0, x: 20, scale: 0.95 },
2602
+ animate: { opacity: 1, x: 0, scale: 1 },
2603
+ transition: { duration: 0.2, ease: [0.16, 1, 0.3, 1] },
2604
+ "data-devtools-panel": "",
2605
+ children: [
2606
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2607
+ "div",
2608
+ {
2609
+ style: headerStyle,
2610
+ onPointerDown: handlePointerDown,
2611
+ onPointerMove: handlePointerMove,
2612
+ onPointerUp: handlePointerUp,
2613
+ onPointerCancel: handlePointerUp,
2614
+ children: [
2615
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: styles9.titleGroup, children: [
2616
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles9.logo, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "hsl(217 91% 70%)", children: [
2617
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M8 0L14.9 4v8L8 16 1.1 12V4L8 0zm0 2.3L3.1 5.2v5.6L8 13.7l4.9-2.9V5.2L8 2.3z" }),
2618
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M8 5l3 1.7v3.4L8 11.8 5 10.1V6.7L8 5z" })
2619
+ ] }) }),
2620
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: styles9.title, children: "DevTools" })
2621
+ ] }),
2622
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles9.headerButtons, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2623
+ "button",
2624
+ {
2625
+ type: "button",
2626
+ style: styles9.iconButton,
2627
+ onClick: () => setCollapsed(!collapsed),
2628
+ title: collapsed ? "Expand (Ctrl+Shift+M)" : "Collapse (Ctrl+Shift+M)",
2629
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2630
+ "svg",
2631
+ {
2632
+ width: "14",
2633
+ height: "14",
2634
+ viewBox: "0 0 16 16",
2635
+ fill: "currentColor",
2636
+ style: {
2637
+ transform: collapsed ? "rotate(180deg)" : "none",
2638
+ transition: "transform 0.2s ease"
2639
+ },
2640
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708l6-6z" })
2641
+ }
2642
+ )
2643
+ }
2644
+ ) })
2645
+ ]
2646
+ }
2647
+ ),
2648
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.AnimatePresence, { initial: false, children: !collapsed && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2649
+ _react3.motion.div,
2650
+ {
2651
+ style: styles9.body,
2652
+ initial: { height: 0, opacity: 0 },
2653
+ animate: { height: "auto", opacity: 1 },
2654
+ exit: { height: 0, opacity: 0 },
2655
+ transition: { duration: 0.2, ease: [0.16, 1, 0.3, 1] },
2656
+ children: [
2657
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2658
+ TabNav,
2659
+ {
2660
+ activeTab,
2661
+ onTabChange: setActiveTab,
2662
+ stepCount: steps.length,
2663
+ flowCount: flows.length
2664
+ }
2665
+ ),
2666
+ activeTab === "steps" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2667
+ StepList,
2668
+ {
2669
+ steps,
2670
+ mode,
2671
+ onToggleGrab: toggleGrabbing,
2672
+ onDeleteStep: removeStep,
2673
+ onReorderSteps: reorderSteps,
2674
+ onClearAll: clearAllSteps,
2675
+ onExport: exportSteps
2676
+ }
2677
+ ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FlowsTab, { container: shadowContainer })
2678
+ ]
2679
+ }
2680
+ ) })
2681
+ ]
2682
+ }
2683
+ ),
2684
+ portalContainer
2685
+ )
2686
+ ] });
2687
+ }
2688
+
2689
+
2690
+
2691
+
2692
+
2693
+
2694
+
2695
+
2696
+
2697
+
2698
+
2699
+
2700
+
2701
+
2702
+
2703
+
2704
+
2705
+
2706
+
2707
+
2708
+
2709
+
2710
+
2711
+
2712
+
2713
+
2714
+
2715
+ exports.DevToolsContext = _chunkFCOKCGV3cjs.DevToolsContext; exports.DevToolsProvider = DevToolsProvider; exports.FlowEditModal = FlowEditModal; exports.FlowItem = FlowItem; exports.FlowsTab = FlowsTab; exports.GrabberOverlay = GrabberOverlay; exports.SortableStepItem = SortableStepItem; exports.StepItem = SortableStepItem; exports.StepItemDragPreview = StepItemDragPreview; exports.StepList = StepList; exports.TabNav = TabNav; exports.Toolbar = Toolbar; exports.clearSteps = clearSteps; exports.extractComponentHierarchy = extractComponentHierarchy; exports.extractSource = extractSource; exports.formatSourcePath = formatSourcePath; exports.generateSelector = generateSelector; exports.getVSCodeLink = getVSCodeLink; exports.loadSteps = loadSteps; exports.saveSteps = saveSteps; exports.useDevToolsContext = _chunkFCOKCGV3cjs.useDevToolsContext; exports.useDevToolsContextRequired = _chunkFCOKCGV3cjs.useDevToolsContextRequired; exports.useElementInfo = useElementInfo; exports.useFlowsData = useFlowsData; exports.useGrabMode = useGrabMode; exports.useStepStore = useStepStore;