@octaviaflow/core 3.1.0-beta.83 → 3.1.0-beta.84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -11361,7 +11361,7 @@ EmptyState.displayName = "EmptyState";
11361
11361
 
11362
11362
  // src/components/ExecutionConsole/ExecutionConsole.tsx
11363
11363
  import { motion as motion13 } from "framer-motion";
11364
- import { useEffect as useEffect21, useMemo as useMemo13, useRef as useRef21, useState as useState26 } from "react";
11364
+ import { memo, useCallback as useCallback17, useEffect as useEffect21, useMemo as useMemo13, useRef as useRef21, useState as useState26 } from "react";
11365
11365
  import { Fragment as Fragment22, jsx as jsx52, jsxs as jsxs52 } from "react/jsx-runtime";
11366
11366
  var iconProps = {
11367
11367
  xmlns: "http://www.w3.org/2000/svg",
@@ -11471,11 +11471,17 @@ function ExecutionConsole({
11471
11471
  }, [running]);
11472
11472
  useEffect21(() => {
11473
11473
  if (!open || !autoScroll) return;
11474
+ const logsEl = logsRef.current;
11475
+ if (running && logsEl) {
11476
+ logsEl.scrollTop = logsEl.scrollHeight;
11477
+ lastScrollTopRef.current = logsEl.scrollTop;
11478
+ return;
11479
+ }
11474
11480
  const el = logEndRef.current;
11475
11481
  if (el && typeof el.scrollIntoView === "function") {
11476
11482
  el.scrollIntoView({ behavior: "smooth", block: "end" });
11477
11483
  }
11478
- }, [filteredLogs.length, open, autoScroll]);
11484
+ }, [filteredLogs.length, open, autoScroll, running]);
11479
11485
  const handleLogsScroll = () => {
11480
11486
  const el = logsRef.current;
11481
11487
  if (!el) return;
@@ -11495,14 +11501,14 @@ function ExecutionConsole({
11495
11501
  return next;
11496
11502
  });
11497
11503
  };
11498
- const toggleLineExpand = (index) => {
11504
+ const toggleLineExpand = useCallback17((index) => {
11499
11505
  setExpandedLines((prev) => {
11500
11506
  const next = new Set(prev);
11501
11507
  if (next.has(index)) next.delete(index);
11502
11508
  else next.add(index);
11503
11509
  return next;
11504
11510
  });
11505
- };
11511
+ }, []);
11506
11512
  const handleCopy = () => {
11507
11513
  if (onCopy) {
11508
11514
  onCopy();
@@ -11778,38 +11784,17 @@ function ExecutionConsole({
11778
11784
  /* @__PURE__ */ jsx52("span", { className: "ods-console__empty-title", children: logs.length === 0 ? "No log entries" : "No logs match the filters" }),
11779
11785
  logs.length === 0 && /* @__PURE__ */ jsx52("span", { className: "ods-console__empty-hint", children: "Output will appear here when the step runs." })
11780
11786
  ] }) }),
11781
- !loading && filteredLogs.map((log, i) => {
11782
- const expanded = expandedLines.has(i);
11783
- const canExpand = log.detail !== void 0 && log.detail !== null;
11784
- return /* @__PURE__ */ jsxs52(
11785
- "div",
11786
- {
11787
- className: cn("ods-console__line", `ods-console__line--${log.level}`),
11788
- "data-testid": "console-log-line",
11789
- children: [
11790
- /* @__PURE__ */ jsxs52("div", { className: "ods-console__line-row", children: [
11791
- canExpand ? /* @__PURE__ */ jsx52(
11792
- "button",
11793
- {
11794
- type: "button",
11795
- className: "ods-console__line-toggle",
11796
- onClick: () => toggleLineExpand(i),
11797
- "aria-label": expanded ? "Collapse log detail" : "Expand log detail",
11798
- "aria-expanded": expanded,
11799
- children: /* @__PURE__ */ jsx52(ChevronIcon2, { open: expanded })
11800
- }
11801
- ) : /* @__PURE__ */ jsx52("span", { className: "ods-console__line-toggle ods-console__line-toggle--placeholder" }),
11802
- /* @__PURE__ */ jsx52("span", { className: "ods-console__timestamp", children: log.timestamp }),
11803
- /* @__PURE__ */ jsx52("span", { className: cn("ods-console__level", `ods-console__level--${log.level}`), children: log.level.toUpperCase() }),
11804
- log.nodeLabel && /* @__PURE__ */ jsx52("span", { className: "ods-console__node-tag", title: log.nodeId, children: log.nodeLabel }),
11805
- /* @__PURE__ */ jsx52("span", { className: "ods-console__message", children: q(query, log.message) })
11806
- ] }),
11807
- canExpand && expanded && /* @__PURE__ */ jsx52("pre", { className: "ods-console__detail", children: typeof log.detail === "string" ? log.detail : safeStringify(log.detail) })
11808
- ]
11809
- },
11810
- i
11811
- );
11812
- }),
11787
+ !loading && filteredLogs.map((log, i) => /* @__PURE__ */ jsx52(
11788
+ ConsoleLine,
11789
+ {
11790
+ log,
11791
+ index: i,
11792
+ expanded: expandedLines.has(i),
11793
+ query,
11794
+ onToggleExpand: toggleLineExpand
11795
+ },
11796
+ i
11797
+ )),
11813
11798
  /* @__PURE__ */ jsx52("div", { ref: logEndRef })
11814
11799
  ]
11815
11800
  }
@@ -11818,6 +11803,42 @@ function ExecutionConsole({
11818
11803
  }
11819
11804
  );
11820
11805
  }
11806
+ var ConsoleLine = memo(function ConsoleLine2({
11807
+ log,
11808
+ index,
11809
+ expanded,
11810
+ query,
11811
+ onToggleExpand
11812
+ }) {
11813
+ const canExpand = log.detail !== void 0 && log.detail !== null;
11814
+ return /* @__PURE__ */ jsxs52(
11815
+ "div",
11816
+ {
11817
+ className: cn("ods-console__line", `ods-console__line--${log.level}`),
11818
+ "data-testid": "console-log-line",
11819
+ children: [
11820
+ /* @__PURE__ */ jsxs52("div", { className: "ods-console__line-row", children: [
11821
+ canExpand ? /* @__PURE__ */ jsx52(
11822
+ "button",
11823
+ {
11824
+ type: "button",
11825
+ className: "ods-console__line-toggle",
11826
+ onClick: () => onToggleExpand(index),
11827
+ "aria-label": expanded ? "Collapse log detail" : "Expand log detail",
11828
+ "aria-expanded": expanded,
11829
+ children: /* @__PURE__ */ jsx52(ChevronIcon2, { open: expanded })
11830
+ }
11831
+ ) : /* @__PURE__ */ jsx52("span", { className: "ods-console__line-toggle ods-console__line-toggle--placeholder" }),
11832
+ /* @__PURE__ */ jsx52("span", { className: "ods-console__timestamp", children: log.timestamp }),
11833
+ /* @__PURE__ */ jsx52("span", { className: cn("ods-console__level", `ods-console__level--${log.level}`), children: log.level.toUpperCase() }),
11834
+ log.nodeLabel && /* @__PURE__ */ jsx52("span", { className: "ods-console__node-tag", title: log.nodeId, children: log.nodeLabel }),
11835
+ /* @__PURE__ */ jsx52("span", { className: "ods-console__message", children: q(query, log.message) })
11836
+ ] }),
11837
+ canExpand && expanded && /* @__PURE__ */ jsx52("pre", { className: "ods-console__detail", children: typeof log.detail === "string" ? log.detail : safeStringify(log.detail) })
11838
+ ]
11839
+ }
11840
+ );
11841
+ });
11821
11842
  function q(query, text) {
11822
11843
  const trimmed = query.trim();
11823
11844
  if (!trimmed) return text;
@@ -11958,7 +11979,7 @@ import {
11958
11979
  } from "@octaviaflow/icons";
11959
11980
  import {
11960
11981
  forwardRef as forwardRef43,
11961
- useCallback as useCallback17,
11982
+ useCallback as useCallback18,
11962
11983
  useEffect as useEffect22,
11963
11984
  useId as useId22,
11964
11985
  useImperativeHandle as useImperativeHandle5,
@@ -12094,7 +12115,7 @@ var FileDropzone = forwardRef43(
12094
12115
  const [isOver, setOver] = useState27(false);
12095
12116
  const [error, setError] = useState27(null);
12096
12117
  const [autoPreviews, setAutoPreviews] = useState27({});
12097
- const validate = useCallback17(
12118
+ const validate = useCallback18(
12098
12119
  (list) => {
12099
12120
  if (maxFiles && list.length > maxFiles) {
12100
12121
  return { ok: [], error: `Too many files \u2014 max ${maxFiles}` };
@@ -12123,7 +12144,7 @@ var FileDropzone = forwardRef43(
12123
12144
  },
12124
12145
  [accept, maxFiles, maxSize]
12125
12146
  );
12126
- const handleFiles = useCallback17(
12147
+ const handleFiles = useCallback18(
12127
12148
  (incoming) => {
12128
12149
  if (disabled) return;
12129
12150
  const { ok, error: error2 } = validate(incoming);
@@ -12414,7 +12435,7 @@ import {
12414
12435
  SearchIcon as SearchIcon9
12415
12436
  } from "@octaviaflow/icons";
12416
12437
  import {
12417
- useCallback as useCallback22,
12438
+ useCallback as useCallback23,
12418
12439
  useEffect as useEffect26,
12419
12440
  useMemo as useMemo19,
12420
12441
  useRef as useRef23,
@@ -12463,7 +12484,7 @@ import {
12463
12484
  XmlIcon
12464
12485
  } from "@octaviaflow/icons";
12465
12486
  import {
12466
- useCallback as useCallback18,
12487
+ useCallback as useCallback19,
12467
12488
  useMemo as useMemo14,
12468
12489
  useState as useState28
12469
12490
  } from "react";
@@ -12700,7 +12721,7 @@ function FileList({
12700
12721
  }) {
12701
12722
  const [viewState, setViewState] = useState28(defaultView);
12702
12723
  const view = viewProp ?? viewState;
12703
- const setView = useCallback18(
12724
+ const setView = useCallback19(
12704
12725
  (v) => {
12705
12726
  if (viewProp === void 0) setViewState(v);
12706
12727
  onViewChange?.(v);
@@ -12711,7 +12732,7 @@ function FileList({
12711
12732
  const [sortDirState, setSortDirState] = useState28(defaultSortDir);
12712
12733
  const sortKey = sortKeyProp ?? sortKeyState;
12713
12734
  const sortDir = sortDirProp ?? sortDirState;
12714
- const applySort = useCallback18(
12735
+ const applySort = useCallback19(
12715
12736
  (key) => {
12716
12737
  const nextDir = key === sortKey ? sortDir === "asc" ? "desc" : "asc" : "asc";
12717
12738
  if (sortKeyProp === void 0) setSortKeyState(key);
@@ -12725,14 +12746,14 @@ function FileList({
12725
12746
  );
12726
12747
  const selectedPaths = selectedProp ?? selectedState;
12727
12748
  const selectedSet = useMemo14(() => new Set(selectedPaths), [selectedPaths]);
12728
- const commitSelection = useCallback18(
12749
+ const commitSelection = useCallback19(
12729
12750
  (paths) => {
12730
12751
  if (selectedProp === void 0) setSelectedState(paths);
12731
12752
  onSelectionChange?.(paths);
12732
12753
  },
12733
12754
  [selectedProp, onSelectionChange]
12734
12755
  );
12735
- const isSelectable = useCallback18(
12756
+ const isSelectable = useCallback19(
12736
12757
  (it) => !it.disabled && (it.isDirectory ? selectableFolders : selectableFiles),
12737
12758
  [selectableFiles, selectableFolders]
12738
12759
  );
@@ -12758,7 +12779,7 @@ function FileList({
12758
12779
  const selectableItems = useMemo14(() => sorted.filter(isSelectable), [sorted, isSelectable]);
12759
12780
  const allSelected = selectableItems.length > 0 && selectableItems.every((it) => selectedSet.has(it.path));
12760
12781
  const someSelected = selectableItems.some((it) => selectedSet.has(it.path));
12761
- const toggleRow = useCallback18(
12782
+ const toggleRow = useCallback19(
12762
12783
  (it) => {
12763
12784
  if (!isSelectable(it)) return;
12764
12785
  if (multiSelect) {
@@ -12773,11 +12794,11 @@ function FileList({
12773
12794
  },
12774
12795
  [isSelectable, multiSelect, selectedPaths, commitSelection, onSelect]
12775
12796
  );
12776
- const toggleAll = useCallback18(() => {
12797
+ const toggleAll = useCallback19(() => {
12777
12798
  if (allSelected) commitSelection([]);
12778
12799
  else commitSelection(selectableItems.map((it) => it.path));
12779
12800
  }, [allSelected, commitSelection, selectableItems]);
12780
- const activate = useCallback18(
12801
+ const activate = useCallback19(
12781
12802
  (it) => {
12782
12803
  if (it.disabled) return;
12783
12804
  onOpen?.(it);
@@ -12983,7 +13004,7 @@ import {
12983
13004
  import { XMLValidator } from "fast-xml-parser";
12984
13005
  import {
12985
13006
  forwardRef as forwardRef45,
12986
- useCallback as useCallback19,
13007
+ useCallback as useCallback20,
12987
13008
  useEffect as useEffect23,
12988
13009
  useId as useId23,
12989
13010
  useMemo as useMemo15,
@@ -13185,7 +13206,7 @@ function XmlNodeRow({
13185
13206
  const [open, setOpen] = useState29(depth < defaultExpandDepth);
13186
13207
  const [copied, setCopied] = useState29(false);
13187
13208
  const pad2 = depth * 14;
13188
- const onCopy = useCallback19(
13209
+ const onCopy = useCallback20(
13189
13210
  (e) => {
13190
13211
  e.stopPropagation();
13191
13212
  const text = serializeNode(node);
@@ -13369,7 +13390,7 @@ import {
13369
13390
  } from "@octaviaflow/icons";
13370
13391
  import {
13371
13392
  forwardRef as forwardRef46,
13372
- useCallback as useCallback20,
13393
+ useCallback as useCallback21,
13373
13394
  useEffect as useEffect24,
13374
13395
  useId as useId24,
13375
13396
  useMemo as useMemo16,
@@ -13537,7 +13558,7 @@ var YamlViewer = forwardRef46(
13537
13558
  });
13538
13559
  return s;
13539
13560
  });
13540
- const toggle = useCallback20((idx) => {
13561
+ const toggle = useCallback21((idx) => {
13541
13562
  setCollapsed((prev) => {
13542
13563
  const next = new Set(prev);
13543
13564
  if (next.has(idx)) next.delete(idx);
@@ -13561,7 +13582,7 @@ var YamlViewer = forwardRef46(
13561
13582
  return hide;
13562
13583
  }, [tokens, collapsed]);
13563
13584
  const [copied, setCopied] = useState30(false);
13564
- const onCopy = useCallback20(() => {
13585
+ const onCopy = useCallback21(() => {
13565
13586
  if (!navigator?.clipboard?.writeText) return;
13566
13587
  navigator.clipboard.writeText(text).then(
13567
13588
  () => {
@@ -13956,7 +13977,7 @@ import { ChevronRightIcon as ChevronRightIcon5 } from "@octaviaflow/icons";
13956
13977
  import { motion as motion14, useReducedMotion as useReducedMotion7 } from "framer-motion";
13957
13978
  import {
13958
13979
  forwardRef as forwardRef47,
13959
- useCallback as useCallback21,
13980
+ useCallback as useCallback22,
13960
13981
  useEffect as useEffect25,
13961
13982
  useId as useId25,
13962
13983
  useMemo as useMemo18,
@@ -14002,7 +14023,7 @@ var TreeView = forwardRef47(
14002
14023
  const expandedSet = isExpandedControlled ? controlledExpanded : internalExpanded;
14003
14024
  const [loaded, setLoaded] = useState31({});
14004
14025
  const [loading, setLoading] = useState31(/* @__PURE__ */ new Set());
14005
- const resolveChildren = useCallback21(
14026
+ const resolveChildren = useCallback22(
14006
14027
  (node) => node.children ?? loaded[node.id],
14007
14028
  [loaded]
14008
14029
  );
@@ -14018,14 +14039,14 @@ var TreeView = forwardRef47(
14018
14039
  () => buildVisibleList(resolvedNodes, expandedSet),
14019
14040
  [resolvedNodes, expandedSet]
14020
14041
  );
14021
- const setExpanded = useCallback21(
14042
+ const setExpanded = useCallback22(
14022
14043
  (next) => {
14023
14044
  if (!isExpandedControlled) setInternalExpanded(new Set(next));
14024
14045
  onExpandedChange?.(new Set(next));
14025
14046
  },
14026
14047
  [isExpandedControlled, onExpandedChange]
14027
14048
  );
14028
- const toggleExpand = useCallback21(
14049
+ const toggleExpand = useCallback22(
14029
14050
  async (node) => {
14030
14051
  const next = new Set(expandedSet);
14031
14052
  const isOpen = next.has(node.id);
@@ -14054,7 +14075,7 @@ var TreeView = forwardRef47(
14054
14075
  },
14055
14076
  [expandedSet, setExpanded, onLoadChildren, loaded, loading]
14056
14077
  );
14057
- const handleSelect = useCallback21(
14078
+ const handleSelect = useCallback22(
14058
14079
  (node) => {
14059
14080
  if (node.disabled || disabled) return;
14060
14081
  if (!isSelectedControlled) setInternalSelected(node.id);
@@ -14295,7 +14316,7 @@ function FileBrowser({
14295
14316
  const [query, setQuery] = useState32("");
14296
14317
  const [preview, setPreview] = useState32(null);
14297
14318
  const previewEnabled = (showPreview ?? Boolean(getPreview)) && Boolean(getPreview);
14298
- const loadFolder = useCallback22(
14319
+ const loadFolder = useCallback23(
14299
14320
  async (folder) => {
14300
14321
  const cached = cacheRef.current[folder];
14301
14322
  if (cached?.status === "loaded" && cached.items) return cached.items;
@@ -14316,7 +14337,7 @@ function FileBrowser({
14316
14337
  useEffect26(() => {
14317
14338
  void loadFolder(currentPath);
14318
14339
  }, [currentPath, loadFolder]);
14319
- const navigate = useCallback22(
14340
+ const navigate = useCallback23(
14320
14341
  (next) => {
14321
14342
  if (pathProp === void 0) setPathState(next);
14322
14343
  setExpanded((prev) => {
@@ -14328,7 +14349,7 @@ function FileBrowser({
14328
14349
  },
14329
14350
  [pathProp, onNavigate, rootPath, separator]
14330
14351
  );
14331
- const refresh = useCallback22(() => {
14352
+ const refresh = useCallback23(() => {
14332
14353
  setCache((prev) => {
14333
14354
  const next = { ...prev };
14334
14355
  delete next[currentPath];
@@ -14337,18 +14358,18 @@ function FileBrowser({
14337
14358
  setTreeVersion((v) => v + 1);
14338
14359
  void loadFolder(currentPath);
14339
14360
  }, [currentPath, loadFolder]);
14340
- const resolveItems = useCallback22(
14361
+ const resolveItems = useCallback23(
14341
14362
  (paths) => paths.map((p) => seenRef.current.get(p)).filter(Boolean),
14342
14363
  []
14343
14364
  );
14344
- const commitSelection = useCallback22(
14365
+ const commitSelection = useCallback23(
14345
14366
  (paths) => {
14346
14367
  if (selectedProp === void 0) setSelectedState(paths);
14347
14368
  onSelectionChange?.(paths, resolveItems(paths));
14348
14369
  },
14349
14370
  [selectedProp, onSelectionChange, resolveItems]
14350
14371
  );
14351
- const loadPreview = useCallback22(
14372
+ const loadPreview = useCallback23(
14352
14373
  async (item) => {
14353
14374
  if (!getPreview) return;
14354
14375
  setPreview({ path: item.path, name: item.name, loading: true });
@@ -14366,13 +14387,13 @@ function FileBrowser({
14366
14387
  },
14367
14388
  [getPreview]
14368
14389
  );
14369
- const handleSelect = useCallback22(
14390
+ const handleSelect = useCallback23(
14370
14391
  (item) => {
14371
14392
  if (!item.isDirectory && previewEnabled) void loadPreview(item);
14372
14393
  },
14373
14394
  [previewEnabled, loadPreview]
14374
14395
  );
14375
- const handleOpen = useCallback22(
14396
+ const handleOpen = useCallback23(
14376
14397
  (item) => {
14377
14398
  if (item.isDirectory) navigate(item.path);
14378
14399
  else onFileOpen?.(item);
@@ -14386,7 +14407,7 @@ function FileBrowser({
14386
14407
  if (!q2) return rawItems;
14387
14408
  return rawItems.filter((it) => it.name.toLowerCase().includes(q2));
14388
14409
  }, [rawItems, query]);
14389
- const folderToTreeNode = useCallback22(
14410
+ const folderToTreeNode = useCallback23(
14390
14411
  (it) => ({
14391
14412
  id: it.path,
14392
14413
  label: it.name,
@@ -14396,7 +14417,7 @@ function FileBrowser({
14396
14417
  }),
14397
14418
  []
14398
14419
  );
14399
- const loadTreeChildren = useCallback22(
14420
+ const loadTreeChildren = useCallback23(
14400
14421
  async (node) => {
14401
14422
  const children = await loadFolder(String(node.id));
14402
14423
  return children.filter((c) => c.isDirectory).map(folderToTreeNode);
@@ -14575,7 +14596,7 @@ import {
14575
14596
  XmlIcon as XmlIcon3
14576
14597
  } from "@octaviaflow/icons";
14577
14598
  import {
14578
- useCallback as useCallback23,
14599
+ useCallback as useCallback24,
14579
14600
  useEffect as useEffect27,
14580
14601
  useId as useId26,
14581
14602
  useMemo as useMemo20,
@@ -14676,7 +14697,7 @@ function FilePicker({
14676
14697
  const popoverPos = useAnchoredPopover(triggerRef, open, { popoverRef });
14677
14698
  const canSelectFiles = selectMode !== "folder";
14678
14699
  const canSelectFolders = selectMode !== "file";
14679
- const loadFolder = useCallback23(
14700
+ const loadFolder = useCallback24(
14680
14701
  async (folder) => {
14681
14702
  const cached = cacheRef.current[folder];
14682
14703
  if (cached?.status === "loaded" && cached.items) return cached.items;
@@ -14698,7 +14719,7 @@ function FilePicker({
14698
14719
  },
14699
14720
  [loadChildren]
14700
14721
  );
14701
- const openAt = useCallback23(() => {
14722
+ const openAt = useCallback24(() => {
14702
14723
  const start = initialPath ?? (value ? parentOf(value, rootPath, separator) ?? rootPath : rootPath);
14703
14724
  setNavPath(start);
14704
14725
  setTrail([]);
@@ -14707,11 +14728,11 @@ function FilePicker({
14707
14728
  setOpen(true);
14708
14729
  void loadFolder(start);
14709
14730
  }, [initialPath, value, rootPath, separator, loadFolder]);
14710
- const close = useCallback23(() => {
14731
+ const close = useCallback24(() => {
14711
14732
  setOpen(false);
14712
14733
  triggerRef.current?.focus();
14713
14734
  }, []);
14714
- const navigate = useCallback23(
14735
+ const navigate = useCallback24(
14715
14736
  (folder) => {
14716
14737
  setNavPath(folder);
14717
14738
  setQuery("");
@@ -14721,7 +14742,7 @@ function FilePicker({
14721
14742
  },
14722
14743
  [loadFolder]
14723
14744
  );
14724
- const walkSearch = useCallback23(
14745
+ const walkSearch = useCallback24(
14725
14746
  async (root, needle) => {
14726
14747
  const q2 = needle.toLowerCase();
14727
14748
  const out = [];
@@ -14773,7 +14794,7 @@ function FilePicker({
14773
14794
  }, 220);
14774
14795
  return () => clearTimeout(timer);
14775
14796
  }, [query, searchable, open, navPath, selectMode, onSearch, walkSearch]);
14776
- const commit = useCallback23(
14797
+ const commit = useCallback24(
14777
14798
  (path, item) => {
14778
14799
  if (valueProp === void 0) setValueState(path);
14779
14800
  onChange?.(path, item);
@@ -14782,7 +14803,7 @@ function FilePicker({
14782
14803
  },
14783
14804
  [valueProp, onChange]
14784
14805
  );
14785
- const handleRowActivate = useCallback23(
14806
+ const handleRowActivate = useCallback24(
14786
14807
  (item) => {
14787
14808
  if (item.disabled) return;
14788
14809
  if (item.isDirectory) {
@@ -14825,7 +14846,7 @@ function FilePicker({
14825
14846
  if (isSearching) return search?.results ?? [];
14826
14847
  return [...rawItems].sort(folderFirstThenName);
14827
14848
  }, [isSearching, search, rawItems]);
14828
- const displayName = useCallback23(
14849
+ const displayName = useCallback24(
14829
14850
  (p) => p === rootPath ? rootLabel : nameByPath[p] ?? pathLabels?.[p] ?? baseName(p, separator),
14830
14851
  [rootPath, rootLabel, nameByPath, pathLabels, separator]
14831
14852
  );
@@ -14837,12 +14858,12 @@ function FilePicker({
14837
14858
  return chain.map((p, i) => ({ path: p, label: i === 0 ? rootLabel : displayName(p) }));
14838
14859
  }, [navPath, rootPath, rootLabel, separator, trail, displayName]);
14839
14860
  const parent = trail.length ? trail[trail.length - 1] : parentOf(navPath, rootPath, separator);
14840
- const goUp = useCallback23(() => {
14861
+ const goUp = useCallback24(() => {
14841
14862
  if (!parent) return;
14842
14863
  setTrail((t) => t.length ? t.slice(0, -1) : t);
14843
14864
  navigate(parent);
14844
14865
  }, [parent, navigate]);
14845
- const goToCrumb = useCallback23(
14866
+ const goToCrumb = useCallback24(
14846
14867
  (path, index) => {
14847
14868
  setTrail(crumbs.slice(1, index).map((c) => c.path));
14848
14869
  navigate(path);
@@ -15101,7 +15122,7 @@ FilePicker.displayName = "FilePicker";
15101
15122
 
15102
15123
  // src/components/FlowCanvas/FlowCanvas.tsx
15103
15124
  import { AnimatePresence as AnimatePresence10 } from "framer-motion";
15104
- import { useCallback as useCallback25, useRef as useRef26 } from "react";
15125
+ import { useCallback as useCallback26, useRef as useRef26 } from "react";
15105
15126
 
15106
15127
  // src/components/FlowEdge/FlowEdge.tsx
15107
15128
  import { useId as useId27, useState as useState34 } from "react";
@@ -15288,7 +15309,7 @@ function FlowEdge({
15288
15309
  import { motion as motion15 } from "framer-motion";
15289
15310
  import {
15290
15311
  forwardRef as forwardRef48,
15291
- useCallback as useCallback24,
15312
+ useCallback as useCallback25,
15292
15313
  useEffect as useEffect28,
15293
15314
  useRef as useRef25,
15294
15315
  useState as useState35
@@ -15356,7 +15377,7 @@ var FlowNode = forwardRef48(function FlowNode2({
15356
15377
  const [wasDragged, setWasDragged] = useState35(false);
15357
15378
  const dragStartRef = useRef25(null);
15358
15379
  const zoom = viewport?.zoom ?? 1;
15359
- const handleClick = useCallback24(
15380
+ const handleClick = useCallback25(
15360
15381
  (e) => {
15361
15382
  e.stopPropagation();
15362
15383
  if (wasDragged) {
@@ -15367,7 +15388,7 @@ var FlowNode = forwardRef48(function FlowNode2({
15367
15388
  },
15368
15389
  [node.id, onSelect, wasDragged]
15369
15390
  );
15370
- const handleDelete = useCallback24(
15391
+ const handleDelete = useCallback25(
15371
15392
  (e) => {
15372
15393
  e.stopPropagation();
15373
15394
  if (isLockMode) return;
@@ -15375,7 +15396,7 @@ var FlowNode = forwardRef48(function FlowNode2({
15375
15396
  },
15376
15397
  [node.id, onDelete, isLockMode]
15377
15398
  );
15378
- const handleMouseDown = useCallback24(
15399
+ const handleMouseDown = useCallback25(
15379
15400
  (e) => {
15380
15401
  if (isLockMode) return;
15381
15402
  const target = e.target;
@@ -15388,7 +15409,7 @@ var FlowNode = forwardRef48(function FlowNode2({
15388
15409
  },
15389
15410
  [isLockMode]
15390
15411
  );
15391
- const handleTouchStart = useCallback24(
15412
+ const handleTouchStart = useCallback25(
15392
15413
  (e) => {
15393
15414
  if (isLockMode) return;
15394
15415
  if (e.touches.length !== 1) return;
@@ -15450,7 +15471,7 @@ var FlowNode = forwardRef48(function FlowNode2({
15450
15471
  document.removeEventListener("touchcancel", onTouchEnd);
15451
15472
  };
15452
15473
  }, [isDragging, zoom, node.id, node.position.x, node.position.y, onPositionChange]);
15453
- const handlePortMouseDown = useCallback24(
15474
+ const handlePortMouseDown = useCallback25(
15454
15475
  (e, portId, portType) => {
15455
15476
  e.stopPropagation();
15456
15477
  if (isLockMode) return;
@@ -15460,7 +15481,7 @@ var FlowNode = forwardRef48(function FlowNode2({
15460
15481
  },
15461
15482
  [connectingFrom, isLockMode, node.id, onStartConnecting]
15462
15483
  );
15463
- const handlePortMouseUp = useCallback24(
15484
+ const handlePortMouseUp = useCallback25(
15464
15485
  (e, portId, portType) => {
15465
15486
  e.stopPropagation();
15466
15487
  if (isLockMode) return;
@@ -15469,7 +15490,7 @@ var FlowNode = forwardRef48(function FlowNode2({
15469
15490
  },
15470
15491
  [connectingFrom, isLockMode, node.id, onEndConnecting]
15471
15492
  );
15472
- const isPortEdgeSelected = useCallback24(
15493
+ const isPortEdgeSelected = useCallback25(
15473
15494
  (portId, portType) => edges.some(
15474
15495
  (edge) => edge.selected && (portType === "input" ? edge.target === node.id && edge.targetPort === portId : edge.source === node.id && edge.sourcePort === portId)
15475
15496
  ),
@@ -15704,7 +15725,7 @@ function FlowCanvas2({
15704
15725
  }) {
15705
15726
  const canvasRef = useRef26(null);
15706
15727
  const isEmpty = nodes.length === 0 && edges.length === 0;
15707
- const handleCanvasClick = useCallback25(
15728
+ const handleCanvasClick = useCallback26(
15708
15729
  (e) => {
15709
15730
  const target = e.target;
15710
15731
  if (target === canvasRef.current) {
@@ -15956,7 +15977,7 @@ function FlowDoctor({
15956
15977
 
15957
15978
  // src/components/FlowMinimap/FlowMinimap.tsx
15958
15979
  import {
15959
- useCallback as useCallback26,
15980
+ useCallback as useCallback27,
15960
15981
  useContext,
15961
15982
  useEffect as useEffect29,
15962
15983
  useMemo as useMemo21,
@@ -16100,7 +16121,7 @@ function FlowMinimap(props) {
16100
16121
  h: maxY - minY + bounds_padding * 2
16101
16122
  };
16102
16123
  }, [totalWidthProp, totalHeightProp, contentBounds, bounds_padding]);
16103
- const clampWorldTopLeft = useCallback26(
16124
+ const clampWorldTopLeft = useCallback27(
16104
16125
  (worldX, worldY, vw, vh) => {
16105
16126
  if (!contentBounds) return { x: worldX, y: worldY };
16106
16127
  const minTLX = viewBox.x;
@@ -16113,7 +16134,7 @@ function FlowMinimap(props) {
16113
16134
  },
16114
16135
  [contentBounds, viewBox.x, viewBox.y, viewBox.w, viewBox.h]
16115
16136
  );
16116
- const reportViewportChange = useCallback26(
16137
+ const reportViewportChange = useCallback27(
16117
16138
  (worldX, worldY) => {
16118
16139
  if (effectiveViewportRect) {
16119
16140
  const clamped = clampWorldTopLeft(
@@ -16149,7 +16170,7 @@ function FlowMinimap(props) {
16149
16170
  [onViewportChange, viewportProp?.zoom, instance, liveSnapshot, effectiveViewportRect, clampWorldTopLeft]
16150
16171
  );
16151
16172
  const svgRef = useRef27(null);
16152
- const pointToWorld = useCallback26(
16173
+ const pointToWorld = useCallback27(
16153
16174
  (clientX, clientY) => {
16154
16175
  const svg = svgRef.current;
16155
16176
  if (!svg) return null;
@@ -16176,7 +16197,7 @@ function FlowMinimap(props) {
16176
16197
  });
16177
16198
  const suppressNextClickRef = useRef27(false);
16178
16199
  const [isDragging, setIsDragging] = useState36(false);
16179
- const onViewportPointerDown = useCallback26(
16200
+ const onViewportPointerDown = useCallback27(
16180
16201
  (e) => {
16181
16202
  if (!effectiveViewportRect) return;
16182
16203
  e.stopPropagation();
@@ -16198,7 +16219,7 @@ function FlowMinimap(props) {
16198
16219
  },
16199
16220
  [effectiveViewportRect, pointToWorld]
16200
16221
  );
16201
- const onSvgPointerMove = useCallback26(
16222
+ const onSvgPointerMove = useCallback27(
16202
16223
  (e) => {
16203
16224
  const d = dragRef.current;
16204
16225
  if (!d.dragging || d.pointerId !== e.pointerId) return;
@@ -16214,7 +16235,7 @@ function FlowMinimap(props) {
16214
16235
  },
16215
16236
  [pointToWorld, reportViewportChange]
16216
16237
  );
16217
- const onSvgPointerUp = useCallback26((e) => {
16238
+ const onSvgPointerUp = useCallback27((e) => {
16218
16239
  const d = dragRef.current;
16219
16240
  if (d.dragging && d.pointerId === e.pointerId) {
16220
16241
  d.dragging = false;
@@ -16223,7 +16244,7 @@ function FlowMinimap(props) {
16223
16244
  e.currentTarget.releasePointerCapture?.(e.pointerId);
16224
16245
  }
16225
16246
  }, []);
16226
- const handleSvgClick = useCallback26(
16247
+ const handleSvgClick = useCallback27(
16227
16248
  (e) => {
16228
16249
  if (suppressNextClickRef.current) {
16229
16250
  suppressNextClickRef.current = false;
@@ -16241,7 +16262,7 @@ function FlowMinimap(props) {
16241
16262
  },
16242
16263
  [pointToWorld, effectiveViewportRect, reportViewportChange]
16243
16264
  );
16244
- const handleWheel = useCallback26(
16265
+ const handleWheel = useCallback27(
16245
16266
  (e) => {
16246
16267
  if (!zoomOnScroll) return;
16247
16268
  if (!instance || !liveSnapshot) return;
@@ -16595,7 +16616,7 @@ import {
16595
16616
  import { useEffect as useEffect32, useRef as useRef29, useState as useState39 } from "react";
16596
16617
 
16597
16618
  // src/components/HoverCard/HoverCard.tsx
16598
- import { useCallback as useCallback27, useEffect as useEffect31, useLayoutEffect as useLayoutEffect7, useRef as useRef28, useState as useState38 } from "react";
16619
+ import { useCallback as useCallback28, useEffect as useEffect31, useLayoutEffect as useLayoutEffect7, useRef as useRef28, useState as useState38 } from "react";
16599
16620
  import { createPortal as createPortal11 } from "react-dom";
16600
16621
  import { Fragment as Fragment27, jsx as jsx70, jsxs as jsxs69 } from "react/jsx-runtime";
16601
16622
  function computePosition2(rect, panelRect, placement, offset) {
@@ -16646,7 +16667,7 @@ function HoverCard({
16646
16667
  clearTimers();
16647
16668
  closeTimer.current = setTimeout(() => setOpen(false), closeDelay);
16648
16669
  };
16649
- const reposition = useCallback27(() => {
16670
+ const reposition = useCallback28(() => {
16650
16671
  if (!triggerRef.current || !panelRef.current) return;
16651
16672
  const trigRect = triggerRef.current.getBoundingClientRect();
16652
16673
  const panelRect = panelRef.current.getBoundingClientRect();
@@ -17190,7 +17211,7 @@ import { useEffect as useEffect34, useState as useState41 } from "react";
17190
17211
  // src/components/OTPInput/OTPInput.tsx
17191
17212
  import {
17192
17213
  forwardRef as forwardRef49,
17193
- useCallback as useCallback28,
17214
+ useCallback as useCallback29,
17194
17215
  useId as useId28,
17195
17216
  useImperativeHandle as useImperativeHandle6,
17196
17217
  useRef as useRef30
@@ -17236,7 +17257,7 @@ var OTPInput = forwardRef49(function OTPInput2({
17236
17257
  }),
17237
17258
  [value, length, onChange]
17238
17259
  );
17239
- const setCharAt = useCallback28(
17260
+ const setCharAt = useCallback29(
17240
17261
  (idx, ch) => {
17241
17262
  const cleaned = ch.replace(pattern, "").slice(0, 1);
17242
17263
  const chars = value.split("");
@@ -17322,7 +17343,7 @@ OTPInput.displayName = "OTPInput";
17322
17343
  // src/components/PhoneInput/PhoneInput.tsx
17323
17344
  import {
17324
17345
  forwardRef as forwardRef50,
17325
- useCallback as useCallback29,
17346
+ useCallback as useCallback30,
17326
17347
  useEffect as useEffect33,
17327
17348
  useId as useId29,
17328
17349
  useRef as useRef31,
@@ -17415,7 +17436,7 @@ var PhoneInput = forwardRef50(
17415
17436
  useEffect33(() => {
17416
17437
  setActiveIdx(0);
17417
17438
  }, [query]);
17418
- const handleTriggerKey = useCallback29(
17439
+ const handleTriggerKey = useCallback30(
17419
17440
  (e) => {
17420
17441
  if (disabled) return;
17421
17442
  if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
@@ -17425,7 +17446,7 @@ var PhoneInput = forwardRef50(
17425
17446
  },
17426
17447
  [disabled]
17427
17448
  );
17428
- const handleNavKey = useCallback29(
17449
+ const handleNavKey = useCallback30(
17429
17450
  (e) => {
17430
17451
  if (e.key === "ArrowDown") {
17431
17452
  e.preventDefault();
@@ -19638,7 +19659,7 @@ var Grid2 = Object.assign(GridBase, { Item: GridItem });
19638
19659
  import { AnimatePresence as AnimatePresence11, motion as motion17 } from "framer-motion";
19639
19660
  import {
19640
19661
  forwardRef as forwardRef55,
19641
- useCallback as useCallback30,
19662
+ useCallback as useCallback31,
19642
19663
  useId as useId33,
19643
19664
  useMemo as useMemo23,
19644
19665
  useState as useState45
@@ -19715,14 +19736,14 @@ var Heatmap = forwardRef55(
19715
19736
  [domainMax, data]
19716
19737
  );
19717
19738
  const [hovered, setHovered] = useState45(null);
19718
- const fire = useCallback30(
19739
+ const fire = useCallback31(
19719
19740
  (cell) => {
19720
19741
  setHovered(cell);
19721
19742
  onCellHover?.(cell);
19722
19743
  },
19723
19744
  [onCellHover]
19724
19745
  );
19725
- const handleKey = useCallback30(
19746
+ const handleKey = useCallback31(
19726
19747
  (e, cell) => {
19727
19748
  if (!onCellClick) return;
19728
19749
  if (e.key === "Enter" || e.key === " ") {
@@ -20402,7 +20423,7 @@ KbdGroup.displayName = "KbdGroup";
20402
20423
  import { AnimatePresence as AnimatePresence12, motion as motion18 } from "framer-motion";
20403
20424
  import {
20404
20425
  forwardRef as forwardRef60,
20405
- useCallback as useCallback31,
20426
+ useCallback as useCallback32,
20406
20427
  useEffect as useEffect37,
20407
20428
  useId as useId37,
20408
20429
  useMemo as useMemo24,
@@ -20530,7 +20551,7 @@ var LineChart = forwardRef60(
20530
20551
  const [pointerPct, setPointerPct] = useState46(null);
20531
20552
  const plotRef = useRef32(null);
20532
20553
  const [brush, setBrush] = useState46(null);
20533
- const indexFromPct = useCallback31(
20554
+ const indexFromPct = useCallback32(
20534
20555
  (pct) => {
20535
20556
  if (xCount === 0) return 0;
20536
20557
  return Math.max(
@@ -20540,7 +20561,7 @@ var LineChart = forwardRef60(
20540
20561
  },
20541
20562
  [xCount]
20542
20563
  );
20543
- const handlePlotMove = useCallback31(
20564
+ const handlePlotMove = useCallback32(
20544
20565
  (e) => {
20545
20566
  if (xCount === 0) return;
20546
20567
  const rect = plotRef.current?.getBoundingClientRect();
@@ -20569,12 +20590,12 @@ var LineChart = forwardRef60(
20569
20590
  visibleRange.start
20570
20591
  ]
20571
20592
  );
20572
- const handlePlotLeave = useCallback31(() => {
20593
+ const handlePlotLeave = useCallback32(() => {
20573
20594
  setHoveredIdx(null);
20574
20595
  setPointerPct(null);
20575
20596
  onPointHover?.(null, null, null);
20576
20597
  }, [onPointHover]);
20577
- const handlePlotDown = useCallback31(
20598
+ const handlePlotDown = useCallback32(
20578
20599
  (e) => {
20579
20600
  if (!zoomable) return;
20580
20601
  const rect = plotRef.current?.getBoundingClientRect();
@@ -20608,12 +20629,12 @@ var LineChart = forwardRef60(
20608
20629
  window.addEventListener("mouseup", onUp);
20609
20630
  return () => window.removeEventListener("mouseup", onUp);
20610
20631
  }, [brush, indexFromPct, visibleRange.start, onZoomChange]);
20611
- const handleDoubleClick = useCallback31(() => {
20632
+ const handleDoubleClick = useCallback32(() => {
20612
20633
  if (!zoomable || !zoom) return;
20613
20634
  setZoom(null);
20614
20635
  onZoomChange?.(null);
20615
20636
  }, [zoomable, zoom, onZoomChange]);
20616
- const handlePlotClick = useCallback31(() => {
20637
+ const handlePlotClick = useCallback32(() => {
20617
20638
  if (hoveredIdx === null || !onPointClick) return;
20618
20639
  const s = lines[0];
20619
20640
  const p = s?.data[hoveredIdx];
@@ -20633,11 +20654,11 @@ var LineChart = forwardRef60(
20633
20654
  const showX = showAxis === "x" || showAxis === "both";
20634
20655
  const isMulti = (series?.length ?? 0) > 0;
20635
20656
  const tooltipPoint = hoveredIdx !== null ? lines[0]?.data[hoveredIdx] : void 0;
20636
- const dataXPct = useCallback31(
20657
+ const dataXPct = useCallback32(
20637
20658
  (i) => (PAD + i * stepX) / W * 100,
20638
20659
  [stepX]
20639
20660
  );
20640
- const dataYPct = useCallback31(
20661
+ const dataYPct = useCallback32(
20641
20662
  (v) => (PAD + (1 - (v - lo) / (hi - lo)) * (H - PAD * 2)) / H * 100,
20642
20663
  [lo, hi]
20643
20664
  );
@@ -21022,7 +21043,7 @@ LinkButton.displayName = "LinkButton";
21022
21043
  // src/components/MessageBlockBuilder/MessageBlockBuilder.tsx
21023
21044
  import { AddIcon as AddIcon5, CodeIcon as CodeIcon4, CopyIcon as CopyIcon5, DataConnectedIcon, TrashCanIcon as TrashCanIcon2 } from "@octaviaflow/icons";
21024
21045
  import {
21025
- useCallback as useCallback33,
21046
+ useCallback as useCallback34,
21026
21047
  useEffect as useEffect41,
21027
21048
  useMemo as useMemo26,
21028
21049
  useRef as useRef35,
@@ -21032,7 +21053,7 @@ import {
21032
21053
  // src/components/Sortable/Sortable.tsx
21033
21054
  import {
21034
21055
  forwardRef as forwardRef62,
21035
- useCallback as useCallback32,
21056
+ useCallback as useCallback33,
21036
21057
  useEffect as useEffect38,
21037
21058
  useRef as useRef33,
21038
21059
  useState as useState47
@@ -21059,7 +21080,7 @@ function Sortable({
21059
21080
  const [dropPos, setDropPos] = useState47(null);
21060
21081
  const [kbActiveId, setKbActiveId] = useState47(null);
21061
21082
  const isVertical = direction === "vertical";
21062
- const onDragStart = useCallback32(
21083
+ const onDragStart = useCallback33(
21063
21084
  (id) => (e) => {
21064
21085
  if (disabled) return;
21065
21086
  e.dataTransfer.effectAllowed = "move";
@@ -21070,7 +21091,7 @@ function Sortable({
21070
21091
  },
21071
21092
  [disabled, items]
21072
21093
  );
21073
- const cancelDrag = useCallback32(() => {
21094
+ const cancelDrag = useCallback33(() => {
21074
21095
  setDraggingId(null);
21075
21096
  setDropPos(null);
21076
21097
  originalOrderRef.current = null;
@@ -21079,7 +21100,7 @@ function Sortable({
21079
21100
  scrollTimerRef.current = null;
21080
21101
  }
21081
21102
  }, []);
21082
- const onDragEnd = useCallback32(() => {
21103
+ const onDragEnd = useCallback33(() => {
21083
21104
  cancelDrag();
21084
21105
  }, [cancelDrag]);
21085
21106
  const onItemDragOver = (id) => (e) => {
@@ -21104,7 +21125,7 @@ function Sortable({
21104
21125
  if (sourceId === target.id) return;
21105
21126
  commitMove(sourceId, target.id, target.edge);
21106
21127
  };
21107
- const commitMove = useCallback32(
21128
+ const commitMove = useCallback33(
21108
21129
  (sourceId, targetId, edge) => {
21109
21130
  const from = items.findIndex((i) => i.id === sourceId);
21110
21131
  let to = items.findIndex((i) => i.id === targetId);
@@ -24493,7 +24514,7 @@ function MessageBlockBuilder({
24493
24514
  };
24494
24515
  }
24495
24516
  }, [draft.mode, draft.jsonText]);
24496
- const commit = useCallback33(
24517
+ const commit = useCallback34(
24497
24518
  (next) => {
24498
24519
  setDraft(next);
24499
24520
  if (onChange) {
@@ -25532,7 +25553,7 @@ MetricCard.displayName = "MetricCard";
25532
25553
  import { AnimatePresence as AnimatePresence13, motion as motion20 } from "framer-motion";
25533
25554
  import {
25534
25555
  forwardRef as forwardRef65,
25535
- useCallback as useCallback34,
25556
+ useCallback as useCallback35,
25536
25557
  useEffect as useEffect42,
25537
25558
  useId as useId40,
25538
25559
  useLayoutEffect as useLayoutEffect8,
@@ -25601,7 +25622,7 @@ var MultiSelect = forwardRef65(
25601
25622
  const searchRef = useRef36(null);
25602
25623
  const dropdownRef = useRef36(null);
25603
25624
  const chipRefs = useRef36([]);
25604
- const commit = useCallback34(
25625
+ const commit = useCallback35(
25605
25626
  (next) => {
25606
25627
  if (controlledValue === void 0) setInternalValue(next);
25607
25628
  onChange?.(next);
@@ -25623,7 +25644,7 @@ var MultiSelect = forwardRef65(
25623
25644
  const showSearch = searchable ?? options2.length > 6;
25624
25645
  const getLabel = (v) => options2.find((o) => o.value === v)?.label ?? v;
25625
25646
  const getIcon = (v) => options2.find((o) => o.value === v)?.icon;
25626
- const updatePosition = useCallback34(() => {
25647
+ const updatePosition = useCallback35(() => {
25627
25648
  if (!wrapRef.current) return;
25628
25649
  const rect = wrapRef.current.getBoundingClientRect();
25629
25650
  setDropdownPos({
@@ -25697,7 +25718,7 @@ var MultiSelect = forwardRef65(
25697
25718
  ro.observe(row);
25698
25719
  return () => ro.disconnect();
25699
25720
  }, []);
25700
- const addValue = useCallback34(
25721
+ const addValue = useCallback35(
25701
25722
  (val) => {
25702
25723
  if (maxTags && selectedValues.length >= maxTags) return;
25703
25724
  commit([...selectedValues, val]);
@@ -25707,13 +25728,13 @@ var MultiSelect = forwardRef65(
25707
25728
  },
25708
25729
  [selectedValues, maxTags, commit]
25709
25730
  );
25710
- const removeValue = useCallback34(
25731
+ const removeValue = useCallback35(
25711
25732
  (val) => {
25712
25733
  commit(selectedValues.filter((v) => v !== val));
25713
25734
  },
25714
25735
  [selectedValues, commit]
25715
25736
  );
25716
- const toggleValue = useCallback34(
25737
+ const toggleValue = useCallback35(
25717
25738
  (val) => {
25718
25739
  if (selectedSet.has(val)) {
25719
25740
  removeValue(val);
@@ -25723,11 +25744,11 @@ var MultiSelect = forwardRef65(
25723
25744
  },
25724
25745
  [selectedSet, addValue, removeValue]
25725
25746
  );
25726
- const clearAll = useCallback34(() => {
25747
+ const clearAll = useCallback35(() => {
25727
25748
  commit([]);
25728
25749
  setQuery("");
25729
25750
  }, [commit]);
25730
- const handleSearchKey = useCallback34(
25751
+ const handleSearchKey = useCallback35(
25731
25752
  (e) => {
25732
25753
  if (e.key === "Escape") {
25733
25754
  setOpen(false);
@@ -26143,7 +26164,7 @@ import {
26143
26164
  } from "@octaviaflow/icons";
26144
26165
  import {
26145
26166
  forwardRef as forwardRef66,
26146
- useCallback as useCallback35,
26167
+ useCallback as useCallback36,
26147
26168
  useId as useId41,
26148
26169
  useMemo as useMemo29,
26149
26170
  useState as useState52
@@ -26230,7 +26251,7 @@ var Pagination = forwardRef66(
26230
26251
  totalPages,
26231
26252
  Math.max(1, isControlled ? controlledPage : internalPage)
26232
26253
  );
26233
- const goTo = useCallback35(
26254
+ const goTo = useCallback36(
26234
26255
  (next) => {
26235
26256
  const clamped = Math.min(totalPages, Math.max(1, next));
26236
26257
  if (clamped === currentPage) return;
@@ -27022,7 +27043,7 @@ var PlanPicker = forwardRef69(
27022
27043
  PlanPicker.displayName = "PlanPicker";
27023
27044
 
27024
27045
  // src/components/Popover/Popover.tsx
27025
- import { useCallback as useCallback36, useEffect as useEffect43, useLayoutEffect as useLayoutEffect9, useRef as useRef37, useState as useState53 } from "react";
27046
+ import { useCallback as useCallback37, useEffect as useEffect43, useLayoutEffect as useLayoutEffect9, useRef as useRef37, useState as useState53 } from "react";
27026
27047
  import { createPortal as createPortal13 } from "react-dom";
27027
27048
  import { Fragment as Fragment45, jsx as jsx104, jsxs as jsxs101 } from "react/jsx-runtime";
27028
27049
  function computePosition3(rect, popRect, placement, offset) {
@@ -27056,7 +27077,7 @@ function Popover({
27056
27077
  }) {
27057
27078
  const [openState, setOpenState] = useState53(defaultOpen);
27058
27079
  const open = openProp ?? openState;
27059
- const setOpen = useCallback36(
27080
+ const setOpen = useCallback37(
27060
27081
  (v) => {
27061
27082
  if (openProp === void 0) setOpenState(v);
27062
27083
  onOpenChange?.(v);
@@ -27066,7 +27087,7 @@ function Popover({
27066
27087
  const triggerRef = useRef37(null);
27067
27088
  const popRef = useRef37(null);
27068
27089
  const [coords, setCoords] = useState53(null);
27069
- const reposition = useCallback36(() => {
27090
+ const reposition = useCallback37(() => {
27070
27091
  if (!triggerRef.current || !popRef.current) return;
27071
27092
  const trigRect = triggerRef.current.getBoundingClientRect();
27072
27093
  const popRect = popRef.current.getBoundingClientRect();
@@ -27498,7 +27519,7 @@ ProgressRing.displayName = "ProgressRing";
27498
27519
  // src/components/PromptInput/PromptInput.tsx
27499
27520
  import {
27500
27521
  forwardRef as forwardRef73,
27501
- useCallback as useCallback37,
27522
+ useCallback as useCallback38,
27502
27523
  useEffect as useEffect44,
27503
27524
  useId as useId45,
27504
27525
  useImperativeHandle as useImperativeHandle7,
@@ -27562,7 +27583,7 @@ var PromptInput = forwardRef73(
27562
27583
  const [suggestionIndex, setSuggestionIndex] = useState54(0);
27563
27584
  const [isDragOver, setIsDragOver] = useState54(false);
27564
27585
  const [historyIdx, setHistoryIdx] = useState54(null);
27565
- const setValue = useCallback37(
27586
+ const setValue = useCallback38(
27566
27587
  (next) => {
27567
27588
  if (!isControlled) setInternal(next);
27568
27589
  onChange?.(next);
@@ -28615,7 +28636,7 @@ function BinaryButton({
28615
28636
  // src/components/Resizable/Resizable.tsx
28616
28637
  import {
28617
28638
  forwardRef as forwardRef80,
28618
- useCallback as useCallback38,
28639
+ useCallback as useCallback39,
28619
28640
  useEffect as useEffect45,
28620
28641
  useLayoutEffect as useLayoutEffect10,
28621
28642
  useRef as useRef41,
@@ -28699,7 +28720,7 @@ var Resizable = forwardRef80(
28699
28720
  ro.observe(el);
28700
28721
  return () => ro.disconnect();
28701
28722
  }, [direction, minSecond]);
28702
- const persist = useCallback38(
28723
+ const persist = useCallback39(
28703
28724
  (next) => {
28704
28725
  onSplitChange?.(next);
28705
28726
  if (storageKey && typeof window !== "undefined" && total > 0) {
@@ -29176,7 +29197,7 @@ function Show({ above, below, children, ...rest }) {
29176
29197
  Show.displayName = "Show";
29177
29198
 
29178
29199
  // src/components/Sidebar/Sidebar.tsx
29179
- import { useCallback as useCallback39, useEffect as useEffect47, useRef as useRef42, useState as useState57 } from "react";
29200
+ import { useCallback as useCallback40, useEffect as useEffect47, useRef as useRef42, useState as useState57 } from "react";
29180
29201
  import { Fragment as Fragment50, jsx as jsx121, jsxs as jsxs116 } from "react/jsx-runtime";
29181
29202
  function Sidebar({
29182
29203
  variant = "expanded",
@@ -29208,7 +29229,7 @@ function Sidebar({
29208
29229
  }
29209
29230
  }, []);
29210
29231
  const pinned = pinnedProp ?? internalPinned;
29211
- const setPinned = useCallback39(
29232
+ const setPinned = useCallback40(
29212
29233
  (p) => {
29213
29234
  if (pinnedProp === void 0) setInternalPinned(p);
29214
29235
  try {
@@ -30310,7 +30331,7 @@ VStack.displayName = "VStack";
30310
30331
  import { AnimatePresence as AnimatePresence16, motion as motion24, useReducedMotion as useReducedMotion9 } from "framer-motion";
30311
30332
  import {
30312
30333
  forwardRef as forwardRef85,
30313
- useCallback as useCallback40,
30334
+ useCallback as useCallback41,
30314
30335
  useEffect as useEffect50,
30315
30336
  useLayoutEffect as useLayoutEffect11,
30316
30337
  useMemo as useMemo31,
@@ -30344,7 +30365,7 @@ var Spotlight = forwardRef85(
30344
30365
  () => `ods-spotlight-${Math.random().toString(36).slice(2, 9)}`,
30345
30366
  []
30346
30367
  );
30347
- const measure = useCallback40(() => {
30368
+ const measure = useCallback41(() => {
30348
30369
  if (!open) return;
30349
30370
  const el = target.current;
30350
30371
  if (!el) return;
@@ -30515,7 +30536,7 @@ Stat.displayName = "Stat";
30515
30536
  import { motion as motion25 } from "framer-motion";
30516
30537
  import {
30517
30538
  forwardRef as forwardRef87,
30518
- useCallback as useCallback41,
30539
+ useCallback as useCallback42,
30519
30540
  useId as useId50,
30520
30541
  useMemo as useMemo32,
30521
30542
  useState as useState61
@@ -30560,7 +30581,7 @@ var StatusTiles = forwardRef87(
30560
30581
  [data, max]
30561
30582
  );
30562
30583
  const [hoveredIdx, setHoveredIdx] = useState61(null);
30563
- const fire = useCallback41(
30584
+ const fire = useCallback42(
30564
30585
  (idx) => {
30565
30586
  setHoveredIdx(idx);
30566
30587
  if (idx === null) {
@@ -30572,7 +30593,7 @@ var StatusTiles = forwardRef87(
30572
30593
  },
30573
30594
  [onTileHover, visible]
30574
30595
  );
30575
- const handleKey = useCallback41(
30596
+ const handleKey = useCallback42(
30576
30597
  (e, idx) => {
30577
30598
  if (!onTileClick) return;
30578
30599
  if (e.key === "Enter" || e.key === " ") {
@@ -30658,7 +30679,7 @@ StatusTiles.displayName = "StatusTiles";
30658
30679
  import { motion as motion26 } from "framer-motion";
30659
30680
  import {
30660
30681
  forwardRef as forwardRef88,
30661
- useCallback as useCallback42,
30682
+ useCallback as useCallback43,
30662
30683
  useId as useId51,
30663
30684
  useMemo as useMemo33,
30664
30685
  useState as useState62
@@ -30858,21 +30879,21 @@ var Sankey = forwardRef88(function Sankey2({
30858
30879
  }, [links, layoutNodes, nodeWidth, scale]);
30859
30880
  const [hoveredNode, setHoveredNode] = useState62(null);
30860
30881
  const [hoveredLink, setHoveredLink] = useState62(null);
30861
- const fireNode = useCallback42(
30882
+ const fireNode = useCallback43(
30862
30883
  (n) => {
30863
30884
  setHoveredNode(n);
30864
30885
  onNodeHover?.(n);
30865
30886
  },
30866
30887
  [onNodeHover]
30867
30888
  );
30868
- const fireLink = useCallback42(
30889
+ const fireLink = useCallback43(
30869
30890
  (l) => {
30870
30891
  setHoveredLink(l);
30871
30892
  onLinkHover?.(l);
30872
30893
  },
30873
30894
  [onLinkHover]
30874
30895
  );
30875
- const handleNodeKey = useCallback42(
30896
+ const handleNodeKey = useCallback43(
30876
30897
  (e, n) => {
30877
30898
  if (!onNodeClick) return;
30878
30899
  if (e.key === "Enter" || e.key === " ") {
@@ -31017,7 +31038,7 @@ Sankey.displayName = "Sankey";
31017
31038
  // src/components/Table/Table.tsx
31018
31039
  import {
31019
31040
  forwardRef as forwardRef89,
31020
- useCallback as useCallback43,
31041
+ useCallback as useCallback44,
31021
31042
  useState as useState63
31022
31043
  } from "react";
31023
31044
  import {
@@ -31044,7 +31065,7 @@ function TableInner({
31044
31065
  "aria-label": ariaLabel = "Data table",
31045
31066
  ...rest
31046
31067
  }, ref) {
31047
- const handleSort = useCallback43(
31068
+ const handleSort = useCallback44(
31048
31069
  (key) => {
31049
31070
  if (!onSort) return;
31050
31071
  const col = columns.find((c) => c.key === key);
@@ -31054,7 +31075,7 @@ function TableInner({
31054
31075
  },
31055
31076
  [columns, onSort, sortKey, sortDirection]
31056
31077
  );
31057
- const handleSelectAll = useCallback43(() => {
31078
+ const handleSelectAll = useCallback44(() => {
31058
31079
  if (!onSelectionChange) return;
31059
31080
  const allSelected = selectedRows?.size === data.length;
31060
31081
  if (allSelected) {
@@ -31063,7 +31084,7 @@ function TableInner({
31063
31084
  onSelectionChange(new Set(data.map((_, i) => i)));
31064
31085
  }
31065
31086
  }, [data, onSelectionChange, selectedRows]);
31066
- const handleSelectRow = useCallback43(
31087
+ const handleSelectRow = useCallback44(
31067
31088
  (index) => {
31068
31089
  if (!onSelectionChange || !selectedRows) return;
31069
31090
  const next = new Set(selectedRows);
@@ -31636,7 +31657,7 @@ Timeline.displayName = "Timeline";
31636
31657
  import {
31637
31658
  forwardRef as forwardRef93,
31638
31659
  Fragment as Fragment56,
31639
- useCallback as useCallback44,
31660
+ useCallback as useCallback45,
31640
31661
  useEffect as useEffect51,
31641
31662
  useId as useId54,
31642
31663
  useRef as useRef44,
@@ -31694,7 +31715,7 @@ var TimePicker = forwardRef93(
31694
31715
  null
31695
31716
  );
31696
31717
  const draftRef = useRef44(null);
31697
- const setDraftBoth = useCallback44(
31718
+ const setDraftBoth = useCallback45(
31698
31719
  (next) => {
31699
31720
  draftRef.current = next;
31700
31721
  setDraft(next);
@@ -31718,7 +31739,7 @@ var TimePicker = forwardRef93(
31718
31739
  const minutesRef = useRef44(null);
31719
31740
  const secondsRef = useRef44(null);
31720
31741
  const refOf = (s) => s === "hours" ? hoursRef : s === "minutes" ? minutesRef : secondsRef;
31721
- const commit = useCallback44(
31742
+ const commit = useCallback45(
31722
31743
  (seg, n) => {
31723
31744
  const base = valueRef.current;
31724
31745
  const next = { ...base, [seg]: clampSeg(seg, n, use24h) };
@@ -31750,13 +31771,13 @@ var TimePicker = forwardRef93(
31750
31771
  valueRef.current = next;
31751
31772
  onChange?.(next);
31752
31773
  };
31753
- const clearCommitTimer = useCallback44(() => {
31774
+ const clearCommitTimer = useCallback45(() => {
31754
31775
  if (commitTimerRef.current != null) {
31755
31776
  clearTimeout(commitTimerRef.current);
31756
31777
  commitTimerRef.current = null;
31757
31778
  }
31758
31779
  }, []);
31759
- const commitDraft = useCallback44(
31780
+ const commitDraft = useCallback45(
31760
31781
  (seg, digits) => {
31761
31782
  clearCommitTimer();
31762
31783
  const n = parseInt(digits || "0", 10);
@@ -31768,11 +31789,11 @@ var TimePicker = forwardRef93(
31768
31789
  },
31769
31790
  [clearCommitTimer, commit, use24h, setDraftBoth]
31770
31791
  );
31771
- const flushDraft = useCallback44(() => {
31792
+ const flushDraft = useCallback45(() => {
31772
31793
  const d = draftRef.current;
31773
31794
  if (d) commitDraft(d.seg, d.digits);
31774
31795
  }, [commitDraft]);
31775
- const focusSegment = useCallback44(
31796
+ const focusSegment = useCallback45(
31776
31797
  (seg) => {
31777
31798
  const d = draftRef.current;
31778
31799
  if (d && d.seg !== seg) commitDraft(d.seg, d.digits);
@@ -32055,7 +32076,7 @@ TimePicker.displayName = "TimePicker";
32055
32076
  // src/components/TimezonePicker/TimezonePicker.tsx
32056
32077
  import {
32057
32078
  forwardRef as forwardRef94,
32058
- useCallback as useCallback45,
32079
+ useCallback as useCallback46,
32059
32080
  useEffect as useEffect52,
32060
32081
  useId as useId55,
32061
32082
  useMemo as useMemo34,
@@ -32160,7 +32181,7 @@ var TimezonePicker = forwardRef94(
32160
32181
  );
32161
32182
  active?.scrollIntoView?.({ block: "nearest" });
32162
32183
  }, [activeIndex, open]);
32163
- const select = useCallback45(
32184
+ const select = useCallback46(
32164
32185
  (iana) => {
32165
32186
  onChange?.(iana);
32166
32187
  setOpen(false);
@@ -32169,7 +32190,7 @@ var TimezonePicker = forwardRef94(
32169
32190
  },
32170
32191
  [onChange]
32171
32192
  );
32172
- const handlePopoverKey = useCallback45(
32193
+ const handlePopoverKey = useCallback46(
32173
32194
  (e) => {
32174
32195
  if (e.key === "ArrowDown") {
32175
32196
  e.preventDefault();
@@ -32365,7 +32386,7 @@ TimezonePicker.displayName = "TimezonePicker";
32365
32386
  import { AnimatePresence as AnimatePresence18, motion as motion28 } from "framer-motion";
32366
32387
  import {
32367
32388
  createContext as createContext3,
32368
- useCallback as useCallback46,
32389
+ useCallback as useCallback47,
32369
32390
  useContext as useContext4,
32370
32391
  useMemo as useMemo35,
32371
32392
  useRef as useRef46,
@@ -32622,7 +32643,7 @@ function ToastProvider({
32622
32643
  const [toasts, setToasts] = useState67([]);
32623
32644
  const timers = useRef46(/* @__PURE__ */ new Map());
32624
32645
  const idCounter2 = useRef46(0);
32625
- const dismiss = useCallback46((id) => {
32646
+ const dismiss = useCallback47((id) => {
32626
32647
  setToasts((prev) => prev.filter((t) => t.id !== id));
32627
32648
  const timer = timers.current.get(id);
32628
32649
  if (timer) {
@@ -32630,7 +32651,7 @@ function ToastProvider({
32630
32651
  timers.current.delete(id);
32631
32652
  }
32632
32653
  }, []);
32633
- const dismissAll = useCallback46((position) => {
32654
+ const dismissAll = useCallback47((position) => {
32634
32655
  setToasts((prev) => {
32635
32656
  const remaining = position ? prev.filter((t) => t.position !== position) : [];
32636
32657
  for (const t of prev) {
@@ -32645,7 +32666,7 @@ function ToastProvider({
32645
32666
  return remaining;
32646
32667
  });
32647
32668
  }, []);
32648
- const toast = useCallback46(
32669
+ const toast = useCallback47(
32649
32670
  (options2) => {
32650
32671
  const id = `toast-${++idCounter2.current}`;
32651
32672
  const item = {
@@ -32720,7 +32741,7 @@ function useToast() {
32720
32741
 
32721
32742
  // src/components/Toggle/Toggle.tsx
32722
32743
  import {
32723
- useCallback as useCallback47,
32744
+ useCallback as useCallback48,
32724
32745
  useId as useId56,
32725
32746
  useRef as useRef47
32726
32747
  } from "react";
@@ -32751,7 +32772,7 @@ function Toggle({
32751
32772
  const groupLabelledBy = ariaLabelledBy ?? labelId;
32752
32773
  const groupAriaLabel = !groupLabelledBy ? ariaLabel ?? "Toggle group" : void 0;
32753
32774
  const buttonRefs = useRef47([]);
32754
- const findNextEnabled = useCallback47(
32775
+ const findNextEnabled = useCallback48(
32755
32776
  (from, dir) => {
32756
32777
  if (options2.length === 0) return -1;
32757
32778
  let i = from;
@@ -32764,11 +32785,11 @@ function Toggle({
32764
32785
  },
32765
32786
  [options2, disabled]
32766
32787
  );
32767
- const focusIndex = useCallback47((i) => {
32788
+ const focusIndex = useCallback48((i) => {
32768
32789
  if (i < 0) return;
32769
32790
  buttonRefs.current[i]?.focus();
32770
32791
  }, []);
32771
- const handleKey = useCallback47(
32792
+ const handleKey = useCallback48(
32772
32793
  (e, idx) => {
32773
32794
  if (e.key === "ArrowRight" || e.key === "ArrowDown") {
32774
32795
  e.preventDefault();
@@ -33136,7 +33157,7 @@ function TopBar({
33136
33157
  import { AnimatePresence as AnimatePresence19, motion as motion29 } from "framer-motion";
33137
33158
  import {
33138
33159
  forwardRef as forwardRef96,
33139
- useCallback as useCallback48,
33160
+ useCallback as useCallback49,
33140
33161
  useId as useId58,
33141
33162
  useState as useState68
33142
33163
  } from "react";
@@ -33188,7 +33209,7 @@ var TraceStep = forwardRef96(
33188
33209
  const isControlled = controlledOpen !== void 0;
33189
33210
  const open = isControlled ? controlledOpen : uncontrolledOpen;
33190
33211
  const canExpand = !!children;
33191
- const toggle = useCallback48(() => {
33212
+ const toggle = useCallback49(() => {
33192
33213
  if (!canExpand) return;
33193
33214
  const next = !open;
33194
33215
  if (!isControlled) setUncontrolledOpen(next);
@@ -33543,10 +33564,10 @@ var UserCard = forwardRef98(function UserCard2({
33543
33564
  UserCard.displayName = "UserCard";
33544
33565
 
33545
33566
  // src/components/WorkflowEditor/WorkflowEditor.tsx
33546
- import { useCallback as useCallback50, useMemo as useMemo37, useState as useState69 } from "react";
33567
+ import { useCallback as useCallback51, useMemo as useMemo37, useState as useState69 } from "react";
33547
33568
 
33548
33569
  // src/hooks/useWorkflow.ts
33549
- import { useCallback as useCallback49, useMemo as useMemo36, useReducer } from "react";
33570
+ import { useCallback as useCallback50, useMemo as useMemo36, useReducer } from "react";
33550
33571
 
33551
33572
  // src/workflow/types.ts
33552
33573
  var types_exports = {};
@@ -34060,11 +34081,11 @@ function useWorkflow(options2 = {}) {
34060
34081
  []
34061
34082
  );
34062
34083
  const [workflow, dispatch] = useReducer(reducer, initial);
34063
- const addNode = useCallback49(
34084
+ const addNode = useCallback50(
34064
34085
  (node) => dispatch({ type: "ADD_NODE", payload: node }),
34065
34086
  []
34066
34087
  );
34067
- const createNode = useCallback49(
34088
+ const createNode = useCallback50(
34068
34089
  (partial) => {
34069
34090
  const id = partial.id ?? genId("node");
34070
34091
  const ports = partial.ports ?? {
@@ -34113,27 +34134,27 @@ function useWorkflow(options2 = {}) {
34113
34134
  },
34114
34135
  []
34115
34136
  );
34116
- const updateNode = useCallback49(
34137
+ const updateNode = useCallback50(
34117
34138
  (id, updates) => dispatch({ type: "UPDATE_NODE", payload: { id, updates } }),
34118
34139
  []
34119
34140
  );
34120
- const deleteNode = useCallback49(
34141
+ const deleteNode = useCallback50(
34121
34142
  (id) => dispatch({ type: "DELETE_NODE", payload: id }),
34122
34143
  []
34123
34144
  );
34124
- const deleteNodes = useCallback49(
34145
+ const deleteNodes = useCallback50(
34125
34146
  (ids) => dispatch({ type: "DELETE_NODES", payload: ids }),
34126
34147
  []
34127
34148
  );
34128
- const replaceNodes = useCallback49(
34149
+ const replaceNodes = useCallback50(
34129
34150
  (nodes) => dispatch({ type: "REPLACE_NODES", payload: nodes }),
34130
34151
  []
34131
34152
  );
34132
- const addEdge = useCallback49(
34153
+ const addEdge = useCallback50(
34133
34154
  (edge) => dispatch({ type: "ADD_EDGE", payload: edge }),
34134
34155
  []
34135
34156
  );
34136
- const createEdge = useCallback49(
34157
+ const createEdge = useCallback50(
34137
34158
  (source, sourcePort, target, targetPort) => {
34138
34159
  const edge = {
34139
34160
  id: genId("edge"),
@@ -34151,20 +34172,20 @@ function useWorkflow(options2 = {}) {
34151
34172
  },
34152
34173
  []
34153
34174
  );
34154
- const deleteEdge = useCallback49(
34175
+ const deleteEdge = useCallback50(
34155
34176
  (id) => dispatch({ type: "DELETE_EDGE", payload: id }),
34156
34177
  []
34157
34178
  );
34158
- const replaceEdges = useCallback49(
34179
+ const replaceEdges = useCallback50(
34159
34180
  (edges) => dispatch({ type: "REPLACE_EDGES", payload: edges }),
34160
34181
  []
34161
34182
  );
34162
- const startConnecting = useCallback49(
34183
+ const startConnecting = useCallback50(
34163
34184
  (nodeId, portId, portType) => dispatch({ type: "START_CONNECTING", payload: { nodeId, portId, portType } }),
34164
34185
  []
34165
34186
  );
34166
- const endConnecting = useCallback49(() => dispatch({ type: "END_CONNECTING" }), []);
34167
- const selectNode = useCallback49(
34187
+ const endConnecting = useCallback50(() => dispatch({ type: "END_CONNECTING" }), []);
34188
+ const selectNode = useCallback50(
34168
34189
  (id, multi = false) => {
34169
34190
  if (multi) {
34170
34191
  const current = workflow.canvas.selectedNodes;
@@ -34176,36 +34197,36 @@ function useWorkflow(options2 = {}) {
34176
34197
  },
34177
34198
  [workflow.canvas.selectedNodes]
34178
34199
  );
34179
- const selectNodes = useCallback49(
34200
+ const selectNodes = useCallback50(
34180
34201
  (ids) => dispatch({ type: "SELECT_NODES", payload: ids }),
34181
34202
  []
34182
34203
  );
34183
- const selectEdge = useCallback49(
34204
+ const selectEdge = useCallback50(
34184
34205
  (id) => dispatch({ type: "SELECT_EDGE", payload: id }),
34185
34206
  []
34186
34207
  );
34187
- const deselectAll = useCallback49(() => dispatch({ type: "DESELECT_ALL" }), []);
34188
- const zoomIn = useCallback49(() => {
34208
+ const deselectAll = useCallback50(() => dispatch({ type: "DESELECT_ALL" }), []);
34209
+ const zoomIn = useCallback50(() => {
34189
34210
  const z = Math.min(workflow.canvas.viewport.zoom * 1.2, 2);
34190
34211
  dispatch({ type: "UPDATE_VIEWPORT", payload: { zoom: z } });
34191
34212
  }, [workflow.canvas.viewport.zoom]);
34192
- const zoomOut = useCallback49(() => {
34213
+ const zoomOut = useCallback50(() => {
34193
34214
  const z = Math.max(workflow.canvas.viewport.zoom / 1.2, 0.25);
34194
34215
  dispatch({ type: "UPDATE_VIEWPORT", payload: { zoom: z } });
34195
34216
  }, [workflow.canvas.viewport.zoom]);
34196
- const resetViewport = useCallback49(
34217
+ const resetViewport = useCallback50(
34197
34218
  () => dispatch({ type: "UPDATE_VIEWPORT", payload: { x: 0, y: 0, zoom: 1 } }),
34198
34219
  []
34199
34220
  );
34200
- const setViewport = useCallback49(
34221
+ const setViewport = useCallback50(
34201
34222
  (viewport) => dispatch({ type: "UPDATE_VIEWPORT", payload: viewport }),
34202
34223
  []
34203
34224
  );
34204
- const undo = useCallback49(() => dispatch({ type: "UNDO" }), []);
34205
- const redo = useCallback49(() => dispatch({ type: "REDO" }), []);
34225
+ const undo = useCallback50(() => dispatch({ type: "UNDO" }), []);
34226
+ const redo = useCallback50(() => dispatch({ type: "REDO" }), []);
34206
34227
  const canUndo = workflow.canvas.history.past.length > 0;
34207
34228
  const canRedo = workflow.canvas.history.future.length > 0;
34208
- const validate = useCallback49(() => workflow.validation, [workflow.validation]);
34229
+ const validate = useCallback50(() => workflow.validation, [workflow.validation]);
34209
34230
  return {
34210
34231
  workflow,
34211
34232
  dispatch,
@@ -34319,27 +34340,27 @@ function WorkflowEditor({
34319
34340
  const isDrawerOpen = controlledDrawerOpen ?? uncontrolledDrawer;
34320
34341
  const isHistoryOpen = controlledHistoryOpen ?? uncontrolledHistory;
34321
34342
  const isDebugOpen = controlledDebugOpen ?? uncontrolledDebug;
34322
- const toggleLock = useCallback50(() => {
34343
+ const toggleLock = useCallback51(() => {
34323
34344
  const next = !isLockMode;
34324
34345
  if (controlledLockMode === void 0) setUncontrolledLock(next);
34325
34346
  onToggleLockMode?.(next);
34326
34347
  }, [isLockMode, controlledLockMode, onToggleLockMode]);
34327
- const toggleDrawer = useCallback50(() => {
34348
+ const toggleDrawer = useCallback51(() => {
34328
34349
  const next = !isDrawerOpen;
34329
34350
  if (controlledDrawerOpen === void 0) setUncontrolledDrawer(next);
34330
34351
  onToggleDrawer?.(next);
34331
34352
  }, [isDrawerOpen, controlledDrawerOpen, onToggleDrawer]);
34332
- const toggleHistory = useCallback50(() => {
34353
+ const toggleHistory = useCallback51(() => {
34333
34354
  const next = !isHistoryOpen;
34334
34355
  if (controlledHistoryOpen === void 0) setUncontrolledHistory(next);
34335
34356
  onToggleHistory?.(next);
34336
34357
  }, [isHistoryOpen, controlledHistoryOpen, onToggleHistory]);
34337
- const toggleDebug = useCallback50(() => {
34358
+ const toggleDebug = useCallback51(() => {
34338
34359
  const next = !isDebugOpen;
34339
34360
  if (controlledDebugOpen === void 0) setUncontrolledDebug(next);
34340
34361
  onToggleDebug?.(next);
34341
34362
  }, [isDebugOpen, controlledDebugOpen, onToggleDebug]);
34342
- const handleReset = useCallback50(() => {
34363
+ const handleReset = useCallback51(() => {
34343
34364
  if (onReset) onReset();
34344
34365
  else dispatch({ type: "RESET" });
34345
34366
  }, [onReset, dispatch]);
@@ -34348,7 +34369,7 @@ function WorkflowEditor({
34348
34369
  [workflow.canvas.nodes]
34349
34370
  );
34350
34371
  const nextEdges = useMemo37(() => workflow.canvas.edges.map(toNextEdge), [workflow.canvas.edges]);
34351
- const onNodesChange = useCallback50(
34372
+ const onNodesChange = useCallback51(
34352
34373
  (changes) => {
34353
34374
  const reduced = applyNodeChanges(
34354
34375
  nextNodes,
@@ -34389,7 +34410,7 @@ function WorkflowEditor({
34389
34410
  },
34390
34411
  [nextNodes, workflow.canvas.nodes, wf, onNodeSelect]
34391
34412
  );
34392
- const onEdgesChange = useCallback50(
34413
+ const onEdgesChange = useCallback51(
34393
34414
  (changes) => {
34394
34415
  const reduced = applyEdgeChanges(nextEdges, changes);
34395
34416
  const byId = new Map(reduced.map((e) => [e.id, e]));
@@ -34399,18 +34420,18 @@ function WorkflowEditor({
34399
34420
  },
34400
34421
  [nextEdges, workflow.canvas.edges, wf]
34401
34422
  );
34402
- const onConnect = useCallback50(
34423
+ const onConnect = useCallback51(
34403
34424
  (c) => {
34404
34425
  wf.createEdge(c.source, c.sourceHandle ?? "default", c.target, c.targetHandle ?? "default");
34405
34426
  },
34406
34427
  [wf]
34407
34428
  );
34408
34429
  const [canvasSize, setCanvasSize] = useState69({ w: 0, h: 0 });
34409
- const handleCanvasRef = useCallback50((node) => {
34430
+ const handleCanvasRef = useCallback51((node) => {
34410
34431
  if (!node) return;
34411
34432
  setCanvasSize({ w: node.clientWidth, h: node.clientHeight });
34412
34433
  }, []);
34413
- const fitToView = useCallback50(() => {
34434
+ const fitToView = useCallback51(() => {
34414
34435
  const nodes = workflow.canvas.nodes;
34415
34436
  if (nodes.length === 0) return;
34416
34437
  let minX = Infinity;
@@ -35050,7 +35071,7 @@ function WorkflowHeaderExpanded({
35050
35071
  }
35051
35072
 
35052
35073
  // src/hooks/useBanner.ts
35053
- import { useCallback as useCallback51, useEffect as useEffect54, useRef as useRef48, useState as useState71 } from "react";
35074
+ import { useCallback as useCallback52, useEffect as useEffect54, useRef as useRef48, useState as useState71 } from "react";
35054
35075
  function useBanner(options2 = {}) {
35055
35076
  const { defaultOpen = false, autoDismissAfter, onDismiss } = options2;
35056
35077
  const [open, setOpen] = useState71(defaultOpen);
@@ -35059,20 +35080,20 @@ function useBanner(options2 = {}) {
35059
35080
  useEffect54(() => {
35060
35081
  onDismissRef.current = onDismiss;
35061
35082
  }, [onDismiss]);
35062
- const clearTimer = useCallback51(() => {
35083
+ const clearTimer = useCallback52(() => {
35063
35084
  if (timerRef.current !== null) {
35064
35085
  clearTimeout(timerRef.current);
35065
35086
  timerRef.current = null;
35066
35087
  }
35067
35088
  }, []);
35068
- const hide = useCallback51(() => {
35089
+ const hide = useCallback52(() => {
35069
35090
  clearTimer();
35070
35091
  setOpen((wasOpen) => {
35071
35092
  if (wasOpen) onDismissRef.current?.();
35072
35093
  return false;
35073
35094
  });
35074
35095
  }, [clearTimer]);
35075
- const show = useCallback51(() => {
35096
+ const show = useCallback52(() => {
35076
35097
  clearTimer();
35077
35098
  setOpen(true);
35078
35099
  if (typeof autoDismissAfter === "number" && Number.isFinite(autoDismissAfter) && autoDismissAfter > 0) {
@@ -35083,7 +35104,7 @@ function useBanner(options2 = {}) {
35083
35104
  }, autoDismissAfter);
35084
35105
  }
35085
35106
  }, [autoDismissAfter, clearTimer]);
35086
- const toggle = useCallback51(() => {
35107
+ const toggle = useCallback52(() => {
35087
35108
  if (open) hide();
35088
35109
  else show();
35089
35110
  }, [open, show, hide]);
@@ -35098,7 +35119,7 @@ function useBanner(options2 = {}) {
35098
35119
  }
35099
35120
 
35100
35121
  // src/hooks/useCallout.ts
35101
- import { useCallback as useCallback52, useEffect as useEffect55, useState as useState72 } from "react";
35122
+ import { useCallback as useCallback53, useEffect as useEffect55, useState as useState72 } from "react";
35102
35123
  var STORAGE_PREFIX = "ods:callout:dismissed:";
35103
35124
  function readPersisted(key) {
35104
35125
  if (!key || typeof window === "undefined") return false;
@@ -35127,7 +35148,7 @@ function useCallout(options2 = {}) {
35127
35148
  setOpen(false);
35128
35149
  }
35129
35150
  }, []);
35130
- const dismiss = useCallback52(() => {
35151
+ const dismiss = useCallback53(() => {
35131
35152
  setOpen((wasOpen) => {
35132
35153
  if (wasOpen) {
35133
35154
  writePersisted(persistKey, true);
@@ -35136,10 +35157,10 @@ function useCallout(options2 = {}) {
35136
35157
  return false;
35137
35158
  });
35138
35159
  }, [persistKey, onDismiss]);
35139
- const show = useCallback52(() => {
35160
+ const show = useCallback53(() => {
35140
35161
  setOpen(true);
35141
35162
  }, []);
35142
- const toggle = useCallback52(() => {
35163
+ const toggle = useCallback53(() => {
35143
35164
  setOpen((prev) => {
35144
35165
  const next = !prev;
35145
35166
  if (!next) {
@@ -35149,7 +35170,7 @@ function useCallout(options2 = {}) {
35149
35170
  return next;
35150
35171
  });
35151
35172
  }, [persistKey, onDismiss]);
35152
- const reset = useCallback52(() => {
35173
+ const reset = useCallback53(() => {
35153
35174
  writePersisted(persistKey, false);
35154
35175
  setOpen(true);
35155
35176
  }, [persistKey]);
@@ -35222,7 +35243,7 @@ function breakpointMinWidth(name) {
35222
35243
  }
35223
35244
 
35224
35245
  // src/hooks/useRating.ts
35225
- import { useCallback as useCallback53, useState as useState73 } from "react";
35246
+ import { useCallback as useCallback54, useState as useState73 } from "react";
35226
35247
  function useRating({
35227
35248
  value: controlled,
35228
35249
  defaultValue = 0,
@@ -35233,11 +35254,11 @@ function useRating({
35233
35254
  const [internal, setInternal] = useState73(defaultValue);
35234
35255
  const value = controlled ?? internal;
35235
35256
  const isControlled = controlled !== void 0;
35236
- const clamp = useCallback53(
35257
+ const clamp = useCallback54(
35237
35258
  (v) => Math.max(0, Math.min(max, v)),
35238
35259
  [max]
35239
35260
  );
35240
- const set = useCallback53(
35261
+ const set = useCallback54(
35241
35262
  (next) => {
35242
35263
  const clamped = clamp(next);
35243
35264
  if (!isControlled) setInternal(clamped);
@@ -35262,7 +35283,7 @@ function useBinaryRating({
35262
35283
  const [internal, setInternal] = useState73(defaultValue);
35263
35284
  const value = controlled ?? internal;
35264
35285
  const isControlled = controlled !== void 0;
35265
- const set = useCallback53(
35286
+ const set = useCallback54(
35266
35287
  (next) => {
35267
35288
  if (!isControlled) setInternal(next);
35268
35289
  onChange?.(next);
@@ -35281,7 +35302,7 @@ function useBinaryRating({
35281
35302
  }
35282
35303
 
35283
35304
  // src/hooks/useTimeline.ts
35284
- import { useCallback as useCallback54, useState as useState74 } from "react";
35305
+ import { useCallback as useCallback55, useState as useState74 } from "react";
35285
35306
  function useTimeline({
35286
35307
  items: controlled,
35287
35308
  defaultItems = [],
@@ -35290,21 +35311,21 @@ function useTimeline({
35290
35311
  const [internal, setInternal] = useState74(defaultItems);
35291
35312
  const items = controlled ?? internal;
35292
35313
  const isControlled = controlled !== void 0;
35293
- const commit = useCallback54(
35314
+ const commit = useCallback55(
35294
35315
  (next) => {
35295
35316
  if (!isControlled) setInternal(next);
35296
35317
  onChange?.(next);
35297
35318
  },
35298
35319
  [isControlled, onChange]
35299
35320
  );
35300
- const add = useCallback54(
35321
+ const add = useCallback55(
35301
35322
  (item) => {
35302
35323
  if (items.some((i) => i.id === item.id)) return;
35303
35324
  commit([...items, item]);
35304
35325
  },
35305
35326
  [items, commit]
35306
35327
  );
35307
- const insert = useCallback54(
35328
+ const insert = useCallback55(
35308
35329
  (index, item) => {
35309
35330
  if (items.some((i) => i.id === item.id)) return;
35310
35331
  const at = Math.max(0, Math.min(items.length, index));
@@ -35314,7 +35335,7 @@ function useTimeline({
35314
35335
  },
35315
35336
  [items, commit]
35316
35337
  );
35317
- const remove = useCallback54(
35338
+ const remove = useCallback55(
35318
35339
  (id) => {
35319
35340
  const next = items.filter((i) => i.id !== id);
35320
35341
  if (next.length === items.length) return;
@@ -35322,7 +35343,7 @@ function useTimeline({
35322
35343
  },
35323
35344
  [items, commit]
35324
35345
  );
35325
- const update = useCallback54(
35346
+ const update = useCallback55(
35326
35347
  (id, patch) => {
35327
35348
  let changed = false;
35328
35349
  const next = items.map((i) => {
@@ -35347,7 +35368,7 @@ function useTimeline({
35347
35368
  }
35348
35369
 
35349
35370
  // src/hooks/useTraceTimeline.ts
35350
- import { useCallback as useCallback55, useRef as useRef49, useState as useState75 } from "react";
35371
+ import { useCallback as useCallback56, useRef as useRef49, useState as useState75 } from "react";
35351
35372
  var GLOBAL_SEQ = 0;
35352
35373
  var generateId = () => `ods-trace-${Date.now().toString(36)}-${(GLOBAL_SEQ++).toString(36)}`;
35353
35374
  function useTraceTimeline({
@@ -35360,7 +35381,7 @@ function useTraceTimeline({
35360
35381
  const isControlled = controlled !== void 0;
35361
35382
  const stepsRef = useRef49(steps);
35362
35383
  stepsRef.current = steps;
35363
- const commit = useCallback55(
35384
+ const commit = useCallback56(
35364
35385
  (next) => {
35365
35386
  stepsRef.current = next;
35366
35387
  if (!isControlled) setInternal(next);
@@ -35368,7 +35389,7 @@ function useTraceTimeline({
35368
35389
  },
35369
35390
  [isControlled, onChange]
35370
35391
  );
35371
- const start = useCallback55(
35392
+ const start = useCallback56(
35372
35393
  (input) => {
35373
35394
  const id = input.id ?? generateId();
35374
35395
  const record = {
@@ -35388,7 +35409,7 @@ function useTraceTimeline({
35388
35409
  },
35389
35410
  [commit]
35390
35411
  );
35391
- const update = useCallback55(
35412
+ const update = useCallback56(
35392
35413
  (id, patch) => {
35393
35414
  let changed = false;
35394
35415
  const next = stepsRef.current.map((s) => {
@@ -35400,19 +35421,19 @@ function useTraceTimeline({
35400
35421
  },
35401
35422
  [commit]
35402
35423
  );
35403
- const complete = useCallback55(
35424
+ const complete = useCallback56(
35404
35425
  (id, patch = {}) => {
35405
35426
  update(id, { ...patch, status: "success" });
35406
35427
  },
35407
35428
  [update]
35408
35429
  );
35409
- const fail = useCallback55(
35430
+ const fail = useCallback56(
35410
35431
  (id, patch = {}) => {
35411
35432
  update(id, { ...patch, status: "failed" });
35412
35433
  },
35413
35434
  [update]
35414
35435
  );
35415
- const remove = useCallback55(
35436
+ const remove = useCallback56(
35416
35437
  (id) => {
35417
35438
  const next = stepsRef.current.filter((s) => s.id !== id);
35418
35439
  if (next.length === stepsRef.current.length) return;