@ai-matrx/design-system 0.18.21 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/content-transfer/alchemy.svg +1 -1
  3. package/dist/content-transfer/copy-transform.svg +1 -0
  4. package/dist/content-transfer/icon.cjs +8 -2
  5. package/dist/content-transfer/icon.cjs.map +1 -1
  6. package/dist/content-transfer/icon.d.cts +5 -3
  7. package/dist/content-transfer/icon.d.ts +5 -3
  8. package/dist/content-transfer/icon.js +8 -2
  9. package/dist/content-transfer/icon.js.map +1 -1
  10. package/dist/content-transfer/portal.svg +1 -0
  11. package/dist/content-transfer.cjs +923 -304
  12. package/dist/content-transfer.cjs.map +1 -1
  13. package/dist/content-transfer.css +17 -74
  14. package/dist/content-transfer.d.cts +14 -3
  15. package/dist/content-transfer.d.ts +14 -3
  16. package/dist/content-transfer.js +929 -305
  17. package/dist/content-transfer.js.map +1 -1
  18. package/dist/data-table/copy-helpers.d.cts +1 -1
  19. package/dist/data-table/copy-helpers.d.ts +1 -1
  20. package/dist/data-table/data-row-inspector.cjs +990 -397
  21. package/dist/data-table/data-row-inspector.cjs.map +1 -1
  22. package/dist/data-table/data-row-inspector.js +988 -390
  23. package/dist/data-table/data-row-inspector.js.map +1 -1
  24. package/dist/data-table/data-row-window.cjs +989 -396
  25. package/dist/data-table/data-row-window.cjs.map +1 -1
  26. package/dist/data-table/data-row-window.js +987 -389
  27. package/dist/data-table/data-row-window.js.map +1 -1
  28. package/dist/data-table/filter-engine.d.cts +1 -1
  29. package/dist/data-table/filter-engine.d.ts +1 -1
  30. package/dist/data-table/host.cjs.map +1 -1
  31. package/dist/data-table/host.d.cts +3 -2
  32. package/dist/data-table/host.d.ts +3 -2
  33. package/dist/data-table/host.js.map +1 -1
  34. package/dist/data-table/index.cjs +2733 -1441
  35. package/dist/data-table/index.cjs.map +1 -1
  36. package/dist/data-table/index.d.cts +2 -2
  37. package/dist/data-table/index.d.ts +2 -2
  38. package/dist/data-table/index.js +2742 -1440
  39. package/dist/data-table/index.js.map +1 -1
  40. package/dist/data-table/infer-filter.d.cts +1 -1
  41. package/dist/data-table/infer-filter.d.ts +1 -1
  42. package/dist/data-table/layered-filters.d.cts +1 -1
  43. package/dist/data-table/layered-filters.d.ts +1 -1
  44. package/dist/data-table/pagination.cjs +135 -97
  45. package/dist/data-table/pagination.cjs.map +1 -1
  46. package/dist/data-table/pagination.d.cts +8 -1
  47. package/dist/data-table/pagination.d.ts +8 -1
  48. package/dist/data-table/pagination.js +130 -92
  49. package/dist/data-table/pagination.js.map +1 -1
  50. package/dist/data-table/query-control.d.cts +1 -1
  51. package/dist/data-table/query-control.d.ts +1 -1
  52. package/dist/data-table/scroll-pagination.cjs +82 -54
  53. package/dist/data-table/scroll-pagination.cjs.map +1 -1
  54. package/dist/data-table/scroll-pagination.js +82 -54
  55. package/dist/data-table/scroll-pagination.js.map +1 -1
  56. package/dist/data-table/types.cjs.map +1 -1
  57. package/dist/data-table/types.d.cts +1 -1
  58. package/dist/data-table/types.d.ts +1 -1
  59. package/dist/data-table/url-state.cjs +7 -1
  60. package/dist/data-table/url-state.cjs.map +1 -1
  61. package/dist/data-table/url-state.d.cts +1 -1
  62. package/dist/data-table/url-state.d.ts +1 -1
  63. package/dist/data-table/url-state.js +7 -1
  64. package/dist/data-table/url-state.js.map +1 -1
  65. package/dist/data-table/uuid-cell.cjs +1 -1
  66. package/dist/data-table/uuid-cell.cjs.map +1 -1
  67. package/dist/data-table/uuid-cell.js +1 -1
  68. package/dist/data-table/uuid-cell.js.map +1 -1
  69. package/dist/data-table/xlsx.d.cts +1 -1
  70. package/dist/data-table/xlsx.d.ts +1 -1
  71. package/dist/index.cjs +527 -0
  72. package/dist/index.cjs.map +1 -1
  73. package/dist/index.d.cts +1 -0
  74. package/dist/index.d.ts +1 -0
  75. package/dist/index.js +531 -0
  76. package/dist/index.js.map +1 -1
  77. package/dist/tap-target.cjs +636 -0
  78. package/dist/tap-target.cjs.map +1 -0
  79. package/dist/tap-target.css +151 -0
  80. package/dist/tap-target.d.cts +131 -0
  81. package/dist/tap-target.d.ts +131 -0
  82. package/dist/tap-target.js +608 -0
  83. package/dist/tap-target.js.map +1 -0
  84. package/dist/{types-BuDKVpeF.d.ts → types-D1m14boM.d.ts} +49 -3
  85. package/dist/{types-Dqcb7jXO.d.cts → types-Di6QT0P1.d.cts} +49 -3
  86. package/package.json +14 -1
@@ -35,7 +35,7 @@ __export(DataRowWindow_exports, {
35
35
  DataRowWindow: () => DataRowWindow
36
36
  });
37
37
  module.exports = __toCommonJS(DataRowWindow_exports);
38
- var import_react4 = require("react");
38
+ var import_react5 = require("react");
39
39
 
40
40
  // src/dialog.tsx
41
41
  var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"), 1);
@@ -378,7 +378,7 @@ function DefaultTableWindow({ title, onClose, width = 720, height = 560, actions
378
378
  // src/data-table/icons.tsx
379
379
  var import_jsx_runtime6 = require("react/jsx-runtime");
380
380
  function Icon({ children, ...props }) {
381
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", ...props, children });
381
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", ...props, children });
382
382
  }
383
383
  var Check = (p) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { ...p, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m5 12 4 4L19 6" }) });
384
384
  var Pencil = (p) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { ...p, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m4 20 4-1 11-11-3-3L5 16l-1 4z" }) });
@@ -409,11 +409,11 @@ function useMatrxDataTableHost() {
409
409
  }
410
410
 
411
411
  // src/content-transfer/matrx-copy.tsx
412
- var React8 = __toESM(require("react"), 1);
412
+ var React9 = __toESM(require("react"), 1);
413
413
  var import_content_transfer2 = require("@ai-matrx/kit/content-transfer");
414
414
 
415
415
  // src/content-transfer/index.tsx
416
- var React7 = __toESM(require("react"), 1);
416
+ var React8 = __toESM(require("react"), 1);
417
417
  var import_react_dom = require("react-dom");
418
418
  var import_content_transfer = require("@ai-matrx/kit/content-transfer");
419
419
 
@@ -528,81 +528,620 @@ var PopoverContent = React6.forwardRef(
528
528
  );
529
529
  PopoverContent.displayName = PopoverPrimitive.Content.displayName;
530
530
 
531
+ // src/tap-target/tap-target-button.tsx
532
+ var import_react2 = require("react");
533
+
534
+ // src/tooltip.tsx
535
+ var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"), 1);
536
+ var React7 = __toESM(require("react"), 1);
537
+ var import_jsx_runtime10 = require("react/jsx-runtime");
538
+ var TooltipProvider = TooltipPrimitive.Provider;
539
+ var Tooltip = TooltipPrimitive.Root;
540
+ var TooltipTrigger = TooltipPrimitive.Trigger;
541
+ var TooltipContent = React7.forwardRef(({ className, sideOffset = 4, container, animated = true, ...props }, ref) => {
542
+ const resolved = usePortalContainer(container);
543
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TooltipPrimitive.Portal, { container: resolved ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
544
+ TooltipPrimitive.Content,
545
+ {
546
+ ref,
547
+ "data-slot": "tooltip-content",
548
+ sideOffset,
549
+ className: cn(
550
+ "z-[10001] overflow-hidden rounded-md border border-border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md",
551
+ animated && MOTION_POPPER,
552
+ className
553
+ ),
554
+ ...props
555
+ }
556
+ ) });
557
+ });
558
+ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
559
+
560
+ // src/tap-target/cn.ts
561
+ function cn2(...values) {
562
+ return values.filter(Boolean).join(" ").trim();
563
+ }
564
+
565
+ // src/tap-target/link.ts
566
+ var LINK_SLOT = /* @__PURE__ */ Symbol.for("@ai-matrx/tap-target:link-component");
567
+ function getTapTargetLinkComponent() {
568
+ return globalThis[LINK_SLOT] ?? null;
569
+ }
570
+
571
+ // src/tap-target/tap-target-button.tsx
572
+ var import_jsx_runtime11 = require("react/jsx-runtime");
573
+ var EXTERNAL_RE = /^(https?:|mailto:|tel:)/i;
574
+ var TAP_OUTER_CLASS = "matrx-tap-target group";
575
+ var TAP_GROUP_OUTER_CLASS = "matrx-tap-target matrx-tap-target-sm group";
576
+ function IconContent({
577
+ icon,
578
+ children,
579
+ strokeWidth = 2,
580
+ className
581
+ }) {
582
+ if (icon) {
583
+ if ((0, import_react2.isValidElement)(icon)) {
584
+ return (0, import_react2.cloneElement)(icon, {
585
+ className: cn2(className, icon.props.className)
586
+ });
587
+ }
588
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className, children: icon });
589
+ }
590
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
591
+ "svg",
592
+ {
593
+ className,
594
+ fill: "none",
595
+ viewBox: "0 0 24 24",
596
+ stroke: "currentColor",
597
+ strokeWidth,
598
+ children
599
+ }
600
+ );
601
+ }
602
+ function resolveTapGeometry(label, size, mobileIconOnly) {
603
+ const inline = Boolean(label);
604
+ if (size === "sm") {
605
+ return {
606
+ outerClassName: inline && mobileIconOnly ? "matrx-tap-target matrx-tap-target-sm matrx-tap-target-mobile-icon-only-sm group" : inline ? "matrx-tap-target matrx-tap-target-sm matrx-tap-target-inline-sm group" : TAP_GROUP_OUTER_CLASS,
607
+ inlineModifier: mobileIconOnly ? "matrx-tap-pill-mobile-icon-only-sm" : "matrx-tap-pill-inline-sm"
608
+ };
609
+ }
610
+ return {
611
+ outerClassName: inline && mobileIconOnly ? `${TAP_OUTER_CLASS} matrx-tap-target-mobile-icon-only` : inline ? `${TAP_OUTER_CLASS} matrx-tap-target-inline` : TAP_OUTER_CLASS,
612
+ inlineModifier: mobileIconOnly ? "matrx-tap-pill-mobile-icon-only" : "matrx-tap-pill-inline"
613
+ };
614
+ }
615
+ function buildTapInner({
616
+ label,
617
+ pillClassName,
618
+ iconClassName,
619
+ labelClassName,
620
+ inlineModifier,
621
+ icon,
622
+ children,
623
+ strokeWidth = 2
624
+ }) {
625
+ const iconEl = /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
626
+ IconContent,
627
+ {
628
+ icon,
629
+ strokeWidth,
630
+ className: iconClassName,
631
+ children
632
+ }
633
+ );
634
+ const pillClasses = label ? `${pillClassName} ${inlineModifier}`.trim() : pillClassName;
635
+ if (!label) {
636
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: pillClasses, children: iconEl });
637
+ }
638
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: pillClasses, children: [
639
+ iconEl,
640
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: labelClassName ?? "matrx-tap-label", children: label })
641
+ ] });
642
+ }
643
+ function renderTapTarget({
644
+ size = "default",
645
+ pillClassName,
646
+ iconClassName,
647
+ labelClassName,
648
+ icon,
649
+ children,
650
+ strokeWidth,
651
+ label,
652
+ mobileIconOnly = false,
653
+ onClick,
654
+ as,
655
+ htmlFor,
656
+ ariaLabel,
657
+ disabled,
658
+ href,
659
+ target,
660
+ rel,
661
+ prefetch,
662
+ linkComponent,
663
+ tooltip,
664
+ tooltipSide,
665
+ tooltipAlign,
666
+ rest,
667
+ buttonRef
668
+ }) {
669
+ const { outerClassName, inlineModifier } = resolveTapGeometry(
670
+ label,
671
+ size,
672
+ mobileIconOnly
673
+ );
674
+ const responsiveLabelClassName = mobileIconOnly ? `${labelClassName ?? "matrx-tap-label"} matrx-tap-label-mobile-icon-only` : labelClassName;
675
+ const inner = buildTapInner({
676
+ label,
677
+ pillClassName,
678
+ iconClassName,
679
+ labelClassName: responsiveLabelClassName,
680
+ inlineModifier: label ? inlineModifier : "",
681
+ icon,
682
+ children,
683
+ strokeWidth
684
+ });
685
+ const resolvedTooltip = tooltip !== void 0 ? tooltip : label ? false : void 0;
686
+ const triggerAriaLabel = label && !mobileIconOnly ? void 0 : ariaLabel ?? label;
687
+ const trigger = renderTrigger({
688
+ href,
689
+ target,
690
+ rel,
691
+ prefetch,
692
+ linkComponent,
693
+ as,
694
+ htmlFor,
695
+ onClick,
696
+ ariaLabel: triggerAriaLabel,
697
+ disabled,
698
+ outerClassName,
699
+ children: inner,
700
+ rest,
701
+ buttonRef
702
+ });
703
+ return withTooltip(trigger, {
704
+ tooltip: resolvedTooltip,
705
+ ariaLabel: triggerAriaLabel,
706
+ disabled,
707
+ tooltipSide,
708
+ tooltipAlign
709
+ });
710
+ }
711
+ function renderTrigger({
712
+ href,
713
+ target,
714
+ rel,
715
+ prefetch,
716
+ linkComponent,
717
+ as,
718
+ htmlFor,
719
+ onClick,
720
+ ariaLabel,
721
+ disabled,
722
+ outerClassName,
723
+ children,
724
+ rest,
725
+ buttonRef
726
+ }) {
727
+ if (disabled && href) {
728
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
729
+ "span",
730
+ {
731
+ "aria-disabled": "true",
732
+ "aria-label": ariaLabel,
733
+ className: `${outerClassName} opacity-40 pointer-events-none`,
734
+ children
735
+ }
736
+ );
737
+ }
738
+ if (href) {
739
+ const isExternal = EXTERNAL_RE.test(href);
740
+ if (isExternal) {
741
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
742
+ "a",
743
+ {
744
+ href,
745
+ target: target ?? "_blank",
746
+ rel: rel ?? "noopener noreferrer",
747
+ "aria-label": ariaLabel,
748
+ className: outerClassName,
749
+ children
750
+ }
751
+ );
752
+ }
753
+ const Link = linkComponent ?? getTapTargetLinkComponent();
754
+ if (Link) {
755
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
756
+ Link,
757
+ {
758
+ href,
759
+ target,
760
+ rel,
761
+ prefetch,
762
+ "aria-label": ariaLabel,
763
+ className: outerClassName,
764
+ children
765
+ }
766
+ );
767
+ }
768
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
769
+ "a",
770
+ {
771
+ href,
772
+ target,
773
+ rel,
774
+ "aria-label": ariaLabel,
775
+ className: outerClassName,
776
+ children
777
+ }
778
+ );
779
+ }
780
+ if (as === "label") {
781
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
782
+ "label",
783
+ {
784
+ htmlFor,
785
+ "aria-label": ariaLabel,
786
+ className: outerClassName,
787
+ children
788
+ }
789
+ );
790
+ }
791
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
792
+ "button",
793
+ {
794
+ ref: buttonRef,
795
+ type: "button",
796
+ onClick,
797
+ "aria-label": ariaLabel,
798
+ disabled,
799
+ ...rest,
800
+ className: outerClassName,
801
+ children
802
+ }
803
+ );
804
+ }
805
+ function withTooltip(trigger, {
806
+ tooltip,
807
+ ariaLabel,
808
+ disabled,
809
+ tooltipSide = "top",
810
+ tooltipAlign = "center"
811
+ }) {
812
+ if (tooltip === false) return trigger;
813
+ const label = typeof tooltip === "string" && tooltip.length > 0 ? tooltip : ariaLabel;
814
+ if (!label) return trigger;
815
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Tooltip, { children: [
816
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipTrigger, { asChild: true, children: disabled ? (
817
+ // Radix Tooltip triggers need a hoverable element; a disabled button
818
+ // does not dispatch pointer events, so we wrap in a span for the
819
+ // trigger target while keeping the disabled visual state.
820
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "inline-flex", children: trigger })
821
+ ) : trigger }),
822
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipContent, { side: tooltipSide, align: tooltipAlign, children: label })
823
+ ] });
824
+ }
825
+ var TapTargetButton = (0, import_react2.forwardRef)(function TapTargetButton2({
826
+ icon,
827
+ children,
828
+ strokeWidth = 2,
829
+ onClick,
830
+ className,
831
+ as,
832
+ htmlFor,
833
+ ariaLabel,
834
+ disabled,
835
+ href,
836
+ target,
837
+ rel,
838
+ prefetch,
839
+ linkComponent,
840
+ tooltip,
841
+ tooltipSide,
842
+ tooltipAlign,
843
+ label,
844
+ mobileIconOnly,
845
+ ...rest
846
+ }, ref) {
847
+ const color = className ?? "text-foreground";
848
+ return renderTapTarget({
849
+ icon,
850
+ children,
851
+ strokeWidth,
852
+ onClick,
853
+ as,
854
+ htmlFor,
855
+ ariaLabel,
856
+ disabled,
857
+ href,
858
+ target,
859
+ rel,
860
+ prefetch,
861
+ linkComponent,
862
+ tooltip,
863
+ tooltipSide,
864
+ tooltipAlign,
865
+ label,
866
+ mobileIconOnly,
867
+ pillClassName: "matrx-tap-pill matrx-glass-thin-border",
868
+ iconClassName: `matrx-tap-icon ${color}`,
869
+ rest,
870
+ buttonRef: ref
871
+ });
872
+ });
873
+ var TapTargetButtonTransparent = (0, import_react2.forwardRef)(function TapTargetButtonTransparent2({
874
+ icon,
875
+ children,
876
+ strokeWidth = 2,
877
+ onClick,
878
+ className,
879
+ as,
880
+ htmlFor,
881
+ ariaLabel,
882
+ disabled,
883
+ href,
884
+ target,
885
+ rel,
886
+ prefetch,
887
+ linkComponent,
888
+ tooltip,
889
+ tooltipSide,
890
+ tooltipAlign,
891
+ label,
892
+ mobileIconOnly,
893
+ ...rest
894
+ }, ref) {
895
+ const color = className ?? "text-foreground";
896
+ return renderTapTarget({
897
+ icon,
898
+ children,
899
+ strokeWidth,
900
+ onClick,
901
+ as,
902
+ htmlFor,
903
+ ariaLabel,
904
+ disabled,
905
+ href,
906
+ target,
907
+ rel,
908
+ prefetch,
909
+ linkComponent,
910
+ tooltip,
911
+ tooltipSide,
912
+ tooltipAlign,
913
+ label,
914
+ mobileIconOnly,
915
+ pillClassName: "matrx-tap-pill hover:bg-muted active:bg-muted-foreground/15",
916
+ iconClassName: `matrx-tap-icon ${color}`,
917
+ rest,
918
+ buttonRef: ref
919
+ });
920
+ });
921
+ var TapTargetButtonSolid = (0, import_react2.forwardRef)(function TapTargetButtonSolid2({
922
+ icon,
923
+ children,
924
+ strokeWidth = 2,
925
+ onClick,
926
+ as,
927
+ htmlFor,
928
+ ariaLabel,
929
+ disabled,
930
+ href,
931
+ target,
932
+ rel,
933
+ prefetch,
934
+ linkComponent,
935
+ bgColor = "bg-primary",
936
+ iconColor = "text-primary-foreground",
937
+ hoverBgColor = "hover:bg-primary/80",
938
+ activeBgColor = "active:brightness-90",
939
+ tooltip,
940
+ tooltipSide,
941
+ tooltipAlign,
942
+ label,
943
+ mobileIconOnly,
944
+ ...rest
945
+ }, ref) {
946
+ return renderTapTarget({
947
+ icon,
948
+ children,
949
+ strokeWidth,
950
+ onClick,
951
+ as,
952
+ htmlFor,
953
+ ariaLabel,
954
+ disabled,
955
+ href,
956
+ target,
957
+ rel,
958
+ prefetch,
959
+ linkComponent,
960
+ tooltip,
961
+ tooltipSide,
962
+ tooltipAlign,
963
+ label,
964
+ mobileIconOnly,
965
+ pillClassName: `matrx-tap-pill ${bgColor} ${iconColor} ${hoverBgColor} ${activeBgColor}`,
966
+ iconClassName: `matrx-tap-icon ${iconColor}`,
967
+ labelClassName: `matrx-tap-label ${iconColor}`,
968
+ rest,
969
+ buttonRef: ref
970
+ });
971
+ });
972
+ var TapTargetButtonDestructive = (0, import_react2.forwardRef)(function TapTargetButtonDestructive2({
973
+ bgColor = "bg-destructive",
974
+ iconColor = "text-destructive-foreground",
975
+ hoverBgColor = "hover:bg-destructive/90",
976
+ ...rest
977
+ }, ref) {
978
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
979
+ TapTargetButtonSolid,
980
+ {
981
+ ref,
982
+ bgColor,
983
+ iconColor,
984
+ hoverBgColor,
985
+ ...rest
986
+ }
987
+ );
988
+ });
989
+ var TapTargetButtonForGroup = (0, import_react2.forwardRef)(function TapTargetButtonForGroup2({
990
+ icon,
991
+ children,
992
+ strokeWidth = 2,
993
+ onClick,
994
+ className,
995
+ as,
996
+ htmlFor,
997
+ ariaLabel,
998
+ disabled,
999
+ href,
1000
+ target,
1001
+ rel,
1002
+ prefetch,
1003
+ linkComponent,
1004
+ tooltip,
1005
+ tooltipSide,
1006
+ tooltipAlign,
1007
+ label,
1008
+ mobileIconOnly,
1009
+ ...rest
1010
+ }, ref) {
1011
+ const color = className ?? "text-foreground";
1012
+ return renderTapTarget({
1013
+ size: "sm",
1014
+ icon,
1015
+ children,
1016
+ strokeWidth,
1017
+ onClick,
1018
+ as,
1019
+ htmlFor,
1020
+ ariaLabel,
1021
+ disabled,
1022
+ href,
1023
+ target,
1024
+ rel,
1025
+ prefetch,
1026
+ linkComponent,
1027
+ tooltip,
1028
+ tooltipSide,
1029
+ tooltipAlign,
1030
+ label,
1031
+ mobileIconOnly,
1032
+ pillClassName: "matrx-tap-pill matrx-tap-pill-sm matrx-glass-interactive",
1033
+ iconClassName: `matrx-tap-icon ${color}`,
1034
+ labelClassName: `matrx-tap-label ${color}`,
1035
+ rest,
1036
+ buttonRef: ref
1037
+ });
1038
+ });
1039
+
531
1040
  // src/content-transfer/icon.ts
532
- var ALCHEMY_GLYPH_PATHS = ["M9 3h6", "M10 3v6l-5.2 8.7A2 2 0 0 0 6.5 21h11a2 2 0 0 0 1.7-3.3L14 9V3", "M8 15h8"];
533
- var ALCHEMY_GLYPH_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">${ALCHEMY_GLYPH_PATHS.map((d) => `<path d="${d}"/>`).join("")}</svg>`;
1041
+ var ALCHEMY_GLYPH_PATHS = {
1042
+ portal: ["M10 4H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h4M14 4h4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-4M8 12h8m-3-3 3 3-3 3"],
1043
+ "copy-transform": ["M8 7V5a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v8M13 21H5a2 2 0 0 1-2-2V10a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v3m-5 4h11m-3-3 3 3-3 3"]
1044
+ };
1045
+ var svg = (paths) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">${paths.map((d) => `<path d="${d}"/>`).join("")}</svg>`;
1046
+ var ALCHEMY_GLYPH_SVG = svg(ALCHEMY_GLYPH_PATHS.portal);
1047
+ var ALCHEMY_COPY_TRANSFORM_SVG = svg(ALCHEMY_GLYPH_PATHS["copy-transform"]);
534
1048
 
535
1049
  // src/content-transfer/index.tsx
536
- var import_jsx_runtime10 = require("react/jsx-runtime");
537
- function AlchemyGlyph(props) {
538
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", ...props, children: ALCHEMY_GLYPH_PATHS.map((d) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d }, d)) });
1050
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1051
+ function AlchemyGlyph({ icon = "portal", ...props }) {
1052
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", ...props, children: ALCHEMY_GLYPH_PATHS[icon].map((d) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d }, d)) });
539
1053
  }
540
- var CapabilityContext = React7.createContext({});
541
- var useContentTransferCapabilities = () => React7.useContext(CapabilityContext);
542
- var SurfaceContext = React7.createContext(null);
1054
+ var CapabilityContext = React8.createContext({});
1055
+ var useContentTransferCapabilities = () => React8.useContext(CapabilityContext);
1056
+ var SurfaceContext = React8.createContext(null);
543
1057
  function MenuPresentation({ label, hint, icon: Icon2 }) {
544
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
545
- Icon2 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon2, { className: "matrx-alchemy-menu-icon" }) : null,
546
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
1058
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1059
+ Icon2 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon2, { className: "matrx-alchemy-menu-icon" }) : null,
1060
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
547
1061
  label,
548
- hint ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
1062
+ hint ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
549
1063
  ] })
550
1064
  ] });
551
1065
  }
1066
+ function DestinationPresentation({ action }) {
1067
+ const paths = {
1068
+ notes: "M5 3h14v18H5zM8 8h8M8 12h8M8 16h5",
1069
+ scratch: "M5 3h14v18H5zM9 12h6M12 9v6",
1070
+ document: "M6 3h8l4 4v14H6zM14 3v5h4M9 12h6M9 16h6",
1071
+ workbook: "M3 4h18v16H3zM3 9h18M9 4v16M15 9v11M3 15h18",
1072
+ task: "M9 6h11M9 12h11M9 18h11M3 6l1 1 2-2M3 12l1 1 2-2M3 18l1 1 2-2",
1073
+ attach: "m9 12 5-5a3 3 0 0 1 4 4l-7 7a5 5 0 0 1-7-7l8-8M7 14l7-7",
1074
+ code: "m8 6-6 6 6 6m8-12 6 6-6 6m-3-14-2 16",
1075
+ chat: "M4 4h16v13H9l-5 4zM8 9h8M8 13h5",
1076
+ assistant: "M3 4h18v16H3zM15 4v16M6 9h6M6 13h4",
1077
+ tools: "m14 4 3 3 4-1a6 6 0 0 1-8 7l-7 7-3-3 7-7a6 6 0 0 1 4-6z"
1078
+ };
1079
+ const path = paths[action.id.replace(/^matrx:/, "")];
1080
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1081
+ !action.icon ? path ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: path }) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PaletteGlyph, { file: true }) : null,
1082
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MenuPresentation, { ...action })
1083
+ ] });
1084
+ }
1085
+ function ReceiptLink({ target }) {
1086
+ return target?.href && /^(\/(?!\/)|https?:\/\/)/.test(target.href) ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("a", { className: "matrx-alchemy-receipt-link", href: target.href, children: [
1087
+ "Open ",
1088
+ target.kind
1089
+ ] }) : null;
1090
+ }
552
1091
  function PaletteGlyph({ format, ai = false, file = false, kind }) {
553
- if (kind === "ai-copy") return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
554
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { x: "5", y: "5", width: "11", height: "14", rx: "2" }),
555
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M9 3h6a2 2 0 0 1 2 2v10" }),
556
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m18.5 3 .55 1.45L20.5 5l-1.45.55L18.5 7l-.55-1.45L16.5 5l1.45-.55z" })
1092
+ if (kind === "ai-copy") return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1093
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("rect", { x: "5", y: "5", width: "11", height: "14", rx: "2" }),
1094
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M9 3h6a2 2 0 0 1 2 2v10" }),
1095
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "m18.5 3 .55 1.45L20.5 5l-1.45.55L18.5 7l-.55-1.45L16.5 5l1.45-.55z" })
557
1096
  ] });
558
- if (kind === "sliders") return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
559
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 6h16M4 12h16M4 18h16" }),
560
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M8 3v6M16 9v6M10 15v6" })
1097
+ if (kind === "sliders") return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1098
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M4 6h16M4 12h16M4 18h16" }),
1099
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M8 3v6M16 9v6M10 15v6" })
561
1100
  ] });
562
- if (ai) return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
563
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 5a3 3 0 1 0-5.997.125A4 4 0 0 0 3.5 10.9a4 4 0 0 0 .556 6.588A4 4 0 0 0 12 19" }),
564
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.503 5.775 4 4 0 0 1-.556 6.588A4 4 0 0 1 12 19" }),
565
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 5v14M8 9h1M15 9h1M8 15h1M15 15h1" })
1101
+ if (ai) return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1102
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M12 5a3 3 0 1 0-5.997.125A4 4 0 0 0 3.5 10.9a4 4 0 0 0 .556 6.588A4 4 0 0 0 12 19" }),
1103
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.503 5.775 4 4 0 0 1-.556 6.588A4 4 0 0 1 12 19" }),
1104
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M12 5v14M8 9h1M15 9h1M8 15h1M15 15h1" })
566
1105
  ] });
567
- if (file) return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
568
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M6 3h8l4 4v14H6z" }),
569
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 3v5h5M9 13h6M9 17h6" })
1106
+ if (file) return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1107
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M6 3h8l4 4v14H6z" }),
1108
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M14 3v5h5M9 13h6M9 17h6" })
570
1109
  ] });
571
- const path = format === "json" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
572
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M9 4C7 4 7 7 5 7v3c2 0 2 1 2 2s0 2-2 2v3c2 0 2 3 4 3" }),
573
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M15 4c2 0 2 3 4 3v3c-2 0-2 1-2 2s0 2 2 2v3c-2 0-2 3-4 3" })
574
- ] }) : format === "compact-json" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
575
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m14 10 7-7" }),
576
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M20 10h-6V4" }),
577
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m3 21 7-7" }),
578
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 14h6v6" })
579
- ] }) : format === "csv" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
580
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { x: "4", y: "4", width: "16", height: "16", rx: "1" }),
581
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 10h16M10 4v16" })
582
- ] }) : format === "tsv" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
583
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
584
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v6h6M8 13h2M14 13h2M8 17h2M14 17h2" })
585
- ] }) : format === "xlsx" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
586
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
587
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v6h6M8 13h8M8 17h8M12 11v8" })
588
- ] }) : format === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
589
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5z" }),
590
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v6h6M10 13l-2 2 2 2M14 17l2-2-2-2" })
591
- ] }) : format === "html" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M15 6h6M3 6h7M3 12h18M3 18h12" }) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 7V4h16v3M9 20h6M12 4v16" }) });
592
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: path });
1110
+ const path = format === "json" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1111
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M9 4C7 4 7 7 5 7v3c2 0 2 1 2 2s0 2-2 2v3c2 0 2 3 4 3" }),
1112
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M15 4c2 0 2 3 4 3v3c-2 0-2 1-2 2s0 2 2 2v3c-2 0-2 3-4 3" })
1113
+ ] }) : format === "compact-json" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1114
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "m14 10 7-7" }),
1115
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M20 10h-6V4" }),
1116
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "m3 21 7-7" }),
1117
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M4 14h6v6" })
1118
+ ] }) : format === "csv" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1119
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("rect", { x: "4", y: "4", width: "16", height: "16", rx: "1" }),
1120
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M4 10h16M10 4v16" })
1121
+ ] }) : format === "tsv" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1122
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1123
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M14 2v6h6M8 13h2M14 13h2M8 17h2M14 17h2" })
1124
+ ] }) : format === "xlsx" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1125
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1126
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M14 2v6h6M8 13h8M8 17h8M12 11v8" })
1127
+ ] }) : format === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1128
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5z" }),
1129
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M14 2v6h6M10 13l-2 2 2 2M14 17l2-2-2-2" })
1130
+ ] }) : format === "html" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M15 6h6M3 6h7M3 12h18M3 18h12" }) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M4 7V4h16v3M9 20h6M12 4v16" }) });
1131
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: path });
593
1132
  }
594
1133
  function PaletteRows({ title, items, onRun, extra, ai = false, glyphKind, fallbackHint }) {
595
1134
  if (!items.length && !extra) return null;
596
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
597
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: title }),
1135
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
1136
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { children: title }),
598
1137
  items.map((item) => {
599
1138
  const label = item.copyLabel ?? item.label;
600
1139
  const hint = item.hint ?? fallbackHint;
601
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", className: cn("matrx-alchemy-palette-row", ai && "matrx-alchemy-palette-row-ai"), "aria-label": item.ariaLabel ?? `${label}${hint ? ` ${hint}` : ""}`, onClick: () => onRun?.(item), children: [
602
- item.icon ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(item.icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { ai, ...glyphKind ? { kind: glyphKind } : {} }),
603
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
1140
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: cn("matrx-alchemy-palette-row", ai && "matrx-alchemy-palette-row-ai"), "aria-label": item.ariaLabel ?? `${label}${hint ? ` ${hint}` : ""}`, onClick: () => onRun?.(item), children: [
1141
+ item.icon ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(item.icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PaletteGlyph, { ai, ...glyphKind ? { kind: glyphKind } : {} }),
1142
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
604
1143
  label,
605
- hint ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
1144
+ hint ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
606
1145
  ] })
607
1146
  ] }, item.id);
608
1147
  }),
@@ -645,10 +1184,10 @@ function snapshotContent(snapshot) {
645
1184
  return JSON.stringify({ sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits });
646
1185
  }
647
1186
  function useFence() {
648
- const mounted = React7.useRef(true);
649
- const nextId = React7.useRef(0);
650
- const active = React7.useRef(/* @__PURE__ */ new Set());
651
- React7.useEffect(() => {
1187
+ const mounted = React8.useRef(true);
1188
+ const nextId = React8.useRef(0);
1189
+ const active = React8.useRef(/* @__PURE__ */ new Set());
1190
+ React8.useEffect(() => {
652
1191
  mounted.current = true;
653
1192
  return () => {
654
1193
  mounted.current = false;
@@ -657,14 +1196,14 @@ function useFence() {
657
1196
  active.current.clear();
658
1197
  };
659
1198
  }, []);
660
- const begin = React7.useCallback(() => {
1199
+ const begin = React8.useCallback(() => {
661
1200
  const controller = new AbortController();
662
1201
  active.current.add(controller);
663
1202
  return { controller, id: ++nextId.current };
664
1203
  }, []);
665
- const finish = React7.useCallback((controller) => active.current.delete(controller), []);
666
- const valid = React7.useCallback((id, controller) => mounted.current && !controller.signal.aborted && nextId.current === id, []);
667
- const abortAll = React7.useCallback(() => {
1204
+ const finish = React8.useCallback((controller) => active.current.delete(controller), []);
1205
+ const valid = React8.useCallback((id, controller) => mounted.current && !controller.signal.aborted && nextId.current === id, []);
1206
+ const abortAll = React8.useCallback(() => {
668
1207
  nextId.current += 1;
669
1208
  active.current.forEach((c) => c.abort());
670
1209
  active.current.clear();
@@ -693,45 +1232,47 @@ async function buildArtifact(draft, format, label) {
693
1232
  return (0, import_content_transfer.serialize)(draft, format, { spreadsheetSafe: format === "csv" || format === "tsv", filename: `${filenameFor(label)}.${extension}` });
694
1233
  }
695
1234
  function ContentTransferMenu(props) {
696
- const inherited = React7.useContext(CapabilityContext);
1235
+ const inherited = React8.useContext(CapabilityContext);
697
1236
  const identityKey = props.capabilities?.identityKey ?? inherited.identityKey;
698
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
1237
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
699
1238
  }
700
- function ContentTransferMenuSession({ source, surface, label, projection, sections, preferences, table, formatSources, sourceFormats = true, variants = EMPTY_VARIANTS, actions = [], capabilities: local, disabled, enabled = true, className, stopPropagation = true, hide = [], controllerRef }) {
701
- const triggerRef = React7.useRef(null);
702
- const inherited = React7.useContext(CapabilityContext);
703
- const nearestSurface = React7.useContext(SurfaceContext);
1239
+ function ContentTransferMenuSession({ source, surface, label, projection, sections, preferences, table, formatSources, sourceFormats = true, variants = EMPTY_VARIANTS, actions = [], capabilities: local, disabled, enabled = true, className, stopPropagation = true, hide = [], controllerRef, icon = "portal", triggerVariant = "transparent" }) {
1240
+ const triggerRef = React8.useRef(null);
1241
+ const inherited = React8.useContext(CapabilityContext);
1242
+ const nearestSurface = React8.useContext(SurfaceContext);
704
1243
  const fence = useFence();
705
- const [menuCapture, setMenuCapture] = React7.useState(null);
706
- const [menuStatus, setMenuStatus] = React7.useState("idle");
707
- const [workspaces, setWorkspaces] = React7.useState({});
708
- const [workspaceKey, setWorkspaceKey] = React7.useState(null);
709
- const [workspaceOpen, setWorkspaceOpen] = React7.useState(false);
710
- const workspaceCaptures = React7.useRef(/* @__PURE__ */ new Map());
711
- const externalWorkspaceKeys = React7.useRef(/* @__PURE__ */ new Set());
712
- const [notice, setNotice] = React7.useState(null);
713
- const [paletteOpen, setPaletteOpen] = React7.useState(false);
714
- const [mode, setMode] = React7.useState("copy");
715
- const scopes = React7.useMemo(() => table?.availableScopes ?? ["target"], [table]);
1244
+ const [menuCapture, setMenuCapture] = React8.useState(null);
1245
+ const [menuStatus, setMenuStatus] = React8.useState("idle");
1246
+ const [workspaces, setWorkspaces] = React8.useState({});
1247
+ const [workspaceKey, setWorkspaceKey] = React8.useState(null);
1248
+ const [workspaceOpen, setWorkspaceOpen] = React8.useState(false);
1249
+ const workspaceCaptures = React8.useRef(/* @__PURE__ */ new Map());
1250
+ const externalWorkspaceKeys = React8.useRef(/* @__PURE__ */ new Set());
1251
+ const [notice, setNotice] = React8.useState(null);
1252
+ const [receiptTarget, setReceiptTarget] = React8.useState();
1253
+ const [paletteOpen, setPaletteOpen] = React8.useState(false);
1254
+ const [mode, setMode] = React8.useState("copy");
1255
+ const scopes = React8.useMemo(() => table?.availableScopes ?? ["target"], [table]);
716
1256
  const initialScope = table?.initialScope ?? "target";
717
1257
  if (!scopes.includes(initialScope)) throw new Error("Alchemy initialScope must be included in availableScopes.");
718
1258
  const primary = surface ?? source ?? nearestSurface;
719
1259
  const sourceLabel = label ?? (surface?.surfaceName ?? (source && "label" in source ? source.label : nearestSurface?.surfaceName) ?? "content");
720
1260
  const primaryWorkspaceKey = `primary:${materialIdentity(primary)}`;
721
1261
  const nearestWorkspaceKey = source && !surface && nearestSurface ? `surface:${materialIdentity(nearestSurface)}` : null;
722
- const variantWorkspaceKeys = React7.useMemo(() => new Map(variants.map((variant) => [variant.id, `variant:${variant.id}:${materialIdentity(variant.source)}`])), [variants]);
1262
+ const variantWorkspaceKeys = React8.useMemo(() => new Map(variants.map((variant) => [variant.id, `variant:${variant.id}:${materialIdentity(variant.source)}`])), [variants]);
723
1263
  const transport = local?.transport ?? inherited.transport ?? (0, import_content_transfer.createBrowserTransport)();
724
1264
  const ai = local?.ai ?? inherited.ai;
725
- const providerPreferences = React7.useMemo(() => (0, import_content_transfer.resolveTransferPreferences)(inherited.preferences, local?.preferences), [inherited.preferences, local?.preferences]);
726
- const adapters = React7.useMemo(() => (0, import_content_transfer.resolveTransferRegistry)(BUILT_INS, inherited.formats ?? [], local?.formats ?? []).filter((x) => "build" in x), [inherited.formats, local?.formats]);
727
- const registeredActions = React7.useMemo(() => (0, import_content_transfer.resolveTransferRegistry)(inherited.actions ?? [], local?.actions ?? [], actions), [actions, inherited.actions, local?.actions]);
728
- React7.useMemo(() => (0, import_content_transfer.resolveTransferRegistry)(variants), [variants]);
729
- const report = React7.useCallback((result) => {
1265
+ const providerPreferences = React8.useMemo(() => (0, import_content_transfer.resolveTransferPreferences)(inherited.preferences, local?.preferences), [inherited.preferences, local?.preferences]);
1266
+ const adapters = React8.useMemo(() => (0, import_content_transfer.resolveTransferRegistry)(BUILT_INS, inherited.formats ?? [], local?.formats ?? []).filter((x) => "build" in x), [inherited.formats, local?.formats]);
1267
+ const registeredActions = React8.useMemo(() => (0, import_content_transfer.resolveTransferRegistry)(inherited.actions ?? [], local?.actions ?? [], actions), [actions, inherited.actions, local?.actions]);
1268
+ React8.useMemo(() => (0, import_content_transfer.resolveTransferRegistry)(variants), [variants]);
1269
+ const report = React8.useCallback((result) => {
730
1270
  inherited.onOutcome?.(result);
731
1271
  local?.onOutcome?.(result);
732
1272
  setNotice(outcomeMessage(result));
1273
+ setReceiptTarget("target" in result ? result.target : void 0);
733
1274
  }, [inherited, local]);
734
- React7.useEffect(() => {
1275
+ React8.useEffect(() => {
735
1276
  const valid = /* @__PURE__ */ new Set([primaryWorkspaceKey, ...nearestWorkspaceKey ? [nearestWorkspaceKey] : [], ...variantWorkspaceKeys.values(), ...externalWorkspaceKeys.current]);
736
1277
  setWorkspaces((current) => Object.fromEntries(Object.entries(current).filter(([key]) => valid.has(key))));
737
1278
  for (const key of workspaceCaptures.current.keys()) if (!valid.has(key)) workspaceCaptures.current.delete(key);
@@ -740,7 +1281,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
740
1281
  setWorkspaceOpen(false);
741
1282
  }
742
1283
  }, [nearestWorkspaceKey, primaryWorkspaceKey, variantWorkspaceKeys, workspaceKey]);
743
- const captureOne = React7.useCallback(async (material, scope, signal, applyMenuProjection = false, collectPages = true) => {
1284
+ const captureOne = React8.useCallback(async (material, scope, signal, applyMenuProjection = false, collectPages = true) => {
744
1285
  if (!material) throw new Error("Alchemy needs a source or a mounted transfer surface.");
745
1286
  let sourceMaterial;
746
1287
  if ("instanceId" in material) {
@@ -774,14 +1315,14 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
774
1315
  if (result.snapshot.payload.kind !== "rows") throw new Error("All-matching export requires tabular content.");
775
1316
  return { snapshot: (0, import_content_transfer.projectSnapshot)({ ...result.snapshot, payload: { kind: "rows", rows: collected.rows, columns: result.snapshot.payload.columns }, coverage: collected.coverage, omissions: [...collected.omissions] }, { rules: [] }), allMatching: result.allMatching, ...collected.error ? { collectionError: collected.error.message } : {} };
776
1317
  }, [preferences, projection, providerPreferences, sections, sourceLabel]);
777
- const capturePrimary = React7.useCallback((scope, signal) => captureOne(primary, scope, signal, true), [captureOne, primary]);
1318
+ const capturePrimary = React8.useCallback((scope, signal) => captureOne(primary, scope, signal, true), [captureOne, primary]);
778
1319
  workspaceCaptures.current.set(primaryWorkspaceKey, capturePrimary);
779
1320
  if (nearestWorkspaceKey && nearestSurface) workspaceCaptures.current.set(nearestWorkspaceKey, (scope, signal) => captureOne(nearestSurface, scope, signal, true));
780
1321
  for (const variant of variants) {
781
1322
  const key = variantWorkspaceKeys.get(variant.id);
782
1323
  workspaceCaptures.current.set(key, (scope, signal) => captureOne(variant.source, scope, signal, true));
783
1324
  }
784
- const preflight = React7.useCallback(async () => {
1325
+ const preflight = React8.useCallback(async () => {
785
1326
  const { controller, id } = fence.begin();
786
1327
  setMenuCapture(null);
787
1328
  setMenuStatus("loading");
@@ -800,7 +1341,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
800
1341
  fence.finish(controller);
801
1342
  }
802
1343
  }, [captureOne, fence, initialScope, primary]);
803
- const transfer = React7.useCallback(async (format, download, alternate) => {
1344
+ const transfer = React8.useCallback(async (format, download, alternate) => {
804
1345
  const { controller, id } = fence.begin();
805
1346
  try {
806
1347
  const explicit = alternate?.source ?? (typeof format === "string" && format !== "xlsx" ? formatSources?.[format] : void 0);
@@ -825,7 +1366,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
825
1366
  fence.finish(controller);
826
1367
  }
827
1368
  }, [captureOne, capturePrimary, fence, formatSources, initialScope, preferences, providerPreferences, report, transport]);
828
- const openWorkspace = React7.useCallback(
1369
+ const openWorkspace = React8.useCallback(
829
1370
  async (key = primaryWorkspaceKey, variant) => {
830
1371
  const variantMaterial = variant && "kind" in variant.source ? {
831
1372
  id: `variant:${key}`,
@@ -919,7 +1460,8 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
919
1460
  setWorkspaceOpen(true);
920
1461
  } catch (error) {
921
1462
  if (fence.valid(id, controller))
922
- setNotice(errorMessage(error, "Could not capture content"));
1463
+ setReceiptTarget(void 0);
1464
+ setNotice(errorMessage(error, "Could not capture content"));
923
1465
  } finally {
924
1466
  fence.finish(controller);
925
1467
  }
@@ -936,7 +1478,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
936
1478
  workspaces
937
1479
  ]
938
1480
  );
939
- React7.useImperativeHandle(controllerRef, () => ({
1481
+ React8.useImperativeHandle(controllerRef, () => ({
940
1482
  focusTrigger: () => triggerRef.current?.focus(),
941
1483
  prepare: async (requestedSource, options) => {
942
1484
  const requestedLabel = options?.label ?? ("label" in requestedSource ? requestedSource.label : "content");
@@ -945,14 +1487,15 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
945
1487
  await openWorkspace(requestedKey, { source: requestedSource, label: requestedLabel });
946
1488
  }
947
1489
  }), [openWorkspace]);
948
- const runAction = React7.useCallback(async (action) => {
1490
+ const runAction = React8.useCallback(async (action) => {
949
1491
  const { controller, id } = fence.begin();
950
1492
  try {
951
1493
  const actionSource = action.source;
952
1494
  const { snapshot } = actionSource ? await captureOne(actionSource, initialScope, controller.signal, true) : await capturePrimary(initialScope, controller.signal);
953
1495
  const resolved = (0, import_content_transfer.resolveTransferPreferences)(providerPreferences, preferences, snapshot.limits);
954
1496
  const draft = (0, import_content_transfer.applyTransferLimits)((0, import_content_transfer.createDraft)(snapshot), resolved.limits);
955
- if (!action.supports(snapshot)) throw new Error(`${action.label} is unavailable for this content.`);
1497
+ if (snapshot.coverage.status !== "complete" || draft.omissions.length) throw new Error("This content is partial or requires reductions. Open Prepare for AI to review it before sending it to a destination.");
1498
+ if (!action.supports(snapshot, draft)) throw new Error(`${action.label} is unavailable for this content.`);
956
1499
  const result = await action.run({ snapshot, draft, signal: controller.signal });
957
1500
  if (fence.valid(id, controller) && draft.snapshotId === snapshot.id) report(result);
958
1501
  } catch (error) {
@@ -967,99 +1510,128 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
967
1510
  const visibleCopies = sourceFormats ? COPIES.filter((f) => Boolean(formatSources?.[f]) || !["csv", "tsv"].includes(f) || payload?.kind === "rows") : [];
968
1511
  const visibleDownloads = sourceFormats ? DOWNLOADS.filter((f) => f !== "xlsx" && Boolean(formatSources?.[f]) || !["csv", "tsv", "xlsx"].includes(f) || payload?.kind === "rows") : [];
969
1512
  const visibleAdapters = sourceFormats && menuCapture ? adapters.filter((a) => a.supports(menuCapture.snapshot.payload)) : [];
970
- const visibleActions = menuCapture ? registeredActions.filter((a) => a.supports(menuCapture.snapshot)) : [];
1513
+ const visibleActions = menuCapture ? registeredActions.filter((a) => a.supports(menuCapture.snapshot, (0, import_content_transfer.applyTransferLimits)((0, import_content_transfer.createDraft)(menuCapture.snapshot), (0, import_content_transfer.resolveTransferPreferences)(providerPreferences, preferences, menuCapture.snapshot.limits).limits))) : [];
971
1514
  const downloadActions = visibleActions.filter((action) => action.placement === "download");
972
1515
  const ordinaryActions = visibleActions.filter((action) => action.placement !== "download");
1516
+ const preparedActions = registeredActions.filter((action) => action.prepared && !action.source);
973
1517
  const copyAvailable = !hide.includes("copy") && visibleCopies.length + visibleAdapters.length + quickVariants("copy").length > 0;
974
1518
  const downloadAvailable = !hide.includes("download") && visibleDownloads.length + visibleAdapters.length + downloadActions.length > 0;
975
1519
  const prepareAvailable = !hide.includes("prepare") && (quickVariants("ai").length > 0 || Boolean(primary) || Boolean(nearestWorkspaceKey) || variants.length > 0);
976
1520
  const resolvedMode = mode === "copy" && !copyAvailable ? "download" : mode === "download" && !downloadAvailable ? "copy" : mode;
1521
+ const nativeAiFormat = {
1522
+ id: "ai-context",
1523
+ label: "AI context",
1524
+ supports: () => true,
1525
+ build: async (draft) => {
1526
+ const json = (0, import_content_transfer.serialize)(draft, "json");
1527
+ return (0, import_content_transfer.sealTransferArtifact)({ snapshotId: draft.snapshotId, draftRevision: draft.revision, format: "ai-context", plainText: (0, import_content_transfer.buildAgentPayload)({ kind: "matrx_content", location: sourceLabel, description: "Captured content for an assistant", data: JSON.parse(json.plainText), attributes: { source: draft.sourceId } }), omissions: [...json.omissions] });
1528
+ }
1529
+ };
977
1530
  const closePalette = () => setPaletteOpen(false);
978
1531
  const tile = (id, label2, onClick, options = {}) => {
979
1532
  const presentation = options.action;
980
1533
  const Icon2 = presentation?.icon;
981
1534
  const fallbackLabel = options.file && !/^download\b/i.test(label2) ? `Download ${label2}` : label2;
982
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-tile", "aria-label": presentation?.ariaLabel ?? (presentation ? fallbackLabel : options.ariaLabel ?? `${resolvedMode === "copy" ? "Copy" : "Download"} ${label2}`), onClick: () => {
1535
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-tile", "aria-label": presentation?.ariaLabel ?? (presentation ? fallbackLabel : options.ariaLabel ?? `${resolvedMode === "copy" ? "Copy" : "Download"} ${label2}`), onClick: () => {
983
1536
  closePalette();
984
1537
  onClick();
985
1538
  }, children: [
986
- Icon2 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon2, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { ...!options.custom ? { format: id } : {}, ...options.ai ? { ai: true } : {}, ...options.file ? { file: true } : {} }),
987
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
1539
+ Icon2 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Icon2, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PaletteGlyph, { ...!options.custom ? { format: id } : {}, ...options.ai ? { ai: true } : {}, ...options.file ? { file: true } : {} }),
1540
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
988
1541
  label2,
989
- presentation?.hint ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: presentation.hint }) : null
1542
+ presentation?.hint ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("small", { className: "matrx-alchemy-menu-hint", children: presentation.hint }) : null
990
1543
  ] })
991
1544
  ] }, id);
992
1545
  };
993
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: cn("matrx-alchemy", className), onClick: stopPropagation ? (event) => event.stopPropagation() : void 0, children: [
994
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Popover, { open: paletteOpen, onOpenChange: (open) => {
1546
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: cn("matrx-alchemy", className), onClick: stopPropagation ? (event) => event.stopPropagation() : void 0, children: [
1547
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Popover, { open: paletteOpen, onOpenChange: (open) => {
995
1548
  setPaletteOpen(open);
996
1549
  if (open) {
997
1550
  setMode("copy");
998
1551
  void preflight();
999
1552
  }
1000
1553
  }, children: [
1001
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { ref: triggerRef, type: "button", className: "matrx-alchemy-trigger", disabled, "aria-label": `Copy, transform or export ${sourceLabel}`, title: "Alchemy \u2014 copy, transform, export", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AlchemyGlyph, {}) }) }),
1002
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(PopoverContent, { align: "end", className: "matrx-alchemy-menu matrx-alchemy-palette", "aria-label": "Alchemy output options", onCloseAutoFocus: () => triggerRef.current?.focus(), children: [
1003
- menuStatus === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "matrx-alchemy-palette-status", children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "matrx-alchemy-error", children: menuStatus }) : null,
1004
- copyAvailable || downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "matrx-alchemy-output", children: [
1005
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
1006
- copyAvailable && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
1007
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
1008
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
1554
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PopoverTrigger, { asChild: true, children: triggerVariant === "glass" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TapTargetButton, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "glass" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TapTargetButtonTransparent, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "transparent" }) }),
1555
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(PopoverContent, { align: "end", className: "matrx-alchemy-menu matrx-alchemy-palette", "aria-label": "Alchemy output options", onCloseAutoFocus: () => triggerRef.current?.focus(), children: [
1556
+ menuStatus === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "matrx-alchemy-palette-status", children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "matrx-alchemy-error", children: menuStatus }) : null,
1557
+ copyAvailable || downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("section", { className: "matrx-alchemy-output", children: [
1558
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
1559
+ copyAvailable && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
1560
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
1561
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
1009
1562
  ] }) : null,
1010
- resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1011
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
1563
+ resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1564
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
1012
1565
  visibleCopies.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets" }[format], () => void transfer(format, false), { ariaLabel: `Copy ${LABEL[format]}` })),
1013
1566
  visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, false), { custom: true }))
1014
1567
  ] }),
1015
- quickVariants("copy").length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
1568
+ quickVariants("copy").length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
1016
1569
  closePalette();
1017
1570
  void transfer("markdown", false, variant);
1018
1571
  } }) : null
1019
1572
  ] }) : null,
1020
- resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
1573
+ resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
1021
1574
  visibleDownloads.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets", xlsx: "Excel" }[format], () => void transfer(format, true), { ariaLabel: `Download ${LABEL[format]}` })),
1022
1575
  visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, true), { custom: true })),
1023
1576
  downloadActions.map((action) => tile(action.id, action.label, () => void runAction(action), { custom: true, action, file: true }))
1024
1577
  ] }) }) : null
1025
1578
  ] }) : null,
1026
- prepareAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1027
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", items: quickVariants("ai"), onRun: (variant) => {
1579
+ prepareAvailable ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1580
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", extra: sourceFormats ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
1581
+ closePalette();
1582
+ void transfer(nativeAiFormat, false);
1583
+ }, children: [
1584
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PaletteGlyph, { kind: "ai-copy" }),
1585
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
1586
+ "Copy with AI context",
1587
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Content, source and capture details" })
1588
+ ] })
1589
+ ] }) : null, items: quickVariants("ai"), onRun: (variant) => {
1028
1590
  closePalette();
1029
1591
  void transfer("markdown", false, variant);
1030
1592
  } }),
1031
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Edit and prepare", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": "Prepare for AI", onClick: () => {
1593
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PaletteRows, { title: "Edit and prepare", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": "Prepare for AI", onClick: () => {
1032
1594
  closePalette();
1033
1595
  void openWorkspace();
1034
1596
  }, children: [
1035
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { kind: "sliders" }),
1036
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
1597
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PaletteGlyph, { kind: "sliders" }),
1598
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
1037
1599
  "Prepare for AI",
1038
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Review and edit before copying" })
1600
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Review and edit before copying" })
1039
1601
  ] })
1040
1602
  ] }) })
1041
1603
  ] }) : null,
1042
- prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Other sources", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1043
- nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
1604
+ prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PaletteRows, { title: "Other sources", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1605
+ nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
1044
1606
  closePalette();
1045
1607
  void openWorkspace(nearestWorkspaceKey, { source: nearestSurface, label: nearestSurface.surfaceName });
1046
- }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Prepare this surface" }) }) : null,
1047
- variants.map((variant) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
1608
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "Prepare this surface" }) }) : null,
1609
+ variants.map((variant) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
1048
1610
  closePalette();
1049
1611
  void openWorkspace(variantWorkspaceKeys.get(variant.id), variant);
1050
- }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
1612
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
1051
1613
  ] }) }) : null,
1052
- ordinaryActions.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Actions", items: [], extra: ordinaryActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
1053
- closePalette();
1054
- void runAction(action);
1055
- }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MenuPresentation, { ...action, label: action.label }) }, action.id)) }) : null
1614
+ ["save", "chat", "other"].map((group) => {
1615
+ const entries = ordinaryActions.filter((action) => (action.group ?? "other") === group);
1616
+ return entries.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("details", { className: "matrx-alchemy-palette-destinations", children: [
1617
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("summary", { children: [
1618
+ group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : "Actions",
1619
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: entries.length })
1620
+ ] }),
1621
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { children: entries.map((action) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
1622
+ closePalette();
1623
+ void runAction(action);
1624
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DestinationPresentation, { action }) }, action.id)) })
1625
+ ] }, group) : null;
1626
+ })
1056
1627
  ] })
1057
1628
  ] }),
1058
- notice && triggerRef.current ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-feedback", children: [
1059
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { role: "status", children: notice }),
1060
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": "Dismiss Alchemy feedback", onClick: () => setNotice(null), children: "\xD7" })
1629
+ notice && triggerRef.current ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "matrx-alchemy-feedback", children: [
1630
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { role: "status", children: notice }),
1631
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ReceiptLink, { target: receiptTarget }),
1632
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", "aria-label": "Dismiss Alchemy feedback", onClick: () => setNotice(null), children: "\xD7" })
1061
1633
  ] }), triggerRef.current.ownerDocument.body) : null,
1062
- Object.values(workspaces).map((saved) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PreparationWorkspace, { restoreFocus: () => triggerRef.current?.focus(), open: workspaceOpen && workspaceKey === saved.key, state: saved, scopes, onClose: () => setWorkspaceOpen(false), onChange: (next) => setWorkspaces((current) => ({ ...current, [saved.key]: next })), transport, adapters, captureScope: workspaceCaptures.current.get(saved.key) ?? capturePrimary, ...ai ? { ai } : {}, onOutcome: report }, saved.key))
1634
+ Object.values(workspaces).map((saved) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PreparationWorkspace, { restoreFocus: () => triggerRef.current?.focus(), open: workspaceOpen && workspaceKey === saved.key, state: saved, scopes, onClose: () => setWorkspaceOpen(false), onChange: (next) => setWorkspaces((current) => ({ ...current, [saved.key]: next })), transport, adapters, actions: preparedActions, captureScope: workspaceCaptures.current.get(saved.key) ?? capturePrimary, ...ai ? { ai } : {}, onOutcome: report }, saved.key))
1063
1635
  ] });
1064
1636
  }
1065
1637
  function initialControls(state) {
@@ -1111,30 +1683,34 @@ function preview(draft, format) {
1111
1683
  const resolved = isBuiltInFormat(format) ? format : "plain";
1112
1684
  return (0, import_content_transfer.serialize)(draft, resolved === "xlsx" ? "tsv" : resolved, { spreadsheetSafe: resolved === "csv" || resolved === "tsv" || resolved === "xlsx" }).plainText;
1113
1685
  }
1114
- function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onChange, transport, ai, adapters, onOutcome, captureScope }) {
1686
+ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onChange, transport, ai, adapters, actions, onOutcome, captureScope }) {
1115
1687
  const fence = useFence();
1116
- const latest = React7.useRef(state);
1688
+ const latest = React8.useRef(state);
1117
1689
  latest.current = state;
1118
- const aiSession = React7.useRef(void 0);
1690
+ const aiSession = React8.useRef(void 0);
1119
1691
  if (!aiSession.current && ai) aiSession.current = ai.fork?.() ?? ai;
1120
- const [controls, setControls] = React7.useState(() => initialControls(state));
1121
- const [controlsHistory, setControlsHistory] = React7.useState([]);
1122
- const [pendingControls, setPendingControls] = React7.useState(null);
1692
+ const [controls, setControls] = React8.useState(() => initialControls(state));
1693
+ const [controlsHistory, setControlsHistory] = React8.useState([]);
1694
+ const [pendingControls, setPendingControls] = React8.useState(null);
1123
1695
  const requestedFormat = state.preferences.initialFormat;
1124
- const [format, setFormat] = React7.useState(() => isBuiltInFormat(requestedFormat) ? supportsBuiltIn(requestedFormat, state.draft.payload) ? requestedFormat : "plain" : adapters.some((adapter) => adapter.id === requestedFormat && adapter.supports(state.draft.payload)) ? requestedFormat : "plain");
1125
- const [buffer, setBuffer] = React7.useState(() => isBuiltInFormat(format) ? preview(state.draft, format) : "Preparing format preview\u2026");
1126
- const [bufferError, setBufferError] = React7.useState(null);
1127
- const [formatError, setFormatError] = React7.useState(null);
1128
- const [preparedArtifact, setPreparedArtifact] = React7.useState(null);
1129
- const [instruction, setInstruction] = React7.useState("");
1130
- const [busy, setBusy] = React7.useState(null);
1131
- const [aiFailed, setAiFailed] = React7.useState(false);
1132
- React7.useEffect(() => {
1696
+ const [format, setFormat] = React8.useState(() => isBuiltInFormat(requestedFormat) ? supportsBuiltIn(requestedFormat, state.draft.payload) ? requestedFormat : "plain" : adapters.some((adapter) => adapter.id === requestedFormat && adapter.supports(state.draft.payload)) ? requestedFormat : "plain");
1697
+ const [buffer, setBuffer] = React8.useState(() => isBuiltInFormat(format) ? preview(state.draft, format) : "Preparing format preview\u2026");
1698
+ const [bufferError, setBufferError] = React8.useState(null);
1699
+ const [formatError, setFormatError] = React8.useState(null);
1700
+ const [preparedArtifact, setPreparedArtifact] = React8.useState(null);
1701
+ const [instruction, setInstruction] = React8.useState("");
1702
+ const [busy, setBusy] = React8.useState(null);
1703
+ const [aiFailed, setAiFailed] = React8.useState(false);
1704
+ React8.useEffect(() => {
1133
1705
  setAiFailed(false);
1134
1706
  }, [state.snapshot.id, state.draft.revision]);
1135
- const activeAi = React7.useRef(null);
1136
- const activeCapture = React7.useRef(null);
1137
- React7.useEffect(() => {
1707
+ const handingOff = React8.useRef(false);
1708
+ React8.useEffect(() => {
1709
+ if (open) handingOff.current = false;
1710
+ }, [open]);
1711
+ const activeAi = React8.useRef(null);
1712
+ const activeCapture = React8.useRef(null);
1713
+ React8.useEffect(() => {
1138
1714
  if (bufferError) return;
1139
1715
  const adapter = adapters.find((candidate) => candidate.id === format);
1140
1716
  const controller = new AbortController();
@@ -1154,7 +1730,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1154
1730
  });
1155
1731
  return () => controller.abort();
1156
1732
  }, [adapters, bufferError, format, state.draft, state.snapshot.id]);
1157
- const close = React7.useCallback(() => {
1733
+ const close = React8.useCallback(() => {
1158
1734
  activeAi.current?.abort();
1159
1735
  activeCapture.current?.abort();
1160
1736
  activeAi.current = null;
@@ -1283,8 +1859,8 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1283
1859
  if (fence.valid(id, controller)) setBusy(null);
1284
1860
  }
1285
1861
  };
1286
- const [deliveryNotice, setDeliveryNotice] = React7.useState(null);
1287
- React7.useEffect(() => {
1862
+ const [deliveryNotice, setDeliveryNotice] = React8.useState(null);
1863
+ React8.useEffect(() => {
1288
1864
  setDeliveryNotice(null);
1289
1865
  }, [state.draft.revision]);
1290
1866
  const reportDelivery = (outcome) => {
@@ -1311,45 +1887,64 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1311
1887
  if (fence.valid(id, controller)) setBusy(null);
1312
1888
  }
1313
1889
  };
1890
+ const deliverAction = async (action) => {
1891
+ if (busy || bufferError || formatError || !preparedArtifact) return;
1892
+ const { controller, id } = fence.begin();
1893
+ const current = latest.current;
1894
+ setBusy("action");
1895
+ try {
1896
+ if (!action.supports(current.snapshot, current.draft)) throw new Error(`${action.label} is unavailable for this prepared content.`);
1897
+ handingOff.current = true;
1898
+ (0, import_react_dom.flushSync)(() => onClose());
1899
+ const result = await action.run({ snapshot: current.snapshot, draft: current.draft, signal: controller.signal });
1900
+ if (fence.valid(id, controller)) reportDelivery(result);
1901
+ } catch (error) {
1902
+ if (fence.valid(id, controller)) reportDelivery({ status: "error", code: "destination-failed", message: errorMessage(error, "Could not deliver prepared content"), retryable: false });
1903
+ } finally {
1904
+ fence.finish(controller);
1905
+ if (fence.valid(id, controller)) setBusy(null);
1906
+ }
1907
+ };
1908
+ const eligibleActions = actions.filter((action) => action.supports(state.snapshot, state.draft));
1314
1909
  const rows = state.original.payload.kind === "rows" ? state.original.payload : null;
1315
1910
  const formats = COPIES.filter((f) => supportsBuiltIn(f, state.draft.payload));
1316
1911
  const workspaceAdapters = adapters.filter((adapter) => adapter.supports(state.draft.payload));
1317
1912
  const displayedOmissions = preparedArtifact?.omissions ?? state.draft.omissions;
1318
1913
  const limitText = Object.entries(state.preferences.limits).filter(([, value]) => value != null).map(([key, value]) => `${key.replace(/^max/, "max ")} ${Number(value).toLocaleString()}`).join(" \xB7 ");
1319
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Dialog, { open, onOpenChange: (next) => {
1914
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Dialog, { open, onOpenChange: (next) => {
1320
1915
  if (!next) close();
1321
- }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogContent, { onCloseAutoFocus: (event) => {
1916
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DialogContent, { onCloseAutoFocus: (event) => {
1322
1917
  event.preventDefault();
1323
- restoreFocus();
1918
+ if (!handingOff.current) restoreFocus();
1324
1919
  }, className: "matrx-alchemy-workspace max-w-5xl", "aria-busy": busy !== null, children: [
1325
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogHeader, { children: [
1326
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogTitle, { children: [
1920
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DialogHeader, { children: [
1921
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DialogTitle, { children: [
1327
1922
  "Prepare ",
1328
1923
  state.snapshot.label
1329
1924
  ] }),
1330
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogDescription, { children: [
1925
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DialogDescription, { children: [
1331
1926
  state.snapshot.unsavedChanges ? "Includes your unsaved changes. " : "",
1332
1927
  "Review and edit this copy. Your original stays unchanged."
1333
1928
  ] })
1334
1929
  ] }),
1335
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
1336
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-workspace-grid", children: [
1337
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "matrx-alchemy-main", children: [
1338
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
1339
- scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
1930
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
1931
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "matrx-alchemy-workspace-grid", children: [
1932
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("section", { className: "matrx-alchemy-main", children: [
1933
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
1934
+ scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
1340
1935
  "Scope",
1341
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("select", { "aria-label": "Transfer scope", value: state.scope, disabled: busy !== null, onChange: (e) => void requestCapture(e.target.value), children: scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: scope, children: SCOPE_LABEL[scope] }, scope)) })
1936
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("select", { "aria-label": "Transfer scope", value: state.scope, disabled: busy !== null, onChange: (e) => void requestCapture(e.target.value), children: scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: scope, children: SCOPE_LABEL[scope] }, scope)) })
1342
1937
  ] }) : null,
1343
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
1938
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
1344
1939
  "Detail",
1345
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { "aria-label": "Detail preset", value: controls.preset, onChange: (e) => changeControls({ ...controls, preset: e.target.value }), children: [
1346
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "full", children: "Full" }),
1347
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "compact", children: "Compact" }),
1348
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "brief", children: "Brief" }),
1349
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "custom", children: "Custom" })
1940
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("select", { "aria-label": "Detail preset", value: controls.preset, onChange: (e) => changeControls({ ...controls, preset: e.target.value }), children: [
1941
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "full", children: "Full" }),
1942
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "compact", children: "Compact" }),
1943
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "brief", children: "Brief" }),
1944
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "custom", children: "Custom" })
1350
1945
  ] })
1351
1946
  ] }),
1352
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: !state.draft.history?.length && !controlsHistory.length || busy !== null, onClick: () => {
1947
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: !state.draft.history?.length && !controlsHistory.length || busy !== null, onClick: () => {
1353
1948
  setBufferError(null);
1354
1949
  if (controlsHistory.length) {
1355
1950
  const next = controlsHistory[controlsHistory.length - 1];
@@ -1358,7 +1953,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1358
1953
  onChange({ ...state, draft: rebuild(state, next), error: void 0 });
1359
1954
  } else onChange({ ...state, draft: (0, import_content_transfer.undoDraft)(state.draft), error: void 0 });
1360
1955
  }, children: "Undo" }),
1361
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => {
1956
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => {
1362
1957
  const next = initialControls(state);
1363
1958
  setControls(next);
1364
1959
  setControlsHistory([]);
@@ -1366,64 +1961,64 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1366
1961
  setBufferError(null);
1367
1962
  onChange({ ...state, draft: rebuild(state, next), error: void 0 });
1368
1963
  }, children: "Reset" }),
1369
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => void requestCapture(state.scope), children: "Refresh source" })
1964
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => void requestCapture(state.scope), children: "Refresh source" })
1370
1965
  ] }),
1371
- controls.preset === "custom" && (state.draft.payload.kind === "json" || state.draft.payload.kind === "registered") ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("fieldset", { className: "matrx-alchemy-options", children: [
1372
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("legend", { children: "JSON limits" }),
1373
- [["maxDepth", "Maximum depth"], ["maxStringChars", "Maximum string characters"], ["maxArrayItems", "Maximum array items"]].map(([key, text]) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
1966
+ controls.preset === "custom" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("fieldset", { className: "matrx-alchemy-options", children: [
1967
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("legend", { children: state.draft.payload.kind === "json" || state.draft.payload.kind === "registered" ? "JSON limits" : "Content limits" }),
1968
+ [["maxDepth", "Maximum depth"], ["maxStringChars", state.draft.payload.kind === "rows" ? "Maximum characters per cell" : "Maximum string characters"], ["maxArrayItems", "Maximum array items"]].filter(([key]) => key === "maxStringChars" || state.draft.payload.kind === "json" || state.draft.payload.kind === "registered").map(([key, text]) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
1374
1969
  text,
1375
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "number", min: "0", value: controls[key] ?? "", onChange: (e) => changeControls({ ...controls, [key]: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
1970
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "number", min: "0", value: controls[key] ?? "", onChange: (e) => changeControls({ ...controls, [key]: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
1376
1971
  ] }, key))
1377
1972
  ] }) : null,
1378
- rows ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-data-controls", children: [
1379
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
1973
+ rows ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-data-controls", children: [
1974
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("summary", { children: [
1380
1975
  "Data selection \xB7 ",
1381
1976
  controls.visibleColumns.length,
1382
1977
  " columns",
1383
1978
  controls.search || controls.sort || controls.top != null || controls.selectedOnly || Object.values(controls.filters).some(Boolean) ? " \xB7 customized" : " \xB7 all rows"
1384
1979
  ] }),
1385
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "matrx-alchemy-data-controls-body", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RowControls, { rows, controls, change: changeControls }) })
1980
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "matrx-alchemy-data-controls-body", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RowControls, { rows, controls, change: changeControls }) })
1386
1981
  ] }) : null,
1387
- state.snapshot.sections.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options", children: [
1388
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
1982
+ state.snapshot.sections.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("details", { className: "matrx-alchemy-options", children: [
1983
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("summary", { children: [
1389
1984
  "Sections \xB7 ",
1390
1985
  controls.sections.length,
1391
1986
  " included"
1392
1987
  ] }),
1393
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("fieldset", { "aria-label": "Included sections", children: state.snapshot.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
1394
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: controls.sections.includes(section.id), onChange: (e) => changeControls({ ...controls, sections: e.target.checked ? [...controls.sections, section.id] : controls.sections.filter((id) => id !== section.id) }) }),
1988
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("fieldset", { "aria-label": "Included sections", children: state.snapshot.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
1989
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "checkbox", checked: controls.sections.includes(section.id), onChange: (e) => changeControls({ ...controls, sections: e.target.checked ? [...controls.sections, section.id] : controls.sections.filter((id) => id !== section.id) }) }),
1395
1990
  " ",
1396
1991
  section.label
1397
1992
  ] }, section.id)) })
1398
1993
  ] }) : null,
1399
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "matrx-alchemy-preview-label", children: [
1994
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "matrx-alchemy-preview-label", children: [
1400
1995
  "Output format",
1401
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { "aria-label": "Output format", value: format, onChange: (e) => setFormat(e.target.value), children: [
1402
- formats.map((f) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: f, children: LABEL[f] }, f)),
1403
- state.draft.payload.kind === "rows" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "xlsx", children: "Excel workbook" }) : null,
1404
- workspaceAdapters.map((adapter) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: adapter.id, children: adapter.label }, adapter.id))
1996
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("select", { "aria-label": "Output format", value: format, onChange: (e) => setFormat(e.target.value), children: [
1997
+ formats.map((f) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: f, children: LABEL[f] }, f)),
1998
+ state.draft.payload.kind === "rows" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "xlsx", children: "Excel workbook" }) : null,
1999
+ workspaceAdapters.map((adapter) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: adapter.id, children: adapter.label }, adapter.id))
1405
2000
  ] })
1406
2001
  ] }),
1407
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("textarea", { className: "matrx-alchemy-preview", "aria-label": "Prepared output", "aria-invalid": bufferError ? true : void 0, "aria-describedby": bufferError ? "alchemy-buffer-error" : void 0, value: buffer, onChange: (e) => editBuffer(e.target.value) }),
1408
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-coverage", children: [
1409
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
2002
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("textarea", { className: "matrx-alchemy-preview", "aria-label": "Prepared output", "aria-invalid": bufferError ? true : void 0, "aria-describedby": bufferError ? "alchemy-buffer-error" : void 0, value: buffer, onChange: (e) => editBuffer(e.target.value) }),
2003
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "matrx-alchemy-coverage", children: [
2004
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
1410
2005
  state.snapshot.coverage.included.toLocaleString(),
1411
2006
  " included",
1412
2007
  state.snapshot.coverage.total == null ? "" : ` of ${state.snapshot.coverage.total.toLocaleString()}`,
1413
2008
  " \xB7 ",
1414
2009
  state.snapshot.coverage.status
1415
2010
  ] }),
1416
- state.snapshot.coverage.reason ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: state.snapshot.coverage.reason }) : null,
1417
- limitText ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
2011
+ state.snapshot.coverage.reason ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: state.snapshot.coverage.reason }) : null,
2012
+ limitText ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
1418
2013
  "Limits: ",
1419
2014
  limitText
1420
2015
  ] }) : null,
1421
- displayedOmissions.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { children: [
1422
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
2016
+ displayedOmissions.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("details", { children: [
2017
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("summary", { children: [
1423
2018
  displayedOmissions.length,
1424
2019
  " omissions or adjustments"
1425
2020
  ] }),
1426
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { children: displayedOmissions.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("li", { children: [
2021
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("ul", { children: displayedOmissions.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("li", { children: [
1427
2022
  o.path || "/",
1428
2023
  ": ",
1429
2024
  o.reason,
@@ -1431,57 +2026,79 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1431
2026
  ] }, `${o.path}-${o.reason}-${i}`)) })
1432
2027
  ] }) : null
1433
2028
  ] }),
1434
- bufferError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { id: "alchemy-buffer-error", role: "alert", className: "matrx-alchemy-error", children: bufferError }) : null,
1435
- formatError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: formatError }) : null,
1436
- bufferError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: busy !== null, onClick: () => {
2029
+ bufferError ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { id: "alchemy-buffer-error", role: "alert", className: "matrx-alchemy-error", children: bufferError }) : null,
2030
+ formatError ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: formatError }) : null,
2031
+ bufferError ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: busy !== null, onClick: () => {
1437
2032
  const fallback = (0, import_content_transfer.editDraft)(state.draft, { kind: "text", text: buffer });
1438
2033
  setBufferError(null);
1439
2034
  onChange({ ...state, draft: fallback, error: void 0 });
1440
2035
  setFormat("plain");
1441
2036
  }, children: "Use invalid JSON as plain text" }) : null
1442
2037
  ] }),
1443
- ai || busy === "capture" || state.error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("aside", { children: [
1444
- ai ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1445
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2038
+ ai || busy === "capture" || state.error ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("aside", { children: [
2039
+ ai ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
2040
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
2041
+ "Start with",
2042
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("select", { "aria-label": "AI preparation recipe", defaultValue: "", onChange: (event) => {
2043
+ if (event.target.value) setInstruction(event.target.value);
2044
+ }, children: [
2045
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "", children: "Choose an instruction" }),
2046
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "Summarize this content concisely. Preserve important facts, names, decisions, and source references.", children: "Summarize" }),
2047
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "Extract decisions, action items, owners, and due dates. Mark missing details as unspecified.", children: "Extract action items" }),
2048
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "Prepare a complete handoff for another assistant. Include the objective, relevant facts, constraints, decisions, and unresolved questions.", children: "Assistant handoff" }),
2049
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "Condense this content by removing repetition and formatting noise. Preserve every unique fact and all identifiers.", children: "Condense without losing facts" }),
2050
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "Turn this content into a clear structured outline. Keep the original meaning and explicitly flag uncertainty.", children: "Create an outline" }),
2051
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "Analyze this data. Identify patterns, anomalies, and useful comparisons. Distinguish observations from inferences.", children: "Analyze the data" })
2052
+ ] })
2053
+ ] }),
2054
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
1446
2055
  "AI instruction",
1447
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value), placeholder: "Tell AI how to prepare this content" })
2056
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value), placeholder: "Tell AI how to prepare this content" })
1448
2057
  ] }),
1449
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: !aiSession.current || !instruction.trim() || busy !== null || !aiSession.current.supports(state.snapshot), onClick: () => void runAi(false), children: "Generate preview" }),
1450
- busy === "ai" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void cancelAi(), children: aiSession.current?.cancel ? "Cancel AI" : "Stop waiting" }) : null
2058
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: !aiSession.current || !instruction.trim() || busy !== null || !aiSession.current.supports(state.snapshot), onClick: () => void runAi(false), children: "Generate preview" }),
2059
+ busy === "ai" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void cancelAi(), children: aiSession.current?.cancel ? "Cancel AI" : "Stop waiting" }) : null
1451
2060
  ] }) : null,
1452
- busy === "capture" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => {
2061
+ busy === "capture" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => {
1453
2062
  activeCapture.current?.abort();
1454
2063
  activeCapture.current = null;
1455
2064
  setBusy(null);
1456
2065
  }, children: "Stop loading rows" }) : null,
1457
- ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
1458
- ai ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "matrx-alchemy-meta", children: "AI updates the preview; copy it when you are ready. Closing this window lets the AI run continue." }) : null,
1459
- state.error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
2066
+ ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
2067
+ ai ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "matrx-alchemy-meta", children: "AI updates the preview; copy it when you are ready. Closing this window lets the AI run continue." }) : null,
2068
+ state.error ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
1460
2069
  ] }) : null
1461
2070
  ] }),
1462
- pendingControls ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
1463
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "This control would replace your manual edit." }),
1464
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
1465
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
2071
+ pendingControls ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
2072
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: "This control would replace your manual edit." }),
2073
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
2074
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
1466
2075
  ] }) : null,
1467
- state.sourceStale ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
1468
- state.pending ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
1469
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "A fresh source snapshot is ready." }),
1470
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
1471
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: () => resolveCapture("regenerate"), children: "Regenerate from fresh source" })
2076
+ state.sourceStale ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
2077
+ state.pending ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
2078
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: "A fresh source snapshot is ready." }),
2079
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
2080
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: () => resolveCapture("regenerate"), children: "Regenerate from fresh source" })
1472
2081
  ] }) : null,
1473
- deliveryNotice ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "status", className: "matrx-alchemy-meta", children: deliveryNotice }) : null
2082
+ eligibleActions.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-destinations", children: [
2083
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("summary", { children: [
2084
+ "Use prepared content \xB7 ",
2085
+ eligibleActions.length,
2086
+ " destinations"
2087
+ ] }),
2088
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "matrx-alchemy-destination-grid", children: eligibleActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliverAction(action), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DestinationPresentation, { action }) }, action.id)) })
2089
+ ] }) : null,
2090
+ deliveryNotice ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { role: "status", className: "matrx-alchemy-meta", children: deliveryNotice }) : null
1474
2091
  ] }),
1475
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogFooter, { children: [
1476
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "matrx-alchemy-meta", children: [
2092
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DialogFooter, { children: [
2093
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "matrx-alchemy-meta", children: [
1477
2094
  buffer.length.toLocaleString(),
1478
2095
  " characters \xB7 ~",
1479
2096
  estimateTokens(buffer).toLocaleString(),
1480
2097
  " tokens"
1481
2098
  ] }),
1482
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", onClick: close, children: "Close" }),
1483
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", "aria-label": "Download prepared output", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(true), children: "Download" }),
1484
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", className: "matrx-alchemy-workspace-primary", "aria-label": "Copy prepared output", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(false), children: "Copy" })
2099
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", onClick: close, children: "Close" }),
2100
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", "aria-label": "Download prepared output", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(true), children: "Download" }),
2101
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { type: "button", className: "matrx-alchemy-workspace-primary", "aria-label": "Copy prepared output", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(false), children: "Copy" })
1485
2102
  ] })
1486
2103
  ] }) });
1487
2104
  }
@@ -1489,59 +2106,59 @@ function RowControls({ rows, controls, change }) {
1489
2106
  const filterCount = Object.values(controls.filters).filter(Boolean).length;
1490
2107
  const selectionSummary = controls.selectedOnly ? `${controls.selectedIndices.length} selected row${controls.selectedIndices.length === 1 ? "" : "s"}` : "All rows";
1491
2108
  const dataSummary = [controls.search ? "search active" : "", controls.sort ? `sorted by ${rows.columns.find((column) => column.id === controls.sort)?.label ?? controls.sort}` : "", filterCount ? `${filterCount} filter${filterCount === 1 ? "" : "s"}` : ""].filter(Boolean).join(" \xB7 ");
1492
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1493
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
1494
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2109
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
2110
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
2111
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
1495
2112
  "Search",
1496
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { value: controls.search, onChange: (e) => change({ ...controls, search: e.target.value }) })
2113
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { value: controls.search, onChange: (e) => change({ ...controls, search: e.target.value }) })
1497
2114
  ] }),
1498
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2115
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
1499
2116
  "Sort",
1500
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { value: controls.sort, onChange: (e) => change({ ...controls, sort: e.target.value }), children: [
1501
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "None" }),
1502
- rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: column.id, children: column.label }, column.id))
2117
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("select", { value: controls.sort, onChange: (e) => change({ ...controls, sort: e.target.value }), children: [
2118
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "", children: "None" }),
2119
+ rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: column.id, children: column.label }, column.id))
1503
2120
  ] })
1504
2121
  ] }),
1505
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2122
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
1506
2123
  "Direction",
1507
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { value: controls.direction, disabled: !controls.sort, onChange: (e) => change({ ...controls, direction: e.target.value }), children: [
1508
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "asc", children: "Ascending" }),
1509
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "desc", children: "Descending" })
2124
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("select", { value: controls.direction, disabled: !controls.sort, onChange: (e) => change({ ...controls, direction: e.target.value }), children: [
2125
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "asc", children: "Ascending" }),
2126
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "desc", children: "Descending" })
1510
2127
  ] })
1511
2128
  ] }),
1512
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2129
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
1513
2130
  "Top rows",
1514
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "number", min: "0", value: controls.top ?? "", onChange: (e) => change({ ...controls, top: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
2131
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "number", min: "0", value: controls.top ?? "", onChange: (e) => change({ ...controls, top: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
1515
2132
  ] })
1516
2133
  ] }),
1517
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options", children: [
1518
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
2134
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("details", { className: "matrx-alchemy-options", children: [
2135
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("summary", { children: [
1519
2136
  "Columns and filters",
1520
2137
  dataSummary ? ` \u2014 ${dataSummary}` : ""
1521
2138
  ] }),
1522
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("fieldset", { "aria-label": "Columns and filters", children: rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-column", children: [
1523
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
1524
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: controls.visibleColumns.includes(column.id), onChange: (e) => change({ ...controls, visibleColumns: e.target.checked ? [...controls.visibleColumns, column.id] : controls.visibleColumns.filter((id) => id !== column.id) }) }),
2139
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("fieldset", { "aria-label": "Columns and filters", children: rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "matrx-alchemy-column", children: [
2140
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
2141
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "checkbox", checked: controls.visibleColumns.includes(column.id), onChange: (e) => change({ ...controls, visibleColumns: e.target.checked ? [...controls.visibleColumns, column.id] : controls.visibleColumns.filter((id) => id !== column.id) }) }),
1525
2142
  " ",
1526
2143
  column.label
1527
2144
  ] }),
1528
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { "aria-label": `Filter ${column.label}`, placeholder: "Filter", value: controls.filters[column.id] ?? "", onChange: (e) => change({ ...controls, filters: { ...controls.filters, [column.id]: e.target.value } }) })
2145
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { "aria-label": `Filter ${column.label}`, placeholder: "Filter", value: controls.filters[column.id] ?? "", onChange: (e) => change({ ...controls, filters: { ...controls.filters, [column.id]: e.target.value } }) })
1529
2146
  ] }, column.id)) })
1530
2147
  ] }),
1531
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options", children: [
1532
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
2148
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("details", { className: "matrx-alchemy-options", children: [
2149
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("summary", { children: [
1533
2150
  "Rows \u2014 ",
1534
2151
  selectionSummary
1535
2152
  ] }),
1536
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("fieldset", { "aria-label": "Row selection", children: [
1537
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
1538
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: controls.selectedOnly, onChange: (e) => change({ ...controls, selectedOnly: e.target.checked }) }),
2153
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("fieldset", { "aria-label": "Row selection", children: [
2154
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
2155
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "checkbox", checked: controls.selectedOnly, onChange: (e) => change({ ...controls, selectedOnly: e.target.checked }) }),
1539
2156
  " Only selected rows"
1540
2157
  ] }),
1541
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "matrx-alchemy-row-list", children: rows.rows.map((row, index) => {
2158
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "matrx-alchemy-row-list", children: rows.rows.map((row, index) => {
1542
2159
  const summary = rows.columns.filter((column) => column.visible).slice(0, 2).map((column) => String((0, import_content_transfer.readTransferCell)(row, column) ?? "")).filter(Boolean).join(" \xB7 ");
1543
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
1544
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: controls.selectedIndices.includes(index), onChange: (e) => change({ ...controls, selectedIndices: e.target.checked ? [...controls.selectedIndices, index] : controls.selectedIndices.filter((value) => value !== index) }) }),
2160
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { children: [
2161
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "checkbox", checked: controls.selectedIndices.includes(index), onChange: (e) => change({ ...controls, selectedIndices: e.target.checked ? [...controls.selectedIndices, index] : controls.selectedIndices.filter((value) => value !== index) }) }),
1545
2162
  " Row ",
1546
2163
  index + 1,
1547
2164
  summary ? ` \u2014 ${summary}` : ""
@@ -1553,7 +2170,7 @@ function RowControls({ rows, controls, change }) {
1553
2170
  }
1554
2171
 
1555
2172
  // src/content-transfer/matrx-copy.tsx
1556
- var import_jsx_runtime11 = require("react/jsx-runtime");
2173
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1557
2174
  var resolve = (value) => typeof value === "function" ? value() : value;
1558
2175
  var asPayload = (value) => ({
1559
2176
  kind: "markdown",
@@ -1599,7 +2216,7 @@ var sourceFor = (id, label, build) => ({
1599
2216
  });
1600
2217
  function MatrxCopyMenu(props) {
1601
2218
  const inherited = useContentTransferCapabilities();
1602
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2219
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1603
2220
  MatrxCopyMenuSession,
1604
2221
  {
1605
2222
  ...props
@@ -1611,12 +2228,12 @@ function MatrxCopyMenu(props) {
1611
2228
  );
1612
2229
  }
1613
2230
  function MatrxCopyMenuSession(props) {
1614
- const instance = React8.useId();
1615
- const controller = React8.useRef(null);
2231
+ const instance = React9.useId();
2232
+ const controller = React9.useRef(null);
1616
2233
  const capabilities = useContentTransferCapabilities();
1617
2234
  const transport = capabilities.transport ?? (0, import_content_transfer2.createBrowserTransport)();
1618
- const [modal, setModal] = React8.useState(null);
1619
- const [configuration, setConfiguration] = React8.useState(null);
2235
+ const [modal, setModal] = React9.useState(null);
2236
+ const [configuration, setConfiguration] = React9.useState(null);
1620
2237
  const copyVisible = !props.hide?.includes("copy");
1621
2238
  const aiVisible = !props.hide?.includes("ai");
1622
2239
  const exportVisible = !props.hide?.includes("export");
@@ -1803,11 +2420,13 @@ function MatrxCopyMenuSession(props) {
1803
2420
  const source = (props.primarySource === "table" ? table : void 0) ?? json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
1804
2421
  if (!source && !actions.length) return null;
1805
2422
  const target = source ?? make("actions", () => ({ kind: "text", text: props.label }));
1806
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1807
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2423
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
2424
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1808
2425
  ContentTransferMenu,
1809
2426
  {
1810
2427
  source: target,
2428
+ ...props.icon !== void 0 ? { icon: props.icon } : {},
2429
+ ...props.triggerVariant !== void 0 ? { triggerVariant: props.triggerVariant } : {},
1811
2430
  controllerRef: controller,
1812
2431
  label: props.label,
1813
2432
  variants,
@@ -1839,7 +2458,7 @@ function MatrxCopyMenuSession(props) {
1839
2458
  if (!open) setModal(null);
1840
2459
  }
1841
2460
  }),
1842
- configuration ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2461
+ configuration ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1843
2462
  SourceConfiguration,
1844
2463
  {
1845
2464
  restoreFocus: () => controller.current?.focusTrigger(),
@@ -1866,14 +2485,14 @@ function SourceConfiguration({
1866
2485
  onPrepare
1867
2486
  }) {
1868
2487
  const custom = configuration.custom;
1869
- const handingOff = React8.useRef(false);
2488
+ const handingOff = React9.useRef(false);
1870
2489
  const groomer = configuration.groomer;
1871
- const [values, setValues] = React8.useState(
2490
+ const [values, setValues] = React9.useState(
1872
2491
  () => Object.fromEntries(
1873
2492
  custom?.options.map((option) => [option.key, option.default]) ?? []
1874
2493
  )
1875
2494
  );
1876
- const [sections, setSections] = React8.useState(
2495
+ const [sections, setSections] = React9.useState(
1877
2496
  () => Object.fromEntries(
1878
2497
  groomer?.sections.map((section) => [
1879
2498
  section.id,
@@ -1881,8 +2500,8 @@ function SourceConfiguration({
1881
2500
  ]) ?? []
1882
2501
  )
1883
2502
  );
1884
- const [error, setError] = React8.useState(null);
1885
- const [busy, setBusy] = React8.useState(false);
2503
+ const [error, setError] = React9.useState(null);
2504
+ const [busy, setBusy] = React9.useState(false);
1886
2505
  const title = custom?.dialogTitle ?? groomer?.label ?? "Customize source";
1887
2506
  let prepared = null;
1888
2507
  let buildError = null;
@@ -1919,14 +2538,14 @@ function SourceConfiguration({
1919
2538
  } catch (cause) {
1920
2539
  buildError = cause instanceof Error ? cause.message : "Could not prepare this source.";
1921
2540
  }
1922
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2541
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1923
2542
  Dialog,
1924
2543
  {
1925
2544
  open: true,
1926
2545
  onOpenChange: (open) => {
1927
2546
  if (!open && !busy) onClose();
1928
2547
  },
1929
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2548
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1930
2549
  DialogContent,
1931
2550
  {
1932
2551
  onCloseAutoFocus: (event) => {
@@ -1935,23 +2554,23 @@ function SourceConfiguration({
1935
2554
  },
1936
2555
  className: "matrx-alchemy-workspace matrx-alchemy-configuration",
1937
2556
  children: [
1938
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogHeader, { children: [
1939
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DialogTitle, { children: title }),
1940
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DialogDescription, { children: custom?.dialogDescription ?? "Choose the source detail, then prepare, edit, summarize, copy or export it in Alchemy." })
2557
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DialogHeader, { children: [
2558
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DialogTitle, { children: title }),
2559
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DialogDescription, { children: custom?.dialogDescription ?? "Choose the source detail, then prepare, edit, summarize, copy or export it in Alchemy." })
1941
2560
  ] }),
1942
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
1943
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-main matrx-alchemy-toolbar", children: [
1944
- custom?.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
2561
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
2562
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "matrx-alchemy-main matrx-alchemy-toolbar", children: [
2563
+ custom?.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
1945
2564
  option.label,
1946
- "hint" in option && option.hint ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { children: option.hint }) : null,
1947
- option.kind === "toggle" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2565
+ "hint" in option && option.hint ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("small", { children: option.hint }) : null,
2566
+ option.kind === "toggle" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1948
2567
  "input",
1949
2568
  {
1950
2569
  type: "checkbox",
1951
2570
  checked: Boolean(values[option.key]),
1952
2571
  onChange: (event) => setValues({ ...values, [option.key]: event.target.checked })
1953
2572
  }
1954
- ) : option.kind === "preset" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2573
+ ) : option.kind === "preset" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1955
2574
  "select",
1956
2575
  {
1957
2576
  value: Number(values[option.key]),
@@ -1959,10 +2578,10 @@ function SourceConfiguration({
1959
2578
  ...values,
1960
2579
  [option.key]: Number(event.target.value)
1961
2580
  }),
1962
- children: option.options.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: choice.value, children: choice.label }, choice.value))
2581
+ children: option.options.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: choice.value, children: choice.label }, choice.value))
1963
2582
  }
1964
- ) : option.kind === "slider" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1965
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2583
+ ) : option.kind === "slider" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
2584
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1966
2585
  "input",
1967
2586
  {
1968
2587
  type: "range",
@@ -1976,9 +2595,9 @@ function SourceConfiguration({
1976
2595
  })
1977
2596
  }
1978
2597
  ),
1979
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: option.formatValue(Number(values[option.key])) })
1980
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1981
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2598
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: option.formatValue(Number(values[option.key])) })
2599
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
2600
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1982
2601
  "input",
1983
2602
  {
1984
2603
  type: "number",
@@ -1991,7 +2610,7 @@ function SourceConfiguration({
1991
2610
  })
1992
2611
  }
1993
2612
  ),
1994
- option.presets?.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2613
+ option.presets?.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1995
2614
  Button,
1996
2615
  {
1997
2616
  type: "button",
@@ -2004,8 +2623,8 @@ function SourceConfiguration({
2004
2623
  ))
2005
2624
  ] })
2006
2625
  ] }, option.key)),
2007
- groomer ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2008
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { children: ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2626
+ groomer ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
2627
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { children: ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2009
2628
  Button,
2010
2629
  {
2011
2630
  type: "button",
@@ -2023,9 +2642,9 @@ function SourceConfiguration({
2023
2642
  },
2024
2643
  level
2025
2644
  )) }),
2026
- groomer.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
2645
+ groomer.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
2027
2646
  section.title,
2028
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2647
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2029
2648
  "select",
2030
2649
  {
2031
2650
  value: sections[section.id],
@@ -2034,26 +2653,26 @@ function SourceConfiguration({
2034
2653
  [section.id]: event.target.value
2035
2654
  }),
2036
2655
  children: [
2037
- ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: level, children: section.levelLabels?.[level] ?? level }, level)),
2038
- section.cuttable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "off", children: "Exclude" }) : null
2656
+ ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: level, children: section.levelLabels?.[level] ?? level }, level)),
2657
+ section.cuttable ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "off", children: "Exclude" }) : null
2039
2658
  ]
2040
2659
  }
2041
2660
  ),
2042
- section.description ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: section.description }) : null
2661
+ section.description ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: section.description }) : null
2043
2662
  ] }, section.id))
2044
2663
  ] }) : null
2045
2664
  ] }),
2046
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { children: [
2665
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { children: [
2047
2666
  text.length.toLocaleString(),
2048
2667
  " characters \xB7 approximately",
2049
2668
  " ",
2050
2669
  Math.ceil(text.length / 4).toLocaleString(),
2051
2670
  " tokens"
2052
2671
  ] }),
2053
- error || buildError ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", children: error ?? buildError }) : null
2672
+ error || buildError ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { role: "alert", children: error ?? buildError }) : null
2054
2673
  ] }),
2055
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogFooter, { children: [
2056
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2674
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DialogFooter, { children: [
2675
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2057
2676
  Button,
2058
2677
  {
2059
2678
  type: "button",
@@ -2064,7 +2683,7 @@ function SourceConfiguration({
2064
2683
  children: "Cancel"
2065
2684
  }
2066
2685
  ),
2067
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2686
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2068
2687
  Button,
2069
2688
  {
2070
2689
  type: "button",
@@ -2098,23 +2717,23 @@ function SourceConfiguration({
2098
2717
  }
2099
2718
 
2100
2719
  // src/data-table/copy.tsx
2101
- var import_jsx_runtime12 = require("react/jsx-runtime");
2720
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2102
2721
  function CopyButtons(props) {
2103
2722
  const { CopyControls } = useMatrxDataTableHost();
2104
2723
  const copyProps = props.export?.sheetRows ? { ...props, primarySource: "table" } : props;
2105
- if (CopyControls) return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CopyControls, { ...copyProps });
2106
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MatrxCopyMenu, { ...copyProps });
2724
+ if (CopyControls) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CopyControls, { ...copyProps });
2725
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(MatrxCopyMenu, { ...copyProps });
2107
2726
  }
2108
2727
 
2109
2728
  // src/data-table/MatrxUuidCell.tsx
2110
- var import_react3 = require("react");
2729
+ var import_react4 = require("react");
2111
2730
 
2112
2731
  // src/data-table/useTableNotice.tsx
2113
- var import_react2 = require("react");
2114
- var import_jsx_runtime13 = require("react/jsx-runtime");
2732
+ var import_react3 = require("react");
2733
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2115
2734
  function useTableNotice() {
2116
2735
  const host = useMatrxDataTableHost();
2117
- const [message, setMessage] = (0, import_react2.useState)(null);
2736
+ const [message, setMessage] = (0, import_react3.useState)(null);
2118
2737
  const notify = {
2119
2738
  success(text) {
2120
2739
  if (host.notify) host.notify.success(text);
@@ -2125,41 +2744,15 @@ function useTableNotice() {
2125
2744
  else setMessage({ text, error: true });
2126
2745
  }
2127
2746
  };
2128
- const notice = message ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { role: message.error ? "alert" : "status", className: message.error ? "text-xs text-destructive" : "text-xs text-muted-foreground", children: [
2747
+ const notice = message ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { role: message.error ? "alert" : "status", className: message.error ? "text-xs text-destructive" : "text-xs text-muted-foreground", children: [
2129
2748
  message.text,
2130
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", "aria-label": "Dismiss notification", className: "ml-2 underline", onClick: () => setMessage(null), children: "Dismiss" })
2749
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", "aria-label": "Dismiss notification", className: "ml-2 underline", onClick: () => setMessage(null), children: "Dismiss" })
2131
2750
  ] }) : null;
2132
2751
  return { notify, notice };
2133
2752
  }
2134
2753
 
2135
- // src/tooltip.tsx
2136
- var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"), 1);
2137
- var React9 = __toESM(require("react"), 1);
2138
- var import_jsx_runtime14 = require("react/jsx-runtime");
2139
- var TooltipProvider = TooltipPrimitive.Provider;
2140
- var Tooltip = TooltipPrimitive.Root;
2141
- var TooltipTrigger = TooltipPrimitive.Trigger;
2142
- var TooltipContent = React9.forwardRef(({ className, sideOffset = 4, container, animated = true, ...props }, ref) => {
2143
- const resolved = usePortalContainer(container);
2144
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(TooltipPrimitive.Portal, { container: resolved ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2145
- TooltipPrimitive.Content,
2146
- {
2147
- ref,
2148
- "data-slot": "tooltip-content",
2149
- sideOffset,
2150
- className: cn(
2151
- "z-[10001] overflow-hidden rounded-md border border-border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md",
2152
- animated && MOTION_POPPER,
2153
- className
2154
- ),
2155
- ...props
2156
- }
2157
- ) });
2158
- });
2159
- TooltipContent.displayName = TooltipPrimitive.Content.displayName;
2160
-
2161
2754
  // src/data-table/MatrxUuidCell.tsx
2162
- var import_jsx_runtime15 = require("react/jsx-runtime");
2755
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2163
2756
  var SHORT_LEN = 8;
2164
2757
  function shortUuid(id, len = SHORT_LEN) {
2165
2758
  return id.slice(0, len);
@@ -2198,18 +2791,18 @@ function MatrxUuidCell({
2198
2791
  }) {
2199
2792
  const { resolveEntityDoors, ResourcePeek } = useMatrxDataTableHost();
2200
2793
  const { notify, notice } = useTableNotice();
2201
- const [copied, setCopied] = (0, import_react3.useState)(false);
2202
- const [opening, setOpening] = (0, import_react3.useState)(false);
2203
- const [peekOpen, setPeekOpen] = (0, import_react3.useState)(false);
2204
- const timer = (0, import_react3.useRef)(null);
2205
- (0, import_react3.useEffect)(
2794
+ const [copied, setCopied] = (0, import_react4.useState)(false);
2795
+ const [opening, setOpening] = (0, import_react4.useState)(false);
2796
+ const [peekOpen, setPeekOpen] = (0, import_react4.useState)(false);
2797
+ const timer = (0, import_react4.useRef)(null);
2798
+ (0, import_react4.useEffect)(
2206
2799
  () => () => {
2207
2800
  if (timer.current) clearTimeout(timer.current);
2208
2801
  },
2209
2802
  []
2210
2803
  );
2211
2804
  if (!value) {
2212
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-muted-foreground/40", children: "\u2014" });
2805
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-muted-foreground/40", children: "\u2014" });
2213
2806
  }
2214
2807
  const doors = token ? resolveEntityDoors?.(token, value, href) ?? null : null;
2215
2808
  const resolvedHref = doors?.href ?? href ?? null;
@@ -2252,13 +2845,13 @@ function MatrxUuidCell({
2252
2845
  };
2253
2846
  const idNode = (() => {
2254
2847
  if (forbidden) {
2255
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "inline-flex min-w-0 items-center gap-1 font-mono text-xs text-muted-foreground/70 tabular-nums", children: [
2256
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "min-w-0 truncate", children: display }),
2257
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ShieldOff, { className: "h-3 w-3 shrink-0 opacity-60", "aria-hidden": true })
2848
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "inline-flex min-w-0 items-center gap-1 font-mono text-xs text-muted-foreground/70 tabular-nums", children: [
2849
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "min-w-0 truncate", children: display }),
2850
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ShieldOff, { className: "h-3 w-3 shrink-0 opacity-60", "aria-hidden": true })
2258
2851
  ] });
2259
2852
  }
2260
2853
  if (onOpen) {
2261
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2854
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2262
2855
  "button",
2263
2856
  {
2264
2857
  type: "button",
@@ -2267,14 +2860,14 @@ function MatrxUuidCell({
2267
2860
  disabled: opening,
2268
2861
  className: "inline-flex min-w-0 items-center gap-1 font-mono text-xs text-sky-600 hover:underline dark:text-sky-400 disabled:opacity-60",
2269
2862
  children: [
2270
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "min-w-0 truncate tabular-nums", children: display }),
2271
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(PanelRight, { className: "h-3 w-3 shrink-0 opacity-50" })
2863
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "min-w-0 truncate tabular-nums", children: display }),
2864
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PanelRight, { className: "h-3 w-3 shrink-0 opacity-50" })
2272
2865
  ]
2273
2866
  }
2274
2867
  );
2275
2868
  }
2276
2869
  if (resolvedHref) {
2277
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2870
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2278
2871
  "a",
2279
2872
  {
2280
2873
  href: resolvedHref,
@@ -2284,15 +2877,15 @@ function MatrxUuidCell({
2284
2877
  onClick: stop,
2285
2878
  className: "inline-flex min-w-0 items-center gap-1 font-mono text-xs text-sky-600 hover:underline dark:text-sky-400",
2286
2879
  children: [
2287
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "min-w-0 truncate tabular-nums", children: display }),
2288
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ExternalLink, { className: "h-3 w-3 shrink-0 opacity-50" })
2880
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "min-w-0 truncate tabular-nums", children: display }),
2881
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ExternalLink, { className: "h-3 w-3 shrink-0 opacity-50" })
2289
2882
  ]
2290
2883
  }
2291
2884
  );
2292
2885
  }
2293
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "min-w-0 truncate font-mono text-xs text-muted-foreground tabular-nums select-all", children: display });
2886
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "min-w-0 truncate font-mono text-xs text-muted-foreground tabular-nums select-all", children: display });
2294
2887
  })();
2295
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2888
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2296
2889
  "span",
2297
2890
  {
2298
2891
  "data-matrx-cell-control": true,
@@ -2302,12 +2895,12 @@ function MatrxUuidCell({
2302
2895
  ),
2303
2896
  onClick: stop,
2304
2897
  children: [
2305
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Tooltip, { children: [
2306
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "inline-flex min-w-0 max-w-full items-center", children: idNode }) }),
2307
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TooltipContent, { side: "top", className: "max-w-sm break-all font-mono", children: forbidden ? `No access \xB7 ${tip}` : tip })
2898
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Tooltip, { children: [
2899
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "inline-flex min-w-0 max-w-full items-center", children: idNode }) }),
2900
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipContent, { side: "top", className: "max-w-sm break-all font-mono", children: forbidden ? `No access \xB7 ${tip}` : tip })
2308
2901
  ] }),
2309
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Tooltip, { children: [
2310
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2902
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Tooltip, { children: [
2903
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2311
2904
  "button",
2312
2905
  {
2313
2906
  type: "button",
@@ -2317,13 +2910,13 @@ function MatrxUuidCell({
2317
2910
  "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
2318
2911
  copied && "text-primary"
2319
2912
  ),
2320
- children: copied ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Check, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Copy, { className: "h-3 w-3" })
2913
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Check, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Copy, { className: "h-3 w-3" })
2321
2914
  }
2322
2915
  ) }),
2323
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TooltipContent, { side: "top", children: copied ? "Copied" : `Copy ${label ?? "id"}: ${value}` })
2916
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipContent, { side: "top", children: copied ? "Copied" : `Copy ${label ?? "id"}: ${value}` })
2324
2917
  ] }),
2325
- canPeek ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Tooltip, { children: [
2326
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2918
+ canPeek ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Tooltip, { children: [
2919
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2327
2920
  "button",
2328
2921
  {
2329
2922
  type: "button",
@@ -2333,16 +2926,16 @@ function MatrxUuidCell({
2333
2926
  },
2334
2927
  "aria-label": `Quick look at ${label ?? "record"}`,
2335
2928
  className: "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
2336
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Lightbulb, { className: "h-3 w-3" })
2929
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Lightbulb, { className: "h-3 w-3" })
2337
2930
  }
2338
2931
  ) }),
2339
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(TooltipContent, { side: "top", children: [
2932
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(TooltipContent, { side: "top", children: [
2340
2933
  "Quick look at ",
2341
2934
  label ?? "record"
2342
2935
  ] })
2343
2936
  ] }) : null,
2344
- onOpen && resolvedHref && !forbidden ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Tooltip, { children: [
2345
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2937
+ onOpen && resolvedHref && !forbidden ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Tooltip, { children: [
2938
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2346
2939
  "a",
2347
2940
  {
2348
2941
  href: resolvedHref,
@@ -2351,10 +2944,10 @@ function MatrxUuidCell({
2351
2944
  onClick: stop,
2352
2945
  "aria-label": `Open ${label ?? "record"} in a new tab`,
2353
2946
  className: "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
2354
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ExternalLink, { className: "h-3 w-3" })
2947
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ExternalLink, { className: "h-3 w-3" })
2355
2948
  }
2356
2949
  ) }),
2357
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(TooltipContent, { side: "top", children: [
2950
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(TooltipContent, { side: "top", children: [
2358
2951
  "Open ",
2359
2952
  label ?? "record",
2360
2953
  " in a new tab"
@@ -2362,7 +2955,7 @@ function MatrxUuidCell({
2362
2955
  ] }) : null,
2363
2956
  trailing,
2364
2957
  notice,
2365
- canPeek && peekOpen && ResourcePeek ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2958
+ canPeek && peekOpen && ResourcePeek ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2366
2959
  ResourcePeek,
2367
2960
  {
2368
2961
  kind: doors?.peekKind ?? token ?? "record",
@@ -2382,7 +2975,7 @@ function isUuidValue(value) {
2382
2975
  }
2383
2976
 
2384
2977
  // src/data-table/DataRowInspector.tsx
2385
- var import_jsx_runtime16 = require("react/jsx-runtime");
2978
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2386
2979
  var noFieldToken = () => null;
2387
2980
  function formatValue(value) {
2388
2981
  if (value == null) return "\u2014";
@@ -2411,7 +3004,7 @@ function DataRowInspector({
2411
3004
  tokenForField = noFieldToken
2412
3005
  }) {
2413
3006
  const entries = isPlainObject(row) ? Object.entries(row) : [["value", row]];
2414
- const fieldButtons = (key, value) => fieldCopy ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "absolute right-1 top-1 opacity-0 transition-opacity focus-within:opacity-100 group-hover/field:opacity-100", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3007
+ const fieldButtons = (key, value) => fieldCopy ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "absolute right-1 top-1 opacity-0 transition-opacity focus-within:opacity-100 group-hover/field:opacity-100", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2415
3008
  CopyButtons,
2416
3009
  {
2417
3010
  size: "xs",
@@ -2426,21 +3019,21 @@ function DataRowInspector({
2426
3019
  })
2427
3020
  }
2428
3021
  ) }) : null;
2429
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3022
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2430
3023
  "div",
2431
3024
  {
2432
3025
  className: cn("flex h-full min-h-0 flex-col overflow-hidden", className),
2433
3026
  children: [
2434
- title ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "shrink-0 border-b border-border px-3 py-2 text-sm font-medium", children: title }) : null,
2435
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "min-h-0 flex-1 overflow-auto p-3", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dl", { className: "space-y-2", children: entries.map(([key, value]) => {
3027
+ title ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "shrink-0 border-b border-border px-3 py-2 text-sm font-medium", children: title }) : null,
3028
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "min-h-0 flex-1 overflow-auto p-3", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("dl", { className: "space-y-2", children: entries.map(([key, value]) => {
2436
3029
  if (isUuidValue(value)) {
2437
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3030
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2438
3031
  "div",
2439
3032
  {
2440
3033
  className: "group/field relative grid grid-cols-[minmax(7rem,9rem)_1fr] gap-2 rounded-md border border-border/60 bg-muted/20 px-2.5 py-2",
2441
3034
  children: [
2442
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dt", { className: "truncate text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: key }),
2443
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dd", { className: "min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3035
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("dt", { className: "truncate text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: key }),
3036
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("dd", { className: "min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2444
3037
  MatrxUuidCell,
2445
3038
  {
2446
3039
  value,
@@ -2455,13 +3048,13 @@ function DataRowInspector({
2455
3048
  }
2456
3049
  const formatted = formatValue(value);
2457
3050
  const multiline = formatted.includes("\n") || formatted.length > 80;
2458
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3051
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2459
3052
  "div",
2460
3053
  {
2461
3054
  className: "group/field relative grid grid-cols-[minmax(7rem,9rem)_1fr] gap-2 rounded-md border border-border/60 bg-muted/20 py-2 pl-2.5 pr-12",
2462
3055
  children: [
2463
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("dt", { className: "truncate text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: key }),
2464
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3056
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("dt", { className: "truncate text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: key }),
3057
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2465
3058
  "dd",
2466
3059
  {
2467
3060
  className: cn(
@@ -2483,7 +3076,7 @@ function DataRowInspector({
2483
3076
  }
2484
3077
 
2485
3078
  // src/data-table/DataRowWindow.tsx
2486
- var import_jsx_runtime17 = require("react/jsx-runtime");
3079
+ var import_jsx_runtime18 = require("react/jsx-runtime");
2487
3080
  function DataRowWindow({
2488
3081
  isOpen,
2489
3082
  onClose,
@@ -2503,15 +3096,15 @@ function DataRowWindow({
2503
3096
  const hasEdit = editContent != null;
2504
3097
  const hasTabs = hasEdit && children == null;
2505
3098
  const initialTab = defaultTab ?? (hasEdit ? "edit" : "view");
2506
- const [tab, setTab] = (0, import_react4.useState)(initialTab);
2507
- (0, import_react4.useEffect)(() => {
3099
+ const [tab, setTab] = (0, import_react5.useState)(initialTab);
3100
+ (0, import_react5.useEffect)(() => {
2508
3101
  if (!isOpen) return;
2509
3102
  setTab(defaultTab ?? (hasEdit ? "edit" : "view"));
2510
3103
  }, [isOpen, windowId, hasEdit, defaultTab]);
2511
3104
  if (!isOpen) return null;
2512
- const viewBody = viewContent ?? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DataRowInspector, { row });
2513
- const body = children ?? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex h-full min-h-0 flex-1 flex-col overflow-hidden", children: hasTabs ? tab === "edit" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto", children: editContent }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto", children: viewBody }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto", children: viewBody }) });
2514
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3105
+ const viewBody = viewContent ?? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DataRowInspector, { row });
3106
+ const body = children ?? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex h-full min-h-0 flex-1 flex-col overflow-hidden", children: hasTabs ? tab === "edit" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto", children: editContent }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto", children: viewBody }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto", children: viewBody }) });
3107
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2515
3108
  WindowPanel,
2516
3109
  {
2517
3110
  id: windowId,
@@ -2525,26 +3118,26 @@ function DataRowWindow({
2525
3118
  bodyClassName: "flex min-h-0 flex-1 flex-col overflow-hidden p-0",
2526
3119
  sidebarDefaultSize: 140,
2527
3120
  sidebarMinSize: 110,
2528
- sidebar: hasTabs ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
3121
+ sidebar: hasTabs ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2529
3122
  "nav",
2530
3123
  {
2531
3124
  "aria-label": "Row window tabs",
2532
3125
  className: "flex h-full flex-col gap-0.5 overflow-y-auto p-1.5",
2533
3126
  children: [
2534
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3127
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2535
3128
  TabButton,
2536
3129
  {
2537
3130
  active: tab === "view",
2538
- icon: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Eye, { className: "h-4 w-4 shrink-0" }),
3131
+ icon: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Eye, { className: "h-4 w-4 shrink-0" }),
2539
3132
  label: "View",
2540
3133
  onClick: () => setTab("view")
2541
3134
  }
2542
3135
  ),
2543
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3136
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2544
3137
  TabButton,
2545
3138
  {
2546
3139
  active: tab === "edit",
2547
- icon: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Pencil, { className: "h-4 w-4 shrink-0" }),
3140
+ icon: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pencil, { className: "h-4 w-4 shrink-0" }),
2548
3141
  label: "Edit",
2549
3142
  onClick: () => setTab("edit")
2550
3143
  }
@@ -2562,7 +3155,7 @@ function TabButton({
2562
3155
  label,
2563
3156
  onClick
2564
3157
  }) {
2565
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
3158
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2566
3159
  "button",
2567
3160
  {
2568
3161
  type: "button",
@@ -2575,7 +3168,7 @@ function TabButton({
2575
3168
  ),
2576
3169
  children: [
2577
3170
  icon,
2578
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "min-w-0 flex-1 truncate", children: label })
3171
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "min-w-0 flex-1 truncate", children: label })
2579
3172
  ]
2580
3173
  }
2581
3174
  );