@flytedan/flytebot-design-system 0.12.5 → 0.12.6

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.cjs CHANGED
@@ -253,6 +253,11 @@ function Button({
253
253
  );
254
254
  }
255
255
 
256
+ // src/components/actions/overflowRowContext.ts
257
+ var React = __toESM(require("react"), 1);
258
+ var OverflowRowContext = React.createContext(false);
259
+ var useOverflowRow = () => React.useContext(OverflowRowContext);
260
+
256
261
  // src/components/actions/IconButton.tsx
257
262
  var import_jsx_runtime2 = require("react/jsx-runtime");
258
263
  function IconButton({
@@ -266,19 +271,24 @@ function IconButton({
266
271
  className = "",
267
272
  ...rest
268
273
  }) {
274
+ const overflowRow = useOverflowRow();
269
275
  const cls = [
270
276
  "fd-btn-icon",
271
277
  variant === "outline" ? "fd-btn-icon-outline" : variant === "solid" ? "fd-btn-icon-solid" : "",
272
278
  tone !== "neutral" ? "is-" + tone : "",
273
279
  size === "sm" ? "fd-btn-icon-sm" : size === "lg" ? "fd-btn-icon-lg" : "",
274
280
  round ? "fd-btn-icon-round" : "",
281
+ overflowRow ? "fd-btn-icon-row" : "",
275
282
  className
276
283
  ].filter(Boolean).join(" ");
277
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: cls, "aria-label": label, title: label, disabled, ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "ph ph-" + icon, "aria-hidden": "true" }) });
284
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: cls, "aria-label": label, title: label, disabled, ...rest, children: [
285
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", { className: "ph ph-" + icon, "aria-hidden": "true" }),
286
+ overflowRow ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "fd-btn-icon-row-label", children: label }) : null
287
+ ] });
278
288
  }
279
289
 
280
290
  // src/components/actions/Popover.tsx
281
- var React = __toESM(require("react"), 1);
291
+ var React2 = __toESM(require("react"), 1);
282
292
  var import_react_dom = require("react-dom");
283
293
  var import_jsx_runtime3 = require("react/jsx-runtime");
284
294
  var MARGIN = 8;
@@ -310,12 +320,12 @@ function measureLayer(el) {
310
320
  function usePopoverPosition(open, anchorRef, opts) {
311
321
  const o = opts || {};
312
322
  const { side: wantSide, align } = parsePlacement(o.placement);
313
- const [pos, setPos] = React.useState(null);
314
- const posRef = React.useRef(null);
315
- const detachRef = React.useRef(o.onDetach);
323
+ const [pos, setPos] = React2.useState(null);
324
+ const posRef = React2.useRef(null);
325
+ const detachRef = React2.useRef(o.onDetach);
316
326
  detachRef.current = o.onDetach;
317
327
  const layerRef = o.layerRef;
318
- React.useLayoutEffect(() => {
328
+ React2.useLayoutEffect(() => {
319
329
  if (!open || !anchorRef || !anchorRef.current) {
320
330
  posRef.current = null;
321
331
  setPos(null);
@@ -390,8 +400,8 @@ var portal = (node) => {
390
400
  };
391
401
  var ROOT_LAYER = 0;
392
402
  var LAYER_STEP = 10;
393
- var LayerContext = React.createContext(ROOT_LAYER);
394
- var useLayer = () => React.useContext(LayerContext);
403
+ var LayerContext = React2.createContext(ROOT_LAYER);
404
+ var useLayer = () => React2.useContext(LayerContext);
395
405
  var useOverlayLayer = (base) => {
396
406
  const parent = useLayer();
397
407
  return parent === ROOT_LAYER ? base : parent + LAYER_STEP;
@@ -421,7 +431,7 @@ function Popover({
421
431
  footer,
422
432
  children
423
433
  }) {
424
- const ref = React.useRef(null);
434
+ const ref = React2.useRef(null);
425
435
  const pos = usePopoverPosition(!!open, anchorRef, {
426
436
  placement,
427
437
  offset,
@@ -433,9 +443,9 @@ function Popover({
433
443
  onDetach: onClose,
434
444
  layerRef: ref
435
445
  });
436
- const restore = React.useRef(null);
446
+ const restore = React2.useRef(null);
437
447
  const zIndex = useOverlayLayer(POPOVER_BASE);
438
- React.useEffect(() => {
448
+ React2.useEffect(() => {
439
449
  if (!open) return;
440
450
  restore.current = typeof document !== "undefined" ? document.activeElement : null;
441
451
  return () => {
@@ -447,7 +457,7 @@ function Popover({
447
457
  }
448
458
  };
449
459
  }, [open, returnFocus]);
450
- React.useEffect(() => {
460
+ React2.useEffect(() => {
451
461
  if (!open) return;
452
462
  const away = (e) => {
453
463
  if (!closeOnOutside) return;
@@ -521,12 +531,12 @@ function Popover({
521
531
  }
522
532
  var isItem = (it) => !!it && it.kind !== "separator" && it.kind !== "section" && it.kind !== "custom" && !it.disabled;
523
533
  function Menu({ items = [], onSelect, onClose, autoFocus = true, className = "", footer, header }) {
524
- const listRef = React.useRef(null);
525
- const [active, setActive] = React.useState(() => items.findIndex(isItem));
526
- const [openSub, setOpenSub] = React.useState(null);
527
- const subAnchor = React.useRef(null);
528
- const typed = React.useRef({ s: "", t: 0 });
529
- React.useEffect(() => {
534
+ const listRef = React2.useRef(null);
535
+ const [active, setActive] = React2.useState(() => items.findIndex(isItem));
536
+ const [openSub, setOpenSub] = React2.useState(null);
537
+ const subAnchor = React2.useRef(null);
538
+ const typed = React2.useRef({ s: "", t: 0 });
539
+ React2.useEffect(() => {
530
540
  if (autoFocus && listRef.current) listRef.current.focus({ preventScroll: true });
531
541
  }, [autoFocus]);
532
542
  const move = (dir) => {
@@ -588,7 +598,7 @@ function Menu({ items = [], onSelect, onClose, autoFocus = true, className = "",
588
598
  }
589
599
  };
590
600
  const sub = openSub != null ? items[openSub] : null;
591
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(React.Fragment, { children: [
601
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(React2.Fragment, { children: [
592
602
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "fd-menu-frame", children: [
593
603
  header != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "fd-menu-header", children: header }) : null,
594
604
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
@@ -702,9 +712,9 @@ function MenuButton({
702
712
  header,
703
713
  footer
704
714
  }) {
705
- const [open, setOpen] = React.useState(false);
706
- const ref = React.useRef(null);
707
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(React.Fragment, { children: [
715
+ const [open, setOpen] = React2.useState(false);
716
+ const ref = React2.useRef(null);
717
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(React2.Fragment, { children: [
708
718
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
709
719
  "button",
710
720
  {
@@ -797,7 +807,7 @@ function CardRow({ label, children, className = "" }) {
797
807
  }
798
808
 
799
809
  // src/components/surfaces/Collapsible.tsx
800
- var React2 = __toESM(require("react"), 1);
810
+ var React3 = __toESM(require("react"), 1);
801
811
  var import_jsx_runtime6 = require("react/jsx-runtime");
802
812
  function Collapsible({
803
813
  title,
@@ -811,7 +821,7 @@ function Collapsible({
811
821
  className = "",
812
822
  ...rest
813
823
  }) {
814
- const [internal, setInternal] = React2.useState(defaultOpen);
824
+ const [internal, setInternal] = React3.useState(defaultOpen);
815
825
  const isOpen = open === void 0 ? internal : open;
816
826
  const toggle = () => {
817
827
  if (open === void 0) setInternal(!isOpen);
@@ -832,19 +842,19 @@ function Collapsible({
832
842
  }
833
843
 
834
844
  // src/components/surfaces/Drawer.tsx
835
- var React3 = __toESM(require("react"), 1);
845
+ var React4 = __toESM(require("react"), 1);
836
846
  var import_react_dom2 = require("react-dom");
837
847
  var import_jsx_runtime7 = require("react/jsx-runtime");
838
848
  var DRAWER_BASE = 90;
839
849
  function Drawer({ open = true, title, onClose, footer, children, className = "", ...rest }) {
840
850
  const zIndex = useOverlayLayer(DRAWER_BASE);
841
- const [closing, setClosing] = React3.useState(false);
842
- const close = React3.useCallback(() => {
851
+ const [closing, setClosing] = React4.useState(false);
852
+ const close = React4.useCallback(() => {
843
853
  if (!onClose) return;
844
854
  setClosing(true);
845
855
  setTimeout(onClose, 210);
846
856
  }, [onClose]);
847
- React3.useEffect(() => {
857
+ React4.useEffect(() => {
848
858
  if (!open || !onClose) return;
849
859
  const h = (e) => {
850
860
  if (e.key === "Escape") close();
@@ -870,17 +880,17 @@ function Drawer({ open = true, title, onClose, footer, children, className = "",
870
880
  }
871
881
 
872
882
  // src/components/surfaces/Modal.tsx
873
- var React4 = __toESM(require("react"), 1);
883
+ var React5 = __toESM(require("react"), 1);
874
884
  var import_react_dom3 = require("react-dom");
875
885
  var import_jsx_runtime8 = require("react/jsx-runtime");
876
886
  function Modal({ open = true, title, description, onClose, footer, wide = false, children, className = "", ...rest }) {
877
- const [closing, setClosing] = React4.useState(false);
878
- const close = React4.useCallback(() => {
887
+ const [closing, setClosing] = React5.useState(false);
888
+ const close = React5.useCallback(() => {
879
889
  if (!onClose) return;
880
890
  setClosing(true);
881
891
  setTimeout(onClose, 190);
882
892
  }, [onClose]);
883
- React4.useEffect(() => {
893
+ React5.useEffect(() => {
884
894
  if (!open || !onClose) return;
885
895
  const h = (e) => {
886
896
  if (e.key === "Escape") close();
@@ -1107,13 +1117,13 @@ function Tabs({ tabs = [], value, onChange, className = "", ...rest }) {
1107
1117
  }
1108
1118
 
1109
1119
  // src/components/navigation/Topbar.tsx
1110
- var React5 = __toESM(require("react"), 1);
1120
+ var React6 = __toESM(require("react"), 1);
1111
1121
  var import_jsx_runtime16 = require("react/jsx-runtime");
1112
1122
  function useIsNarrow(breakpoint) {
1113
- const [narrow, setNarrow] = React5.useState(
1123
+ const [narrow, setNarrow] = React6.useState(
1114
1124
  () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
1115
1125
  );
1116
- React5.useEffect(() => {
1126
+ React6.useEffect(() => {
1117
1127
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1118
1128
  const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
1119
1129
  const apply = () => setNarrow(mq.matches);
@@ -1134,11 +1144,11 @@ function Topbar({
1134
1144
  ...rest
1135
1145
  }) {
1136
1146
  const narrow = useIsNarrow(overflowBreakpoint);
1137
- const [moreOpen, setMoreOpen] = React5.useState(false);
1138
- const moreRef = React5.useRef(null);
1147
+ const [moreOpen, setMoreOpen] = React6.useState(false);
1148
+ const moreRef = React6.useRef(null);
1139
1149
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("header", { className: ["fd-topbar", narrow ? "is-narrow" : "", className].filter(Boolean).join(" "), ...rest, children: [
1140
1150
  onMenu ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: "fd-btn-icon", "aria-label": "Menu", onClick: onMenu, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("i", { className: "ph ph-list" }) }) : null,
1141
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(React5.Fragment, { children: [
1151
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(React6.Fragment, { children: [
1142
1152
  i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("i", { className: "ph ph-caret-right", style: { fontSize: 11, opacity: 0.6 }, "aria-hidden": "true" }) : null,
1143
1153
  i === crumbs.length - 1 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "fd-crumb-current", children: c.label }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1144
1154
  "a",
@@ -1177,7 +1187,7 @@ function Topbar({
1177
1187
  padded: true,
1178
1188
  label: "More actions",
1179
1189
  className: "fd-topbar-overflow",
1180
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "fd-stack fd-topbar-overflow-list", children: overflowActions })
1190
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "fd-stack fd-topbar-overflow-list", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(OverflowRowContext.Provider, { value: true, children: overflowActions }) })
1181
1191
  }
1182
1192
  )
1183
1193
  ] }) : overflowActions : null,
@@ -1343,19 +1353,19 @@ function Toast({ title, children, tone = "success", onUndo, onDismiss, className
1343
1353
  }
1344
1354
 
1345
1355
  // src/components/feedback/Tooltip.tsx
1346
- var React6 = __toESM(require("react"), 1);
1356
+ var React7 = __toESM(require("react"), 1);
1347
1357
  var import_jsx_runtime24 = require("react/jsx-runtime");
1348
1358
  var TOOLTIP_BASE = 150;
1349
1359
  var CLOSE_DELAY_MS = 120;
1350
1360
  function Tooltip({ label, placement = "top", children, className = "" }) {
1351
- const anchorRef = React6.useRef(null);
1352
- const bubbleRef = React6.useRef(null);
1353
- const [reason, setReason] = React6.useState(null);
1354
- const closeTimer = React6.useRef(null);
1355
- const id = React6.useId();
1361
+ const anchorRef = React7.useRef(null);
1362
+ const bubbleRef = React7.useRef(null);
1363
+ const [reason, setReason] = React7.useState(null);
1364
+ const closeTimer = React7.useRef(null);
1365
+ const id = React7.useId();
1356
1366
  const descId = id + "-desc";
1357
1367
  const open = reason != null;
1358
- const cancelClose = React6.useCallback(() => {
1368
+ const cancelClose = React7.useCallback(() => {
1359
1369
  if (closeTimer.current) {
1360
1370
  clearTimeout(closeTimer.current);
1361
1371
  closeTimer.current = null;
@@ -1365,7 +1375,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1365
1375
  cancelClose();
1366
1376
  setReason(why);
1367
1377
  };
1368
- const hide = React6.useCallback(() => {
1378
+ const hide = React7.useCallback(() => {
1369
1379
  cancelClose();
1370
1380
  setReason(null);
1371
1381
  }, [cancelClose]);
@@ -1380,7 +1390,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1380
1390
  setReason((r) => r === "hover" ? null : r);
1381
1391
  }, CLOSE_DELAY_MS);
1382
1392
  };
1383
- React6.useEffect(() => cancelClose, [cancelClose]);
1393
+ React7.useEffect(() => cancelClose, [cancelClose]);
1384
1394
  const pos = usePopoverPosition(open, anchorRef, {
1385
1395
  placement: placement === "bottom" ? "bottom-center" : "top-center",
1386
1396
  offset: 8,
@@ -1390,7 +1400,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1390
1400
  onDetach: hide
1391
1401
  });
1392
1402
  const zIndex = useOverlayLayer(TOOLTIP_BASE);
1393
- React6.useEffect(() => {
1403
+ React7.useEffect(() => {
1394
1404
  if (!open) return;
1395
1405
  const key = (e) => {
1396
1406
  if (e.key === "Escape") hide();
@@ -1418,7 +1428,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1418
1428
  }
1419
1429
  if (keyboard) show("focus");
1420
1430
  };
1421
- const described = React6.isValidElement(children) ? React6.cloneElement(children, {
1431
+ const described = React7.isValidElement(children) ? React7.cloneElement(children, {
1422
1432
  "aria-describedby": [children.props["aria-describedby"], descId].filter(Boolean).join(" ")
1423
1433
  }) : children;
1424
1434
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
@@ -1426,7 +1436,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1426
1436
  {
1427
1437
  ref: anchorRef,
1428
1438
  className: "fd-tooltip-anchor",
1429
- "aria-describedby": React6.isValidElement(children) ? void 0 : descId,
1439
+ "aria-describedby": React7.isValidElement(children) ? void 0 : descId,
1430
1440
  onPointerEnter: (e) => {
1431
1441
  if (isMouse(e)) hover();
1432
1442
  },
@@ -1470,7 +1480,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1470
1480
  }
1471
1481
 
1472
1482
  // src/components/data/Clamp.tsx
1473
- var React7 = __toESM(require("react"), 1);
1483
+ var React8 = __toESM(require("react"), 1);
1474
1484
  var import_jsx_runtime25 = require("react/jsx-runtime");
1475
1485
  function Clamp({
1476
1486
  children,
@@ -1482,16 +1492,16 @@ function Clamp({
1482
1492
  onToggle,
1483
1493
  className = ""
1484
1494
  }) {
1485
- const [open, setOpen] = React7.useState(false);
1486
- const [overflows, setOverflows] = React7.useState(false);
1487
- const bodyRef = React7.useRef(null);
1488
- const charClamped = React7.useMemo(() => {
1495
+ const [open, setOpen] = React8.useState(false);
1496
+ const [overflows, setOverflows] = React8.useState(false);
1497
+ const bodyRef = React8.useRef(null);
1498
+ const charClamped = React8.useMemo(() => {
1489
1499
  if (open || !maxChars || typeof text !== "string" || text.length <= maxChars) return null;
1490
1500
  const cut = text.slice(0, maxChars);
1491
1501
  const at = cut.lastIndexOf(" ");
1492
1502
  return (at > maxChars * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
1493
1503
  }, [text, maxChars, open]);
1494
- React7.useLayoutEffect(() => {
1504
+ React8.useLayoutEffect(() => {
1495
1505
  const node = bodyRef.current;
1496
1506
  if (maxChars || !node || !maxHeight) return;
1497
1507
  const measure = () => {
@@ -1630,19 +1640,19 @@ function DataTable({
1630
1640
  }
1631
1641
 
1632
1642
  // src/components/data/FilterBar.tsx
1633
- var React8 = __toESM(require("react"), 1);
1643
+ var React9 = __toESM(require("react"), 1);
1634
1644
  var import_jsx_runtime28 = require("react/jsx-runtime");
1635
1645
  var FILTER_BAR_BASE = 120;
1636
1646
  var isSet = (v) => !(v == null || v === "" || v === false);
1637
1647
  function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = "left", className = "", ...rest }) {
1638
- const [panel, setPanel] = React8.useState(null);
1648
+ const [panel, setPanel] = React9.useState(null);
1639
1649
  const zIndex = useOverlayLayer(FILTER_BAR_BASE);
1640
- const rootRef = React8.useRef(null);
1641
- const textInputRef = React8.useRef(null);
1642
- const optionsRef = React8.useRef(null);
1650
+ const rootRef = React9.useRef(null);
1651
+ const textInputRef = React9.useRef(null);
1652
+ const optionsRef = React9.useRef(null);
1643
1653
  const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
1644
1654
  const dismissible = !!panel && (panel.kind === "add" || panel.kind === "edit" && editingField?.type === "select");
1645
- React8.useEffect(() => {
1655
+ React9.useEffect(() => {
1646
1656
  if (!dismissible) return;
1647
1657
  const away = (e) => {
1648
1658
  if (rootRef.current && !rootRef.current.contains(e.target)) setPanel(null);
@@ -1657,7 +1667,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1657
1667
  document.removeEventListener("keydown", esc);
1658
1668
  };
1659
1669
  }, [dismissible]);
1660
- React8.useEffect(() => {
1670
+ React9.useEffect(() => {
1661
1671
  if (!panel || panel.kind !== "edit") return;
1662
1672
  if (editingField?.type === "text") {
1663
1673
  textInputRef.current?.focus();
@@ -1823,7 +1833,7 @@ function StatTile({ label, value, sub, delta, loading = false, compact: compact3
1823
1833
  }
1824
1834
 
1825
1835
  // src/components/data/CodeBlock.tsx
1826
- var React9 = __toESM(require("react"), 1);
1836
+ var React10 = __toESM(require("react"), 1);
1827
1837
  var import_jsx_runtime30 = require("react/jsx-runtime");
1828
1838
  var JS_KW = /^(?:const|let|var|function|return|if|else|for|while|do|new|class|extends|import|from|export|default|await|async|try|catch|finally|throw|typeof|instanceof|of|in|switch|case|break|continue|delete|void|yield|static|get|set|this|super|interface|type|enum|implements|public|private|protected|readonly|abstract|as|satisfies|declare|namespace)$/;
1829
1839
  var RULES = {
@@ -1979,13 +1989,13 @@ function tokenize(src, lang) {
1979
1989
  return out;
1980
1990
  }
1981
1991
  function Highlighted({ code, lang }) {
1982
- const toks = React9.useMemo(() => tokenize(code, lang), [code, lang]);
1992
+ const toks = React10.useMemo(() => tokenize(code, lang), [code, lang]);
1983
1993
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_jsx_runtime30.Fragment, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
1984
1994
  }
1985
1995
  function useCopy() {
1986
- const [done, setDone] = React9.useState(false);
1987
- const timer = React9.useRef(null);
1988
- React9.useEffect(() => () => {
1996
+ const [done, setDone] = React10.useState(false);
1997
+ const timer = React10.useRef(null);
1998
+ React10.useEffect(() => () => {
1989
1999
  if (timer.current) clearTimeout(timer.current);
1990
2000
  }, []);
1991
2001
  const copy = (text) => {
@@ -2021,8 +2031,8 @@ function CodeBlock({
2021
2031
  actions,
2022
2032
  className = ""
2023
2033
  }) {
2024
- const [wrap, setWrap] = React9.useState(!!wrapDefault);
2025
- const [open, setOpen] = React9.useState(false);
2034
+ const [wrap, setWrap] = React10.useState(!!wrapDefault);
2035
+ const [open, setOpen] = React10.useState(false);
2026
2036
  const [copied, copy] = useCopy();
2027
2037
  const body = String(code).replace(/\n$/, "");
2028
2038
  const lines = body.split("\n");
@@ -2051,7 +2061,7 @@ function CodeBlock({
2051
2061
  ] });
2052
2062
  }
2053
2063
  function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
2054
- const [open, setOpen] = React9.useState(false);
2064
+ const [open, setOpen] = React10.useState(false);
2055
2065
  const [copied, copy] = useCopy();
2056
2066
  const raw = String(diff).replace(/\n$/, "");
2057
2067
  const all = raw.split("\n").map((line) => {
@@ -2097,7 +2107,7 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
2097
2107
  }
2098
2108
 
2099
2109
  // src/components/data/Markdown.tsx
2100
- var React10 = __toESM(require("react"), 1);
2110
+ var React11 = __toESM(require("react"), 1);
2101
2111
  var import_jsx_runtime31 = require("react/jsx-runtime");
2102
2112
  var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
2103
2113
  var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
@@ -2136,7 +2146,7 @@ function inlineNodes(src, ctx, keyBase) {
2136
2146
  const href = safeHref(g(2));
2137
2147
  out.push(href ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("a", { href, title: g(3) || void 0, target: /^https?:/i.test(href) ? "_blank" : void 0, rel: "noopener noreferrer", onClick: ctx.onLinkClick, children: inlineNodes(g(1), ctx, key()) }, key()) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { children: g(1) }, key()));
2138
2148
  } else if (kind === "cite") {
2139
- out.push(ctx.renderCitation ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(React10.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("sup", { className: "fd-md-cite", children: g(1) }, key()));
2149
+ out.push(ctx.renderCitation ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(React11.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("sup", { className: "fd-md-cite", children: g(1) }, key()));
2140
2150
  } else if (kind === "strongem") out.push(/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("strong", { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("em", { children: inlineNodes(g(1), ctx, key()) }) }, key()));
2141
2151
  else if (kind === "strong") out.push(/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("strong", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
2142
2152
  else if (kind === "em") out.push(/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("em", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
@@ -2301,7 +2311,7 @@ function Markdown({
2301
2311
  onLinkClick
2302
2312
  }) {
2303
2313
  const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
2304
- const blocks = React10.useMemo(() => parseBlocks(source), [source]);
2314
+ const blocks = React11.useMemo(() => parseBlocks(source), [source]);
2305
2315
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: ["fd-md", className].filter(Boolean).join(" "), children: renderBlocks(blocks, ctx, "b") });
2306
2316
  }
2307
2317
  function MarkdownInline({ source = "", className = "", onLinkClick }) {
@@ -2409,7 +2419,7 @@ function Pagination({
2409
2419
  }
2410
2420
 
2411
2421
  // src/components/data/RelativeTime.tsx
2412
- var React11 = __toESM(require("react"), 1);
2422
+ var React12 = __toESM(require("react"), 1);
2413
2423
  var import_jsx_runtime34 = require("react/jsx-runtime");
2414
2424
  var MIN = 6e4;
2415
2425
  var HOUR = 36e5;
@@ -2461,9 +2471,9 @@ function formatDuration(ms) {
2461
2471
  return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
2462
2472
  }
2463
2473
  function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
2464
- const [, force] = React11.useState(0);
2474
+ const [, force] = React12.useState(0);
2465
2475
  const t = value instanceof Date ? value.getTime() : Date.parse(value);
2466
- React11.useEffect(() => {
2476
+ React12.useEffect(() => {
2467
2477
  if (!refresh2 || !t || isNaN(t)) return;
2468
2478
  const abs = Math.abs(t - Date.now());
2469
2479
  if (abs > DAY) return;
@@ -2479,10 +2489,10 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
2479
2489
  }
2480
2490
 
2481
2491
  // src/components/data/ScoreMeter.tsx
2482
- var React13 = __toESM(require("react"), 1);
2492
+ var React14 = __toESM(require("react"), 1);
2483
2493
 
2484
2494
  // src/components/data/SegmentedMeter.tsx
2485
- var React12 = __toESM(require("react"), 1);
2495
+ var React13 = __toESM(require("react"), 1);
2486
2496
 
2487
2497
  // src/kits/files.ts
2488
2498
  function formatBytes(n) {
@@ -2687,7 +2697,7 @@ function SegmentedMeter({
2687
2697
  const pct = safeTotal ? Math.min(100, Math.round(used / safeTotal * 100)) : 0;
2688
2698
  const w = (v) => safeTotal ? Math.max(0, Math.min(100, Number(v) / safeTotal * 100)) : 0;
2689
2699
  const fill = (s, i) => s.color || (s.variant ? VARIANT_FILL[s.variant] : void 0) || CHART[i % CHART.length];
2690
- const generatedId = React12.useId();
2700
+ const generatedId = React13.useId();
2691
2701
  const uid2 = id || generatedId;
2692
2702
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
2693
2703
  label || showTotal ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "fd-segmeter-head", children: [
@@ -2771,10 +2781,10 @@ function ScoreMeter({
2771
2781
  breakdownWidth = 280,
2772
2782
  className = ""
2773
2783
  }) {
2774
- const [open, setOpen] = React13.useState(false);
2775
- const ref = React13.useRef(null);
2784
+ const [open, setOpen] = React14.useState(false);
2785
+ const ref = React14.useRef(null);
2776
2786
  const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
2777
- const body = /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(React13.Fragment, { children: [
2787
+ const body = /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(React14.Fragment, { children: [
2778
2788
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "fd-scoremeter-rail", style: { width }, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SegmentedMeter, { total: 100, segments, height, showTotal: false, showPercent: false, legend: false }) }),
2779
2789
  showScore ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
2780
2790
  ] });
@@ -2793,7 +2803,7 @@ function ScoreMeter({
2793
2803
  }
2794
2804
  );
2795
2805
  }
2796
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(React13.Fragment, { children: [
2806
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(React14.Fragment, { children: [
2797
2807
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2798
2808
  "button",
2799
2809
  {
@@ -2824,14 +2834,14 @@ function ScoreMeter({
2824
2834
  }
2825
2835
 
2826
2836
  // src/components/data/SortMenu.tsx
2827
- var React14 = __toESM(require("react"), 1);
2837
+ var React15 = __toESM(require("react"), 1);
2828
2838
  var import_jsx_runtime37 = require("react/jsx-runtime");
2829
2839
  var SORT_MENU_BASE = 120;
2830
2840
  function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", className = "", ...rest }) {
2831
- const [open, setOpen] = React14.useState(false);
2841
+ const [open, setOpen] = React15.useState(false);
2832
2842
  const zIndex = useOverlayLayer(SORT_MENU_BASE);
2833
- const ref = React14.useRef(null);
2834
- React14.useEffect(() => {
2843
+ const ref = React15.useRef(null);
2844
+ React15.useEffect(() => {
2835
2845
  if (!open) return;
2836
2846
  const away = (e) => {
2837
2847
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -2893,7 +2903,7 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
2893
2903
  }
2894
2904
 
2895
2905
  // src/components/data/StepList.tsx
2896
- var React15 = __toESM(require("react"), 1);
2906
+ var React16 = __toESM(require("react"), 1);
2897
2907
  var import_jsx_runtime38 = require("react/jsx-runtime");
2898
2908
  var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
2899
2909
  function StepList({
@@ -2906,9 +2916,9 @@ function StepList({
2906
2916
  dense = false,
2907
2917
  className = ""
2908
2918
  }) {
2909
- const [openState, setOpenState] = React15.useState(defaultOpen);
2919
+ const [openState, setOpenState] = React16.useState(defaultOpen);
2910
2920
  const open = openProp == null ? openState : openProp;
2911
- const [expanded, setExpanded] = React15.useState({});
2921
+ const [expanded, setExpanded] = React16.useState({});
2912
2922
  if (!steps.length) return null;
2913
2923
  const running = steps.some((s) => s.status === "running");
2914
2924
  const failed = steps.filter((s) => s.status === "error").length;
@@ -2966,7 +2976,7 @@ function StepList({
2966
2976
  }
2967
2977
 
2968
2978
  // src/components/data/VirtualList.tsx
2969
- var React16 = __toESM(require("react"), 1);
2979
+ var React17 = __toESM(require("react"), 1);
2970
2980
  var import_jsx_runtime39 = require("react/jsx-runtime");
2971
2981
  var VIRTUAL_LIST_BUFFER_ROWS = 20;
2972
2982
  var VIRTUAL_LIST_ROW_GAP = 6;
@@ -3018,35 +3028,35 @@ function VirtualList({
3018
3028
  className = "",
3019
3029
  style
3020
3030
  }) {
3021
- const [scrollTop, setScrollTop] = React16.useState(0);
3022
- const loaded = React16.useMemo(
3031
+ const [scrollTop, setScrollTop] = React17.useState(0);
3032
+ const loaded = React17.useMemo(
3023
3033
  () => ({ firstItemIndex, count: items.length }),
3024
3034
  [firstItemIndex, items.length]
3025
3035
  );
3026
3036
  const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
3027
3037
  const bandKey = firstItemIndex + ":" + items.length;
3028
- const win = React16.useMemo(
3038
+ const win = React17.useMemo(
3029
3039
  () => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
3030
3040
  [scrollTop, height, itemHeight, total, loaded]
3031
3041
  );
3032
- const need = React16.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
3042
+ const need = React17.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
3033
3043
  const wantStart = need.start && hasMore?.start !== false;
3034
3044
  const wantEnd = need.end && hasMore?.end !== false;
3035
3045
  const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
3036
3046
  const askKey = bandKey + "@" + bucket2;
3037
- const asked = React16.useRef({ start: null, end: null });
3038
- React16.useEffect(() => {
3047
+ const asked = React17.useRef({ start: null, end: null });
3048
+ React17.useEffect(() => {
3039
3049
  if (loading || !wantStart || asked.current.start === askKey) return;
3040
3050
  asked.current.start = askKey;
3041
3051
  onNeedMore("start", win);
3042
3052
  }, [wantStart, loading, askKey, onNeedMore, win]);
3043
- React16.useEffect(() => {
3053
+ React17.useEffect(() => {
3044
3054
  if (loading || !wantEnd || asked.current.end === askKey) return;
3045
3055
  asked.current.end = askKey;
3046
3056
  onNeedMore("end", win);
3047
3057
  }, [wantEnd, loading, askKey, onNeedMore, win]);
3048
- const lastKeysRef = React16.useRef(null);
3049
- const newKeys = React16.useMemo(() => {
3058
+ const lastKeysRef = React17.useRef(null);
3059
+ const newKeys = React17.useMemo(() => {
3050
3060
  const prev = lastKeysRef.current;
3051
3061
  if (!prev) return /* @__PURE__ */ new Set();
3052
3062
  const fresh = /* @__PURE__ */ new Set();
@@ -3056,7 +3066,7 @@ function VirtualList({
3056
3066
  }
3057
3067
  return fresh;
3058
3068
  }, [items]);
3059
- React16.useEffect(() => {
3069
+ React17.useEffect(() => {
3060
3070
  lastKeysRef.current = new Set(items.map(keyOf));
3061
3071
  }, [items]);
3062
3072
  const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
@@ -3101,7 +3111,7 @@ function VirtualList({
3101
3111
  }
3102
3112
 
3103
3113
  // src/components/data/EntityRow.tsx
3104
- var React17 = __toESM(require("react"), 1);
3114
+ var React18 = __toESM(require("react"), 1);
3105
3115
  var import_jsx_runtime40 = require("react/jsx-runtime");
3106
3116
  var ENTITY_ROW_METRIC_WIDTH = 74;
3107
3117
  var METRIC_TONE_COLOR = {
@@ -3114,7 +3124,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
3114
3124
  const key = m.id || m.label || i;
3115
3125
  const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
3116
3126
  const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
3117
- const content = /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(React17.Fragment, { children: [
3127
+ const content = /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(React18.Fragment, { children: [
3118
3128
  m.icon ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
3119
3129
  /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
3120
3130
  /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "fd-sr", children: " " + m.label })
@@ -3182,14 +3192,14 @@ function EntityRow({
3182
3192
  }
3183
3193
 
3184
3194
  // src/components/data/TransferList.tsx
3185
- var React19 = __toESM(require("react"), 1);
3195
+ var React20 = __toESM(require("react"), 1);
3186
3196
  var import_react_dom4 = require("react-dom");
3187
3197
 
3188
3198
  // src/components/forms/field.tsx
3189
- var React18 = __toESM(require("react"), 1);
3199
+ var React19 = __toESM(require("react"), 1);
3190
3200
  var import_jsx_runtime41 = require("react/jsx-runtime");
3191
3201
  function useFieldId(id) {
3192
- const generated = React18.useId();
3202
+ const generated = React19.useId();
3193
3203
  return id || generated;
3194
3204
  }
3195
3205
  function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
@@ -3307,12 +3317,12 @@ function TransferList({
3307
3317
  listHeight = 440,
3308
3318
  className = ""
3309
3319
  }) {
3310
- const [drag, setDrag] = React19.useState(null);
3311
- const [dragOverSide, setDragOverSide] = React19.useState(null);
3312
- const dragRef = React19.useRef(null);
3313
- const armedRef = React19.useRef(null);
3314
- const sideRefs = React19.useRef({ left: null, right: null });
3315
- const hitTestSide = React19.useCallback((x, y) => {
3320
+ const [drag, setDrag] = React20.useState(null);
3321
+ const [dragOverSide, setDragOverSide] = React20.useState(null);
3322
+ const dragRef = React20.useRef(null);
3323
+ const armedRef = React20.useRef(null);
3324
+ const sideRefs = React20.useRef({ left: null, right: null });
3325
+ const hitTestSide = React20.useCallback((x, y) => {
3316
3326
  for (const side of ["left", "right"]) {
3317
3327
  const el = sideRefs.current[side];
3318
3328
  if (!el) continue;
@@ -3321,7 +3331,7 @@ function TransferList({
3321
3331
  }
3322
3332
  return null;
3323
3333
  }, []);
3324
- const findItem = React19.useCallback(
3334
+ const findItem = React20.useCallback(
3325
3335
  (side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
3326
3336
  [left.items, right.items, keyOf]
3327
3337
  );
@@ -3343,7 +3353,7 @@ function TransferList({
3343
3353
  height: rect.height
3344
3354
  };
3345
3355
  };
3346
- React19.useEffect(() => {
3356
+ React20.useEffect(() => {
3347
3357
  const onMovePointer = (e) => {
3348
3358
  const armed = armedRef.current;
3349
3359
  if (!armed || e.pointerId !== armed.pointerId) return;
@@ -3396,7 +3406,7 @@ function TransferList({
3396
3406
  window.removeEventListener("pointercancel", endDrag);
3397
3407
  };
3398
3408
  }, [hitTestSide, findItem, onMove]);
3399
- React19.useEffect(() => {
3409
+ React20.useEffect(() => {
3400
3410
  if (!drag || typeof document === "undefined") return;
3401
3411
  const prev = document.body.style.userSelect;
3402
3412
  document.body.style.userSelect = "none";
@@ -3504,11 +3514,11 @@ function TransferList({
3504
3514
  }
3505
3515
 
3506
3516
  // src/components/forms/Checkbox.tsx
3507
- var React20 = __toESM(require("react"), 1);
3517
+ var React21 = __toESM(require("react"), 1);
3508
3518
  var import_jsx_runtime45 = require("react/jsx-runtime");
3509
3519
  function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
3510
- const ref = React20.useRef(null);
3511
- React20.useEffect(() => {
3520
+ const ref = React21.useRef(null);
3521
+ React21.useEffect(() => {
3512
3522
  if (ref.current) ref.current.indeterminate = indeterminate;
3513
3523
  }, [indeterminate]);
3514
3524
  return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
@@ -3567,7 +3577,7 @@ function Textarea({ label, help, error, required = false, rows = 4, disabled = f
3567
3577
  }
3568
3578
 
3569
3579
  // src/components/forms/NumberInput.tsx
3570
- var React21 = __toESM(require("react"), 1);
3580
+ var React22 = __toESM(require("react"), 1);
3571
3581
  var import_jsx_runtime49 = require("react/jsx-runtime");
3572
3582
  function NumberInput({
3573
3583
  label,
@@ -3595,10 +3605,10 @@ function NumberInput({
3595
3605
  const n = Number(String(v == null ? "" : v).replace(/[^0-9.-]/g, ""));
3596
3606
  return isNaN(n) ? null : n;
3597
3607
  };
3598
- const [text, setText] = React21.useState(value == null || value === "" ? "" : String(value));
3599
- const [editing, setEditing] = React21.useState(false);
3600
- const timer = React21.useRef(null);
3601
- React21.useEffect(() => {
3608
+ const [text, setText] = React22.useState(value == null || value === "" ? "" : String(value));
3609
+ const [editing, setEditing] = React22.useState(false);
3610
+ const timer = React22.useRef(null);
3611
+ React22.useEffect(() => {
3602
3612
  if (!editing) setText(value == null || value === "" ? "" : String(value));
3603
3613
  }, [value, editing]);
3604
3614
  const clamp = (n) => Math.min(max, Math.max(min, n));
@@ -3622,7 +3632,7 @@ function NumberInput({
3622
3632
  const release = () => {
3623
3633
  if (timer.current) clearTimeout(timer.current);
3624
3634
  };
3625
- React21.useEffect(() => () => {
3635
+ React22.useEffect(() => () => {
3626
3636
  if (timer.current) clearTimeout(timer.current);
3627
3637
  }, []);
3628
3638
  const shown = editing ? text : (() => {
@@ -3709,7 +3719,7 @@ function NumberInput({
3709
3719
  }
3710
3720
 
3711
3721
  // src/components/forms/Select.tsx
3712
- var React22 = __toESM(require("react"), 1);
3722
+ var React23 = __toESM(require("react"), 1);
3713
3723
  var import_jsx_runtime50 = require("react/jsx-runtime");
3714
3724
  var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
3715
3725
  function Select({
@@ -3736,13 +3746,13 @@ function Select({
3736
3746
  const isOn = (v) => multiple ? vals.includes(v) : v === value;
3737
3747
  const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
3738
3748
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
3739
- const [open, setOpen] = React22.useState(false);
3740
- const [q, setQ] = React22.useState("");
3741
- const [active, setActive] = React22.useState(-1);
3742
- const rootRef = React22.useRef(null);
3743
- const boxRef = React22.useRef(null);
3744
- const listRef = React22.useRef(null);
3745
- const typeBuf = React22.useRef({ s: "", t: 0 });
3749
+ const [open, setOpen] = React23.useState(false);
3750
+ const [q, setQ] = React23.useState("");
3751
+ const [active, setActive] = React23.useState(-1);
3752
+ const rootRef = React23.useRef(null);
3753
+ const boxRef = React23.useRef(null);
3754
+ const listRef = React23.useRef(null);
3755
+ const typeBuf = React23.useRef({ s: "", t: 0 });
3746
3756
  const selected = multiple ? null : opts.find((o) => o.value === value);
3747
3757
  const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
3748
3758
  const boxText = multiple ? chosen.length === 0 ? placeholder : chosen.length === 1 ? chosen[0].label : summary ? summary(chosen.map((o) => o.value)) : chosen.length + " selected" : selected ? selected.label : placeholder;
@@ -3767,7 +3777,7 @@ function Select({
3767
3777
  }
3768
3778
  setOpen(!open);
3769
3779
  };
3770
- React22.useEffect(() => {
3780
+ React23.useEffect(() => {
3771
3781
  if (!open || active < 0 || !listRef.current) return;
3772
3782
  const el = listRef.current.querySelector('[data-i="' + active + '"]');
3773
3783
  if (el) {
@@ -3888,7 +3898,7 @@ function Select({
3888
3898
  ),
3889
3899
  q ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
3890
3900
  ] }) : void 0,
3891
- footer: multiple ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(React22.Fragment, { children: [
3901
+ footer: multiple ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(React23.Fragment, { children: [
3892
3902
  /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
3893
3903
  "button",
3894
3904
  {
@@ -3919,7 +3929,7 @@ function Select({
3919
3929
  'Nothing matches "',
3920
3930
  q,
3921
3931
  '".'
3922
- ] }) : groups.map((grp) => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(React22.Fragment, { children: [
3932
+ ] }) : groups.map((grp) => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(React23.Fragment, { children: [
3923
3933
  grp.g ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "fd-pop-group", children: grp.g }) : null,
3924
3934
  grp.items.map(({ o, i }) => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
3925
3935
  "button",
@@ -3956,7 +3966,7 @@ function Select({
3956
3966
  }
3957
3967
 
3958
3968
  // src/components/forms/DatePicker.tsx
3959
- var React23 = __toESM(require("react"), 1);
3969
+ var React24 = __toESM(require("react"), 1);
3960
3970
  var import_jsx_runtime51 = require("react/jsx-runtime");
3961
3971
  var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
3962
3972
  var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
@@ -3974,10 +3984,10 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3974
3984
  const today = /* @__PURE__ */ new Date();
3975
3985
  const sel = range ? value || {} : { start: value, end: value };
3976
3986
  const anchor = parse(sel.start) || parse(initialMonth) || today;
3977
- const [vy, setVy] = React23.useState(anchor.getFullYear());
3978
- const [vm, setVm] = React23.useState(anchor.getMonth());
3979
- const [mode2, setMode] = React23.useState("days");
3980
- const [hover, setHover] = React23.useState(null);
3987
+ const [vy, setVy] = React24.useState(anchor.getFullYear());
3988
+ const [vm, setVm] = React24.useState(anchor.getMonth());
3989
+ const [mode2, setMode] = React24.useState("days");
3990
+ const [hover, setHover] = React24.useState(null);
3981
3991
  const s = parse(sel.start), e = parse(sel.end);
3982
3992
  const hoverEnd = range && s && !e && hover ? parse(hover) : null;
3983
3993
  const inRange = (d) => {
@@ -4093,9 +4103,9 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
4093
4103
  }
4094
4104
  function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, ...rest }) {
4095
4105
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
4096
- const [open, setOpen] = React23.useState(false);
4097
- const rootRef = React23.useRef(null);
4098
- const boxRef = React23.useRef(null);
4106
+ const [open, setOpen] = React24.useState(false);
4107
+ const rootRef = React24.useRef(null);
4108
+ const boxRef = React24.useRef(null);
4099
4109
  const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
4100
4110
  const toggle = () => {
4101
4111
  if (!disabled) setOpen(!open);
@@ -4157,7 +4167,7 @@ function DatePicker({ label, help, error, required = false, disabled = false, ra
4157
4167
  }
4158
4168
 
4159
4169
  // src/components/forms/TimePicker.tsx
4160
- var React24 = __toESM(require("react"), 1);
4170
+ var React25 = __toESM(require("react"), 1);
4161
4171
  var import_jsx_runtime52 = require("react/jsx-runtime");
4162
4172
  var pad = (n) => String(n).padStart(2, "0");
4163
4173
  function ClockFace({ value = "09:00", onChange }) {
@@ -4166,9 +4176,9 @@ function ClockFace({ value = "09:00", onChange }) {
4166
4176
  if (isNaN(m)) m = 0;
4167
4177
  const pm = h24 >= 12;
4168
4178
  const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
4169
- const [mode2, setMode] = React24.useState("h");
4170
- const faceRef = React24.useRef(null);
4171
- const dragging = React24.useRef(false);
4179
+ const [mode2, setMode] = React25.useState("h");
4180
+ const faceRef = React25.useRef(null);
4181
+ const dragging = React25.useRef(false);
4172
4182
  const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
4173
4183
  const R = 108, NR = 80;
4174
4184
  const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
@@ -4241,9 +4251,9 @@ function ClockFace({ value = "09:00", onChange }) {
4241
4251
  }
4242
4252
  function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
4243
4253
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
4244
- const [open, setOpen] = React24.useState(false);
4245
- const rootRef = React24.useRef(null);
4246
- const boxRef = React24.useRef(null);
4254
+ const [open, setOpen] = React25.useState(false);
4255
+ const rootRef = React25.useRef(null);
4256
+ const boxRef = React25.useRef(null);
4247
4257
  const disp = () => {
4248
4258
  if (!value) return "";
4249
4259
  const [h, m] = value.split(":").map(Number);
@@ -4286,7 +4296,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
4286
4296
  offset: 6,
4287
4297
  width: 262,
4288
4298
  role: "presentation",
4289
- footer: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(React24.Fragment, { children: [
4299
+ footer: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(React25.Fragment, { children: [
4290
4300
  /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
4291
4301
  "button",
4292
4302
  {
@@ -4314,7 +4324,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
4314
4324
  }
4315
4325
 
4316
4326
  // src/components/forms/Slider.tsx
4317
- var React25 = __toESM(require("react"), 1);
4327
+ var React26 = __toESM(require("react"), 1);
4318
4328
  var import_jsx_runtime53 = require("react/jsx-runtime");
4319
4329
  function Slider({
4320
4330
  label,
@@ -4332,7 +4342,7 @@ function Slider({
4332
4342
  ...rest
4333
4343
  }) {
4334
4344
  const fieldId = useFieldId(id);
4335
- const [dragging, setDragging] = React25.useState(false);
4345
+ const [dragging, setDragging] = React26.useState(false);
4336
4346
  const v = value === void 0 ? min : Number(value);
4337
4347
  const pct = max === min ? 0 : (v - min) / (max - min) * 100;
4338
4348
  return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
@@ -4366,7 +4376,7 @@ function Slider({
4366
4376
  }
4367
4377
 
4368
4378
  // src/components/forms/RangeSlider.tsx
4369
- var React26 = __toESM(require("react"), 1);
4379
+ var React27 = __toESM(require("react"), 1);
4370
4380
  var import_jsx_runtime54 = require("react/jsx-runtime");
4371
4381
  function RangeSlider({
4372
4382
  label,
@@ -4386,9 +4396,9 @@ function RangeSlider({
4386
4396
  }) {
4387
4397
  const fmt2 = format || ((v) => String(v));
4388
4398
  const [a, b] = value || [min, max];
4389
- const [drag, setDrag] = React26.useState(null);
4390
- const [focus, setFocus] = React26.useState(null);
4391
- const railRef = React26.useRef(null);
4399
+ const [drag, setDrag] = React27.useState(null);
4400
+ const [focus, setFocus] = React27.useState(null);
4401
+ const railRef = React27.useRef(null);
4392
4402
  const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
4393
4403
  const clampPair = (i, v) => {
4394
4404
  v = Math.min(max, Math.max(min, Math.round(v / step) * step));
@@ -4403,7 +4413,7 @@ function RangeSlider({
4403
4413
  const r = railRef.current.getBoundingClientRect();
4404
4414
  return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
4405
4415
  };
4406
- React26.useEffect(() => {
4416
+ React27.useEffect(() => {
4407
4417
  if (drag === null) return;
4408
4418
  const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
4409
4419
  const upH = () => setDrag(null);
@@ -4484,7 +4494,7 @@ function RangeSlider({
4484
4494
  /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
4485
4495
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-range-rail", ref: railRef }),
4486
4496
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
4487
- marks.map((m) => /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(React26.Fragment, { children: [
4497
+ marks.map((m) => /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(React27.Fragment, { children: [
4488
4498
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
4489
4499
  m.label ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
4490
4500
  ] }, m.value)),
@@ -4513,7 +4523,7 @@ function RangeSlider({
4513
4523
  }
4514
4524
 
4515
4525
  // src/components/forms/Dropzone.tsx
4516
- var React27 = __toESM(require("react"), 1);
4526
+ var React28 = __toESM(require("react"), 1);
4517
4527
  var import_jsx_runtime55 = require("react/jsx-runtime");
4518
4528
  function Dropzone({
4519
4529
  onFiles,
@@ -4528,8 +4538,8 @@ function Dropzone({
4528
4538
  className = "",
4529
4539
  style
4530
4540
  }) {
4531
- const [over, setOver] = React27.useState(false);
4532
- const depth = React27.useRef(0);
4541
+ const [over, setOver] = React28.useState(false);
4542
+ const depth = React28.useRef(0);
4533
4543
  const has = (e) => {
4534
4544
  const dt = e.dataTransfer;
4535
4545
  if (!dt) return false;
@@ -4591,8 +4601,8 @@ function FilePickButton({
4591
4601
  className = "",
4592
4602
  children
4593
4603
  }) {
4594
- const ref = React27.useRef(null);
4595
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(React27.Fragment, { children: [
4604
+ const ref = React28.useRef(null);
4605
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(React28.Fragment, { children: [
4596
4606
  /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
4597
4607
  "button",
4598
4608
  {
@@ -4625,10 +4635,10 @@ function FilePickButton({
4625
4635
  }
4626
4636
  function useStagedFiles(upload, opts) {
4627
4637
  const o = opts || {};
4628
- const [items, setItems] = React27.useState([]);
4629
- const controllers = React27.useRef({});
4638
+ const [items, setItems] = React28.useState([]);
4639
+ const controllers = React28.useRef({});
4630
4640
  const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
4631
- const run = React27.useCallback((att) => {
4641
+ const run = React28.useCallback((att) => {
4632
4642
  if (!upload) return;
4633
4643
  const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
4634
4644
  controllers.current[att.id] = ac;
@@ -4645,14 +4655,14 @@ function useStagedFiles(upload, opts) {
4645
4655
  delete controllers.current[att.id];
4646
4656
  });
4647
4657
  }, [upload]);
4648
- const add = React27.useCallback((files) => {
4658
+ const add = React28.useCallback((files) => {
4649
4659
  if (!upload) return [];
4650
4660
  const atts = Array.from(files).map((f) => toAttachment(f));
4651
4661
  setItems((list) => list.concat(atts));
4652
4662
  atts.forEach(run);
4653
4663
  return atts;
4654
4664
  }, [upload, run]);
4655
- const remove = React27.useCallback((att) => {
4665
+ const remove = React28.useCallback((att) => {
4656
4666
  const ac = controllers.current[att.id];
4657
4667
  if (ac) {
4658
4668
  try {
@@ -4663,10 +4673,10 @@ function useStagedFiles(upload, opts) {
4663
4673
  }
4664
4674
  setItems((list) => list.filter((f) => f.id !== att.id));
4665
4675
  }, []);
4666
- const retry = React27.useCallback((att) => {
4676
+ const retry = React28.useCallback((att) => {
4667
4677
  run(att);
4668
4678
  }, [run]);
4669
- const clear = React27.useCallback(() => {
4679
+ const clear = React28.useCallback(() => {
4670
4680
  Object.values(controllers.current).forEach((ac) => {
4671
4681
  try {
4672
4682
  ac && ac.abort();
@@ -4790,7 +4800,7 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
4790
4800
  }
4791
4801
 
4792
4802
  // src/components/forms/MarkdownEditor.tsx
4793
- var React28 = __toESM(require("react"), 1);
4803
+ var React29 = __toESM(require("react"), 1);
4794
4804
  var import_jsx_runtime57 = require("react/jsx-runtime");
4795
4805
  var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
4796
4806
  var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
@@ -5004,7 +5014,7 @@ function syncDom(root, value) {
5004
5014
  while (root.children.length > lines.length) root.removeChild(root.lastChild);
5005
5015
  }
5006
5016
  var LIST_CONT = RE_LI;
5007
- var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
5017
+ var MarkdownEditor = React29.forwardRef(function MarkdownEditor2({
5008
5018
  value = "",
5009
5019
  onChange,
5010
5020
  onSubmit,
@@ -5023,10 +5033,10 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
5023
5033
  className = "",
5024
5034
  id
5025
5035
  }, ref) {
5026
- const boxRef = React28.useRef(null);
5027
- const composing = React28.useRef(false);
5028
- const pendingCaret = React28.useRef(null);
5029
- React28.useLayoutEffect(() => {
5036
+ const boxRef = React29.useRef(null);
5037
+ const composing = React29.useRef(false);
5038
+ const pendingCaret = React29.useRef(null);
5039
+ React29.useLayoutEffect(() => {
5030
5040
  const root = boxRef.current;
5031
5041
  if (!root || composing.current) return;
5032
5042
  const active = document.activeElement === root || root.contains(document.activeElement);
@@ -5035,7 +5045,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
5035
5045
  pendingCaret.current = null;
5036
5046
  if (active && caret != null) placeCaret(root, caret);
5037
5047
  }, [value]);
5038
- React28.useEffect(() => {
5048
+ React29.useEffect(() => {
5039
5049
  if (autoFocus && boxRef.current) boxRef.current.focus();
5040
5050
  }, [autoFocus]);
5041
5051
  const caretNow = () => {
@@ -5102,7 +5112,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
5102
5112
  api.replaceRange(from, to, next, from + next.length);
5103
5113
  }
5104
5114
  };
5105
- React28.useImperativeHandle(ref, () => api);
5115
+ React29.useImperativeHandle(ref, () => api);
5106
5116
  function detect(text, caret) {
5107
5117
  if (!onTrigger) return;
5108
5118
  const upto = text.slice(0, caret);
@@ -5254,10 +5264,10 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
5254
5264
  });
5255
5265
 
5256
5266
  // src/components/platform/AccountMenu.tsx
5257
- var React30 = __toESM(require("react"), 1);
5267
+ var React31 = __toESM(require("react"), 1);
5258
5268
 
5259
5269
  // src/kits/session.ts
5260
- var React29 = __toESM(require("react"), 1);
5270
+ var React30 = __toESM(require("react"), 1);
5261
5271
  var PERMISSION_CATALOG = [
5262
5272
  { group: "Plans", items: [
5263
5273
  { key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
@@ -6824,8 +6834,8 @@ function roadmap(overrides) {
6824
6834
  };
6825
6835
  }
6826
6836
  function useSession() {
6827
- const [s, setS] = React29.useState(getSession);
6828
- React29.useEffect(() => subscribe(setS), []);
6837
+ const [s, setS] = React30.useState(getSession);
6838
+ React30.useEffect(() => subscribe(setS), []);
6829
6839
  return s;
6830
6840
  }
6831
6841
  var SessionKit = {
@@ -6895,9 +6905,9 @@ function AccountMenu({
6895
6905
  ...rest
6896
6906
  }) {
6897
6907
  const session = SessionKit.useSession();
6898
- const [open, setOpen] = React30.useState(false);
6899
- const [switching, setSwitching] = React30.useState(false);
6900
- const ref = React30.useRef(null);
6908
+ const [open, setOpen] = React31.useState(false);
6909
+ const [switching, setSwitching] = React31.useState(false);
6910
+ const ref = React31.useRef(null);
6901
6911
  const user = session.user;
6902
6912
  const visibleAdmin = adminLinks.filter((l) => !l.perm || SessionKit.can(l.perm));
6903
6913
  const pick = (item) => {
@@ -6981,14 +6991,14 @@ function AccountMenu({
6981
6991
  }
6982
6992
 
6983
6993
  // src/components/platform/ApiSpecBrowser.tsx
6984
- var React31 = __toESM(require("react"), 1);
6994
+ var React32 = __toESM(require("react"), 1);
6985
6995
  var import_jsx_runtime59 = require("react/jsx-runtime");
6986
6996
  var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
6987
6997
  function Json({ obj }) {
6988
6998
  return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
6989
6999
  }
6990
7000
  function Endpoint({ s, onRequest }) {
6991
- const [tried, setTried] = React31.useState(null);
7001
+ const [tried, setTried] = React32.useState(null);
6992
7002
  const run = async () => {
6993
7003
  setTried("busy");
6994
7004
  const t0 = (window.performance || Date).now();
@@ -7061,10 +7071,10 @@ function ApiSpecBrowser({
7061
7071
  className = "",
7062
7072
  ...rest
7063
7073
  }) {
7064
- const [q, setQ] = React31.useState("");
7065
- const [method, setMethod] = React31.useState(null);
7066
- const [mod, setMod] = React31.useState(null);
7067
- const [listOnly, setListOnly] = React31.useState(false);
7074
+ const [q, setQ] = React32.useState("");
7075
+ const [method, setMethod] = React32.useState(null);
7076
+ const [mod, setMod] = React32.useState(null);
7077
+ const [listOnly, setListOnly] = React32.useState(false);
7068
7078
  const activeModule = modules && modules.find((m) => m.id === mod);
7069
7079
  const hits = spec.filter((s) => (!method || s.method === method) && (!listOnly || s.isList) && (!activeModule || activeModule.endpoints.indexOf(s.id) >= 0) && (!q || (s.path + " " + s.title + " " + s.purpose + " " + (s.usedBy || []).join(" ")).toLowerCase().includes(q.toLowerCase())));
7070
7080
  const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
@@ -7143,7 +7153,7 @@ function ApiSpecBrowser({
7143
7153
  }
7144
7154
 
7145
7155
  // src/components/platform/ProfilePage.tsx
7146
- var React32 = __toESM(require("react"), 1);
7156
+ var React33 = __toESM(require("react"), 1);
7147
7157
  var import_jsx_runtime60 = require("react/jsx-runtime");
7148
7158
  var TIMEZONES = ["America/New_York", "America/Chicago", "America/Denver", "America/Los_Angeles", "America/Anchorage", "Pacific/Honolulu", "Europe/London", "Europe/Berlin"];
7149
7159
  var NOTIFY = [
@@ -7156,7 +7166,7 @@ var NOTIFY = [
7156
7166
  function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSessions = true, className = "", ...rest }) {
7157
7167
  const session = SessionKit.useSession();
7158
7168
  const user = userProp || session.user;
7159
- const [draft, setDraft] = React32.useState(() => ({
7169
+ const [draft, setDraft] = React33.useState(() => ({
7160
7170
  name: user.name || "",
7161
7171
  title: user.title || "",
7162
7172
  email: user.email || "",
@@ -7165,8 +7175,8 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7165
7175
  bio: user.bio || "",
7166
7176
  notify: user.notify || { planShared: true, planChanged: true, goalMissed: true, flagChanged: false, weekly: true }
7167
7177
  }));
7168
- const [saving, setSaving] = React32.useState(false);
7169
- const [saved, setSaved] = React32.useState(false);
7178
+ const [saving, setSaving] = React33.useState(false);
7179
+ const [saved, setSaved] = React33.useState(false);
7170
7180
  const set = (k, v) => {
7171
7181
  setDraft((d) => Object.assign({}, d, { [k]: v }));
7172
7182
  setSaved(false);
@@ -7356,10 +7366,10 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7356
7366
  }
7357
7367
 
7358
7368
  // src/components/platform/RoadmapTimeline.tsx
7359
- var React34 = __toESM(require("react"), 1);
7369
+ var React35 = __toESM(require("react"), 1);
7360
7370
 
7361
7371
  // src/kits/runtime.ts
7362
- var React33 = __toESM(require("react"), 1);
7372
+ var React34 = __toESM(require("react"), 1);
7363
7373
  var WIRED_ENDPOINTS = [
7364
7374
  // Nothing yet. Every id below would come from a real service:
7365
7375
  // "plan.get", "placements.list", …
@@ -7530,8 +7540,8 @@ var RuntimeKit = {
7530
7540
  };
7531
7541
  RuntimeKit.declare(FEATURE_NEEDS);
7532
7542
  function useRuntimeMode() {
7533
- const [m, setM] = React33.useState(RuntimeKit.getMode());
7534
- React33.useEffect(() => RuntimeKit.subscribe(setM), []);
7543
+ const [m, setM] = React34.useState(RuntimeKit.getMode());
7544
+ React34.useEffect(() => RuntimeKit.subscribe(setM), []);
7535
7545
  return m;
7536
7546
  }
7537
7547
  function useFeatureStatus(key) {
@@ -7614,12 +7624,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
7614
7624
  }
7615
7625
  function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7616
7626
  const session = SessionKit.useSession();
7617
- const [project, setProject] = React34.useState("");
7618
- const [q, setQ] = React34.useState("");
7619
- const scrollRef = React34.useRef(null);
7620
- const nowRef = React34.useRef(null);
7621
- const rm = React34.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
7622
- const byKey = React34.useMemo(() => {
7627
+ const [project, setProject] = React35.useState("");
7628
+ const [q, setQ] = React35.useState("");
7629
+ const scrollRef = React35.useRef(null);
7630
+ const nowRef = React35.useRef(null);
7631
+ const rm = React35.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
7632
+ const byKey = React35.useMemo(() => {
7623
7633
  const m = {};
7624
7634
  rm.items.forEach((i) => {
7625
7635
  m[i.key] = i;
@@ -7628,7 +7638,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7628
7638
  }, [rm]);
7629
7639
  const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
7630
7640
  const projects = [...new Set(rm.items.map((i) => i.project))];
7631
- React34.useEffect(() => {
7641
+ React35.useEffect(() => {
7632
7642
  let raf1 = 0, raf2 = 0;
7633
7643
  const place = () => {
7634
7644
  const box = scrollRef.current, mark = nowRef.current;
@@ -7702,7 +7712,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7702
7712
  lastPhase = item.phase;
7703
7713
  const inPhase = items.filter((i) => i.phase === item.phase).length;
7704
7714
  const isBoundary = n === firstPending;
7705
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(React34.Fragment, { children: [
7715
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(React35.Fragment, { children: [
7706
7716
  showPhase ? /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "fd-rm-era", children: [
7707
7717
  /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
7708
7718
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
@@ -7746,7 +7756,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7746
7756
  }
7747
7757
 
7748
7758
  // src/components/platform/ComingSoon.tsx
7749
- var React35 = __toESM(require("react"), 1);
7759
+ var React36 = __toESM(require("react"), 1);
7750
7760
  var import_react_dom5 = require("react-dom");
7751
7761
  var import_jsx_runtime62 = require("react/jsx-runtime");
7752
7762
  var SOON_HOVERCARD_BASE = 220;
@@ -7765,8 +7775,8 @@ function writeBypassed(list) {
7765
7775
  }
7766
7776
  }
7767
7777
  function useBypass(key) {
7768
- const [on, setOn] = React35.useState(() => !!key && readBypassed().indexOf(key) >= 0);
7769
- React35.useEffect(() => {
7778
+ const [on, setOn] = React36.useState(() => !!key && readBypassed().indexOf(key) >= 0);
7779
+ React36.useEffect(() => {
7770
7780
  setOn(!!key && readBypassed().indexOf(key) >= 0);
7771
7781
  }, [key]);
7772
7782
  const set = (next) => {
@@ -7813,9 +7823,9 @@ function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onB
7813
7823
  ] });
7814
7824
  }
7815
7825
  function useHoverCard(open) {
7816
- const anchor = React35.useRef(null);
7817
- const [pos, setPos] = React35.useState(null);
7818
- React35.useLayoutEffect(() => {
7826
+ const anchor = React36.useRef(null);
7827
+ const [pos, setPos] = React36.useState(null);
7828
+ React36.useLayoutEffect(() => {
7819
7829
  if (!open || !anchor.current) {
7820
7830
  setPos(null);
7821
7831
  return;
@@ -7942,10 +7952,10 @@ function ComingSoon({
7942
7952
  ] });
7943
7953
  }
7944
7954
  function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
7945
- const [open, setOpen] = React35.useState(false);
7955
+ const [open, setOpen] = React36.useState(false);
7946
7956
  const [anchor, pos] = useHoverCard(open);
7947
7957
  const zIndex = useOverlayLayer(SOON_HOVERCARD_BASE);
7948
- const close = React35.useRef(null);
7958
+ const close = React36.useRef(null);
7949
7959
  const show = () => {
7950
7960
  if (close.current) {
7951
7961
  clearTimeout(close.current);
@@ -7961,7 +7971,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
7961
7971
  setOpen(false);
7962
7972
  }, 140);
7963
7973
  };
7964
- React35.useEffect(() => () => {
7974
+ React36.useEffect(() => () => {
7965
7975
  if (close.current) clearTimeout(close.current);
7966
7976
  }, []);
7967
7977
  return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
@@ -8130,15 +8140,15 @@ function PermissionHint({ perm, children }) {
8130
8140
  }
8131
8141
 
8132
8142
  // src/components/platform/ModeSwitch.tsx
8133
- var React36 = __toESM(require("react"), 1);
8143
+ var React37 = __toESM(require("react"), 1);
8134
8144
  var import_jsx_runtime64 = require("react/jsx-runtime");
8135
8145
  var MODE_SWITCH_BASE = 140;
8136
8146
  function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog, onOpenSpec, summary }) {
8137
8147
  const mode2 = useRuntimeMode();
8138
- const [open, setOpen] = React36.useState(false);
8148
+ const [open, setOpen] = React37.useState(false);
8139
8149
  const zIndex = useOverlayLayer(MODE_SWITCH_BASE);
8140
- const ref = React36.useRef(null);
8141
- React36.useEffect(() => {
8150
+ const ref = React37.useRef(null);
8151
+ React37.useEffect(() => {
8142
8152
  if (!open) return;
8143
8153
  const away = (e) => {
8144
8154
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -8387,7 +8397,7 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8387
8397
  }
8388
8398
 
8389
8399
  // src/components/planner/MixGap.tsx
8390
- var React37 = __toESM(require("react"), 1);
8400
+ var React38 = __toESM(require("react"), 1);
8391
8401
  var import_jsx_runtime67 = require("react/jsx-runtime");
8392
8402
  var MIX_GAP_LAYOUT = {
8393
8403
  trackHeight: 30,
@@ -8402,7 +8412,7 @@ function mixGapOffset(value, max) {
8402
8412
  }
8403
8413
  function MixGap({ rows = [], loading = false, className = "" }) {
8404
8414
  const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
8405
- const [hover, setHover] = React37.useState(null);
8415
+ const [hover, setHover] = React38.useState(null);
8406
8416
  const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
8407
8417
  const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
8408
8418
  const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
@@ -8545,7 +8555,7 @@ function ChannelContribution({
8545
8555
  }
8546
8556
 
8547
8557
  // src/components/planner/BudgetReallocator.tsx
8548
- var React38 = __toESM(require("react"), 1);
8558
+ var React39 = __toESM(require("react"), 1);
8549
8559
  var import_jsx_runtime69 = require("react/jsx-runtime");
8550
8560
  var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
8551
8561
  function BudgetReallocator({
@@ -8561,8 +8571,8 @@ function BudgetReallocator({
8561
8571
  onCancel,
8562
8572
  className = ""
8563
8573
  }) {
8564
- const [draft, setDraft] = React38.useState(spend);
8565
- React38.useEffect(() => setDraft(spend), [spend]);
8574
+ const [draft, setDraft] = React39.useState(spend);
8575
+ React39.useEffect(() => setDraft(spend), [spend]);
8566
8576
  const dirty = draft !== spend;
8567
8577
  const nextCrp = scoreFor ? scoreFor(draft) : crp;
8568
8578
  const nextBand = bandFor(nextCrp);
@@ -8732,7 +8742,7 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "" })
8732
8742
  }
8733
8743
 
8734
8744
  // src/components/planner/PreferenceMeter.tsx
8735
- var React39 = __toESM(require("react"), 1);
8745
+ var React40 = __toESM(require("react"), 1);
8736
8746
  var import_jsx_runtime72 = require("react/jsx-runtime");
8737
8747
  function preferenceScore(criteria) {
8738
8748
  const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
@@ -8762,7 +8772,7 @@ function PreferenceMeter({
8762
8772
  className = ""
8763
8773
  }) {
8764
8774
  const value = score == null ? preferenceScore(criteria) : score;
8765
- const segments = React39.useMemo(() => preferenceSegments(criteria), [criteria]);
8775
+ const segments = React40.useMemo(() => preferenceSegments(criteria), [criteria]);
8766
8776
  return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
8767
8777
  ScoreMeter,
8768
8778
  {
@@ -8801,10 +8811,10 @@ function PreferenceMeter({
8801
8811
  }
8802
8812
 
8803
8813
  // src/components/chat/AgentChatPanel.tsx
8804
- var React45 = __toESM(require("react"), 1);
8814
+ var React46 = __toESM(require("react"), 1);
8805
8815
 
8806
8816
  // src/components/chat/chatEngine.ts
8807
- var React40 = __toESM(require("react"), 1);
8817
+ var React41 = __toESM(require("react"), 1);
8808
8818
  var CHAT_UNAVAILABLE = "chat_unavailable";
8809
8819
  var JOB_PENDING = ["queued", "running"];
8810
8820
  var JOB_SUCCESS = ["completed", "recovered"];
@@ -8858,22 +8868,22 @@ function useChatEngine(opts) {
8858
8868
  onClear,
8859
8869
  onFeedback
8860
8870
  } = opts || {};
8861
- const [status, setStatus] = React40.useState("idle");
8862
- const [threadId, setThreadId] = React40.useState(null);
8863
- const [messages, setMessages] = React40.useState([]);
8864
- const [queue, setQueue] = React40.useState([]);
8865
- const [fatal, setFatal] = React40.useState(null);
8866
- const [busy, setBusy] = React40.useState(false);
8867
- const [turnStartedAt, setTurnStartedAt] = React40.useState(null);
8868
- const listRef = React40.useRef([]);
8869
- const queueRef = React40.useRef([]);
8870
- const busyRef = React40.useRef(false);
8871
- const stoppedRef = React40.useRef(false);
8872
- const abortRef = React40.useRef(null);
8873
- const serverCount = React40.useRef(0);
8874
- const threadRef = React40.useRef(null);
8875
- const mounted = React40.useRef(true);
8876
- React40.useEffect(() => {
8871
+ const [status, setStatus] = React41.useState("idle");
8872
+ const [threadId, setThreadId] = React41.useState(null);
8873
+ const [messages, setMessages] = React41.useState([]);
8874
+ const [queue, setQueue] = React41.useState([]);
8875
+ const [fatal, setFatal] = React41.useState(null);
8876
+ const [busy, setBusy] = React41.useState(false);
8877
+ const [turnStartedAt, setTurnStartedAt] = React41.useState(null);
8878
+ const listRef = React41.useRef([]);
8879
+ const queueRef = React41.useRef([]);
8880
+ const busyRef = React41.useRef(false);
8881
+ const stoppedRef = React41.useRef(false);
8882
+ const abortRef = React41.useRef(null);
8883
+ const serverCount = React41.useRef(0);
8884
+ const threadRef = React41.useRef(null);
8885
+ const mounted = React41.useRef(true);
8886
+ React41.useEffect(() => {
8877
8887
  mounted.current = true;
8878
8888
  return () => {
8879
8889
  mounted.current = false;
@@ -8895,14 +8905,14 @@ function useChatEngine(opts) {
8895
8905
  }
8896
8906
  return false;
8897
8907
  };
8898
- const loadThread = React40.useCallback(async (id) => {
8908
+ const loadThread = React41.useCallback(async (id) => {
8899
8909
  const data = await apiAdapter.getThread(id);
8900
8910
  const list = [...data && data.messages || []];
8901
8911
  serverCount.current = list.length;
8902
8912
  commit(list);
8903
8913
  return list;
8904
8914
  }, [apiAdapter]);
8905
- React40.useEffect(() => {
8915
+ React41.useEffect(() => {
8906
8916
  if (!apiAdapter) {
8907
8917
  setStatus("idle");
8908
8918
  setFatal(null);
@@ -9115,7 +9125,7 @@ function useChatEngine(opts) {
9115
9125
  await dispatchTurn(turn);
9116
9126
  }
9117
9127
  }
9118
- const send = React40.useCallback((text, attachments) => {
9128
+ const send = React41.useCallback((text, attachments) => {
9119
9129
  const body = (text || "").trim();
9120
9130
  if (!body && !(attachments && attachments.length)) return;
9121
9131
  if (status === "disconnected") return;
@@ -9125,7 +9135,7 @@ function useChatEngine(opts) {
9125
9135
  stoppedRef.current = false;
9126
9136
  drain();
9127
9137
  }, [status]);
9128
- const stop = React40.useCallback(() => {
9138
+ const stop = React41.useCallback(() => {
9129
9139
  stoppedRef.current = true;
9130
9140
  const ac = abortRef.current;
9131
9141
  if (ac) {
@@ -9144,11 +9154,11 @@ function useChatEngine(opts) {
9144
9154
  store.del(STORAGE_PREFIX + threadRef.current);
9145
9155
  }
9146
9156
  }, [apiAdapter]);
9147
- const removeQueued = React40.useCallback((id) => {
9157
+ const removeQueued = React41.useCallback((id) => {
9148
9158
  queueRef.current = queueRef.current.filter((t) => t.id !== id);
9149
9159
  setQueue(queueRef.current.slice());
9150
9160
  }, []);
9151
- const retry = React40.useCallback(() => {
9161
+ const retry = React41.useCallback(() => {
9152
9162
  const list = listRef.current;
9153
9163
  let at = -1;
9154
9164
  for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
@@ -9164,19 +9174,19 @@ function useChatEngine(opts) {
9164
9174
  setQueue(queueRef.current.slice());
9165
9175
  drain();
9166
9176
  }, []);
9167
- const clear = React40.useCallback(() => {
9177
+ const clear = React41.useCallback(() => {
9168
9178
  commit([]);
9169
9179
  serverCount.current = 0;
9170
9180
  queueRef.current = [];
9171
9181
  setQueue([]);
9172
9182
  onClear && onClear();
9173
9183
  }, [onClear]);
9174
- const setFeedback = React40.useCallback((id, value) => {
9184
+ const setFeedback = React41.useCallback((id, value) => {
9175
9185
  patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
9176
9186
  const msg = listRef.current.find((m) => m.id === id);
9177
9187
  onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
9178
9188
  }, [onFeedback]);
9179
- const reload = React40.useCallback(async () => {
9189
+ const reload = React41.useCallback(async () => {
9180
9190
  if (!threadRef.current) return;
9181
9191
  setStatus("loading");
9182
9192
  try {
@@ -9214,10 +9224,10 @@ var ChatKit = {
9214
9224
  };
9215
9225
 
9216
9226
  // src/components/chat/ChatTranscript.tsx
9217
- var React42 = __toESM(require("react"), 1);
9227
+ var React43 = __toESM(require("react"), 1);
9218
9228
 
9219
9229
  // src/components/chat/ChatTurn.tsx
9220
- var React41 = __toESM(require("react"), 1);
9230
+ var React42 = __toESM(require("react"), 1);
9221
9231
  var import_jsx_runtime73 = require("react/jsx-runtime");
9222
9232
  function JsonView({ value }) {
9223
9233
  let text;
@@ -9254,7 +9264,7 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
9254
9264
  ] });
9255
9265
  }
9256
9266
  function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
9257
- const [open, setOpen] = React41.useState(defaultOpen);
9267
+ const [open, setOpen] = React42.useState(defaultOpen);
9258
9268
  if (!text) return null;
9259
9269
  return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "fdc-think" + (open ? " is-open" : ""), children: [
9260
9270
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
@@ -9271,7 +9281,7 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
9271
9281
  ] });
9272
9282
  }
9273
9283
  function Citations({ items = [], onOpen }) {
9274
- const [open, setOpen] = React41.useState(false);
9284
+ const [open, setOpen] = React42.useState(false);
9275
9285
  if (!items.length) return null;
9276
9286
  return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "fdc-cites", children: [
9277
9287
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
@@ -9297,7 +9307,7 @@ function clampText(text, max) {
9297
9307
  return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
9298
9308
  }
9299
9309
  function MessageBody({ message: m, ctx }) {
9300
- const [expanded, setExpanded] = React41.useState(false);
9310
+ const [expanded, setExpanded] = React42.useState(false);
9301
9311
  const isUser = m.role === "user";
9302
9312
  const raw = m.text || "";
9303
9313
  const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
@@ -9364,9 +9374,9 @@ function MessageBody({ message: m, ctx }) {
9364
9374
  ] });
9365
9375
  }
9366
9376
  function useCopyRun() {
9367
- const [done, setDone] = React41.useState(false);
9368
- const t = React41.useRef(null);
9369
- React41.useEffect(() => () => {
9377
+ const [done, setDone] = React42.useState(false);
9378
+ const t = React42.useRef(null);
9379
+ React42.useEffect(() => () => {
9370
9380
  if (t.current) clearTimeout(t.current);
9371
9381
  }, []);
9372
9382
  return [done, (text) => {
@@ -9393,7 +9403,7 @@ function RunActions({ group, ctx }) {
9393
9403
  ] }),
9394
9404
  isAssistant && ctx.onRetry ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
9395
9405
  group.role === "user" && ctx.onEdit ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
9396
- isAssistant && ctx.onFeedback ? /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(React41.Fragment, { children: [
9406
+ isAssistant && ctx.onFeedback ? /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(React42.Fragment, { children: [
9397
9407
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("button", { type: "button", className: "fdc-act" + (fb === "up" ? " is-on" : ""), onClick: () => ctx.onFeedback(last.id, "up"), "aria-pressed": fb === "up", "aria-label": "Good response", children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
9398
9408
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("button", { type: "button", className: "fdc-act" + (fb === "down" ? " is-on" : ""), onClick: () => ctx.onFeedback(last.id, "down"), "aria-pressed": fb === "down", "aria-label": "Bad response", children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
9399
9409
  ] }) : null,
@@ -9488,10 +9498,10 @@ function ChatTranscript({
9488
9498
  renderEmpty,
9489
9499
  className = ""
9490
9500
  }) {
9491
- const scroller = React42.useRef(null);
9492
- const stick = React42.useRef(true);
9493
- const [pill, setPill] = React42.useState(0);
9494
- const seen = React42.useRef(0);
9501
+ const scroller = React43.useRef(null);
9502
+ const stick = React43.useRef(true);
9503
+ const [pill, setPill] = React43.useState(0);
9504
+ const seen = React43.useRef(0);
9495
9505
  const toBottom = (smooth) => {
9496
9506
  const el = scroller.current;
9497
9507
  if (!el) return;
@@ -9510,7 +9520,7 @@ function ChatTranscript({
9510
9520
  seen.current = messages.length;
9511
9521
  }
9512
9522
  };
9513
- React42.useLayoutEffect(() => {
9523
+ React43.useLayoutEffect(() => {
9514
9524
  const el = scroller.current;
9515
9525
  if (!el) return;
9516
9526
  if (stick.current) {
@@ -9518,7 +9528,7 @@ function ChatTranscript({
9518
9528
  seen.current = messages.length;
9519
9529
  } else setPill(Math.max(0, messages.length - seen.current));
9520
9530
  }, [messages]);
9521
- React42.useEffect(() => {
9531
+ React43.useEffect(() => {
9522
9532
  const el = scroller.current;
9523
9533
  const inner = el && el.firstChild;
9524
9534
  if (!el || !inner || typeof ResizeObserver === "undefined") return;
@@ -9528,7 +9538,7 @@ function ChatTranscript({
9528
9538
  ro.observe(inner);
9529
9539
  return () => ro.disconnect();
9530
9540
  }, []);
9531
- const groups = React42.useMemo(() => groupMessages(messages), [messages]);
9541
+ const groups = React43.useMemo(() => groupMessages(messages), [messages]);
9532
9542
  const empty = !messages.length && status === "ready";
9533
9543
  return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
9534
9544
  /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
@@ -9552,7 +9562,7 @@ function ChatTranscript({
9552
9562
  const prev = groups[i - 1];
9553
9563
  const k = dayKey(g.messages[0].timestamp);
9554
9564
  const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
9555
- return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(React42.Fragment, { children: [
9565
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(React43.Fragment, { children: [
9556
9566
  showDay ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "fdc-day", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { children: dayLabel(k) }) }) : null,
9557
9567
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ChatTurn, { group: g, ctx })
9558
9568
  ] }, g.key || i);
@@ -9569,7 +9579,7 @@ function ChatTranscript({
9569
9579
  var TranscriptKit = { groupMessages };
9570
9580
 
9571
9581
  // src/components/chat/ChatComposer.tsx
9572
- var React43 = __toESM(require("react"), 1);
9582
+ var React44 = __toESM(require("react"), 1);
9573
9583
  var import_jsx_runtime75 = require("react/jsx-runtime");
9574
9584
  function ChatComposer({
9575
9585
  onSubmit,
@@ -9597,17 +9607,17 @@ function ChatComposer({
9597
9607
  onReject,
9598
9608
  onOpenAttachment
9599
9609
  }) {
9600
- const [text, setText] = React43.useState(draft || "");
9601
- const [trigger, setTrigger] = React43.useState(null);
9602
- const [mentionItems, setMentionItems] = React43.useState([]);
9603
- const [listening, setListening] = React43.useState(false);
9604
- const [notice, setNotice] = React43.useState(null);
9605
- const editor = React43.useRef(null);
9606
- const wrap = React43.useRef(null);
9607
- const stopVoice = React43.useRef(null);
9610
+ const [text, setText] = React44.useState(draft || "");
9611
+ const [trigger, setTrigger] = React44.useState(null);
9612
+ const [mentionItems, setMentionItems] = React44.useState([]);
9613
+ const [listening, setListening] = React44.useState(false);
9614
+ const [notice, setNotice] = React44.useState(null);
9615
+ const editor = React44.useRef(null);
9616
+ const wrap = React44.useRef(null);
9617
+ const stopVoice = React44.useRef(null);
9608
9618
  const staged = useStagedFiles(fileUploadHandler, { onError: () => {
9609
9619
  } });
9610
- React43.useEffect(() => {
9620
+ React44.useEffect(() => {
9611
9621
  if (draft != null && draft !== text) setText(draft);
9612
9622
  }, [draft]);
9613
9623
  const change = (v) => {
@@ -9641,7 +9651,7 @@ function ChatComposer({
9641
9651
  e.preventDefault();
9642
9652
  staged.add(found.files);
9643
9653
  };
9644
- React43.useEffect(() => {
9654
+ React44.useEffect(() => {
9645
9655
  if (!trigger || trigger.type !== "mention" || !mentionSources) {
9646
9656
  setMentionItems([]);
9647
9657
  return;
@@ -9659,7 +9669,7 @@ function ChatComposer({
9659
9669
  const q = (trigger.query || "").toLowerCase();
9660
9670
  setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
9661
9671
  }, [trigger, mentionSources]);
9662
- const slashItems = React43.useMemo(() => {
9672
+ const slashItems = React44.useMemo(() => {
9663
9673
  if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
9664
9674
  const q = (trigger.query || "").toLowerCase();
9665
9675
  return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
@@ -9833,12 +9843,12 @@ function ChatComposer({
9833
9843
  }
9834
9844
 
9835
9845
  // src/components/chat/ChatSessionBar.tsx
9836
- var React44 = __toESM(require("react"), 1);
9846
+ var React45 = __toESM(require("react"), 1);
9837
9847
  var import_jsx_runtime76 = require("react/jsx-runtime");
9838
9848
  var compact2 = meterFormats.compact;
9839
9849
  function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
9840
- const [open, setOpen] = React44.useState(false);
9841
- const anchor = React44.useRef(null);
9850
+ const [open, setOpen] = React45.useState(false);
9851
+ const anchor = React45.useRef(null);
9842
9852
  const stats = sessionStats || null;
9843
9853
  const cu = contextUsage || null;
9844
9854
  const limits = usageLimits || null;
@@ -9853,7 +9863,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
9853
9863
  if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
9854
9864
  if (cu) bits.push(pct + "% context");
9855
9865
  const expandable = !!(cu || limits);
9856
- return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(React44.Fragment, { children: [
9866
+ return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(React45.Fragment, { children: [
9857
9867
  /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "fdc-bar", children: [
9858
9868
  /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
9859
9869
  "button",
@@ -9994,7 +10004,7 @@ function ModelControls({
9994
10004
  ] })
9995
10005
  });
9996
10006
  }
9997
- return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(React44.Fragment, { children: [
10007
+ return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(React45.Fragment, { children: [
9998
10008
  /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
9999
10009
  MenuButton,
10000
10010
  {
@@ -10111,11 +10121,11 @@ function AgentChatPanel({
10111
10121
  onFeedback,
10112
10122
  onEditMessage
10113
10123
  }) {
10114
- const [panelWidth, setPanelWidth] = React45.useState(width);
10115
- const [applied, setApplied] = React45.useState({});
10116
- const [draft, setDraft] = React45.useState("");
10117
- const dragging = React45.useRef(null);
10118
- React45.useEffect(() => setPanelWidth(width), [width]);
10124
+ const [panelWidth, setPanelWidth] = React46.useState(width);
10125
+ const [applied, setApplied] = React46.useState({});
10126
+ const [draft, setDraft] = React46.useState("");
10127
+ const dragging = React46.useRef(null);
10128
+ React46.useEffect(() => setPanelWidth(width), [width]);
10119
10129
  const engine = useChatEngine({
10120
10130
  contextType,
10121
10131
  contextId,
@@ -10319,7 +10329,7 @@ function AgentChatPanel({
10319
10329
  }
10320
10330
 
10321
10331
  // src/kits/query.ts
10322
- var React46 = __toESM(require("react"), 1);
10332
+ var React47 = __toESM(require("react"), 1);
10323
10333
  function eqFilter(get2) {
10324
10334
  return (row, value) => Array.isArray(value) ? value.includes(get2(row)) : get2(row) === value;
10325
10335
  }
@@ -10351,22 +10361,22 @@ function compare(a, b, dir) {
10351
10361
  var API = null;
10352
10362
  var PREFS = null;
10353
10363
  function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
10354
- const [query, setQuery] = React46.useState(() => {
10364
+ const [query, setQuery] = React47.useState(() => {
10355
10365
  const store = PREFS || window.PlannerPrefs;
10356
10366
  const saved = prefsKey && store ? store.getTable(prefsKey) : {};
10357
10367
  return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
10358
10368
  });
10359
- const savePref = React46.useCallback((patch2) => {
10369
+ const savePref = React47.useCallback((patch2) => {
10360
10370
  const store = PREFS || window.PlannerPrefs;
10361
10371
  if (prefsKey && store) store.setTable(prefsKey, patch2);
10362
10372
  }, [prefsKey]);
10363
- const [res, setRes] = React46.useState(null);
10364
- const [loading, setLoading] = React46.useState(true);
10365
- const seq2 = React46.useRef(0);
10373
+ const [res, setRes] = React47.useState(null);
10374
+ const [loading, setLoading] = React47.useState(true);
10375
+ const seq2 = React47.useRef(0);
10366
10376
  const depKey = (deps || []).join("|");
10367
10377
  const paramKey = JSON.stringify(params || {});
10368
10378
  const queryKey = JSON.stringify(query);
10369
- React46.useEffect(() => {
10379
+ React47.useEffect(() => {
10370
10380
  const id = ++seq2.current;
10371
10381
  setLoading(true);
10372
10382
  const t = setTimeout(() => {