@ai-matrx/design-system 0.18.22 → 0.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +28 -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.d.cts +1 -1
  31. package/dist/data-table/host.d.ts +1 -1
  32. package/dist/data-table/index.cjs +1665 -1012
  33. package/dist/data-table/index.cjs.map +1 -1
  34. package/dist/data-table/index.d.cts +2 -2
  35. package/dist/data-table/index.d.ts +2 -2
  36. package/dist/data-table/index.js +1517 -859
  37. package/dist/data-table/index.js.map +1 -1
  38. package/dist/data-table/infer-filter.d.cts +1 -1
  39. package/dist/data-table/infer-filter.d.ts +1 -1
  40. package/dist/data-table/layered-filters.d.cts +1 -1
  41. package/dist/data-table/layered-filters.d.ts +1 -1
  42. package/dist/data-table/pagination.cjs +1 -1
  43. package/dist/data-table/pagination.cjs.map +1 -1
  44. package/dist/data-table/pagination.js +1 -1
  45. package/dist/data-table/pagination.js.map +1 -1
  46. package/dist/data-table/query-control.d.cts +1 -1
  47. package/dist/data-table/query-control.d.ts +1 -1
  48. package/dist/data-table/scroll-pagination.cjs +85 -54
  49. package/dist/data-table/scroll-pagination.cjs.map +1 -1
  50. package/dist/data-table/scroll-pagination.js +85 -54
  51. package/dist/data-table/scroll-pagination.js.map +1 -1
  52. package/dist/data-table/types.cjs.map +1 -1
  53. package/dist/data-table/types.d.cts +1 -1
  54. package/dist/data-table/types.d.ts +1 -1
  55. package/dist/data-table/url-state.d.cts +1 -1
  56. package/dist/data-table/url-state.d.ts +1 -1
  57. package/dist/data-table/uuid-cell.cjs +1 -1
  58. package/dist/data-table/uuid-cell.cjs.map +1 -1
  59. package/dist/data-table/uuid-cell.js +1 -1
  60. package/dist/data-table/uuid-cell.js.map +1 -1
  61. package/dist/data-table/xlsx.d.cts +1 -1
  62. package/dist/data-table/xlsx.d.ts +1 -1
  63. package/dist/index.cjs +527 -0
  64. package/dist/index.cjs.map +1 -1
  65. package/dist/index.d.cts +1 -0
  66. package/dist/index.d.ts +1 -0
  67. package/dist/index.js +531 -0
  68. package/dist/index.js.map +1 -1
  69. package/dist/tap-target.cjs +636 -0
  70. package/dist/tap-target.cjs.map +1 -0
  71. package/dist/tap-target.css +151 -0
  72. package/dist/tap-target.d.cts +131 -0
  73. package/dist/tap-target.d.ts +131 -0
  74. package/dist/tap-target.js +608 -0
  75. package/dist/tap-target.js.map +1 -0
  76. package/dist/{types-CWW4Tur-.d.cts → types-BcIcmIxd.d.cts} +6 -1
  77. package/dist/{types-Cbnj1Qlm.d.ts → types-xTXSqmR7.d.ts} +6 -1
  78. package/package.json +14 -1
@@ -32,6 +32,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
32
32
  // src/content-transfer/index.tsx
33
33
  var content_transfer_exports = {};
34
34
  __export(content_transfer_exports, {
35
+ ALCHEMY_COPY_TRANSFORM_SVG: () => ALCHEMY_COPY_TRANSFORM_SVG,
35
36
  ALCHEMY_GLYPH_SVG: () => ALCHEMY_GLYPH_SVG,
36
37
  AlchemyGlyph: () => AlchemyGlyph,
37
38
  ContentTransferCapabilitiesProvider: () => ContentTransferCapabilitiesProvider,
@@ -47,7 +48,7 @@ __export(content_transfer_exports, {
47
48
  useContentTransferSurface: () => useContentTransferSurface
48
49
  });
49
50
  module.exports = __toCommonJS(content_transfer_exports);
50
- var React8 = __toESM(require("react"), 1);
51
+ var React9 = __toESM(require("react"), 1);
51
52
  var import_react_dom = require("react-dom");
52
53
  var import_content_transfer2 = require("@ai-matrx/kit/content-transfer");
53
54
 
@@ -485,14 +486,527 @@ var PopoverContent = React6.forwardRef(
485
486
  );
486
487
  PopoverContent.displayName = PopoverPrimitive.Content.displayName;
487
488
 
489
+ // src/tap-target/tap-target-button.tsx
490
+ var import_react = require("react");
491
+
492
+ // src/tooltip.tsx
493
+ var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"), 1);
494
+ var React7 = __toESM(require("react"), 1);
495
+ var import_jsx_runtime7 = require("react/jsx-runtime");
496
+ var Tooltip = TooltipPrimitive.Root;
497
+ var TooltipTrigger = TooltipPrimitive.Trigger;
498
+ var TooltipContent = React7.forwardRef(({ className, sideOffset = 4, container, animated = true, ...props }, ref) => {
499
+ const resolved = usePortalContainer(container);
500
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TooltipPrimitive.Portal, { container: resolved ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
501
+ TooltipPrimitive.Content,
502
+ {
503
+ ref,
504
+ "data-slot": "tooltip-content",
505
+ sideOffset,
506
+ className: cn(
507
+ "z-[10001] overflow-hidden rounded-md border border-border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md",
508
+ animated && MOTION_POPPER,
509
+ className
510
+ ),
511
+ ...props
512
+ }
513
+ ) });
514
+ });
515
+ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
516
+
517
+ // src/tap-target/cn.ts
518
+ function cn2(...values) {
519
+ return values.filter(Boolean).join(" ").trim();
520
+ }
521
+
522
+ // src/tap-target/link.ts
523
+ var LINK_SLOT = /* @__PURE__ */ Symbol.for("@ai-matrx/tap-target:link-component");
524
+ function getTapTargetLinkComponent() {
525
+ return globalThis[LINK_SLOT] ?? null;
526
+ }
527
+
528
+ // src/tap-target/tap-target-button.tsx
529
+ var import_jsx_runtime8 = require("react/jsx-runtime");
530
+ var EXTERNAL_RE = /^(https?:|mailto:|tel:)/i;
531
+ var TAP_OUTER_CLASS = "matrx-tap-target group";
532
+ var TAP_GROUP_OUTER_CLASS = "matrx-tap-target matrx-tap-target-sm group";
533
+ function IconContent({
534
+ icon,
535
+ children,
536
+ strokeWidth = 2,
537
+ className
538
+ }) {
539
+ if (icon) {
540
+ if ((0, import_react.isValidElement)(icon)) {
541
+ return (0, import_react.cloneElement)(icon, {
542
+ className: cn2(className, icon.props.className)
543
+ });
544
+ }
545
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className, children: icon });
546
+ }
547
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
548
+ "svg",
549
+ {
550
+ className,
551
+ fill: "none",
552
+ viewBox: "0 0 24 24",
553
+ stroke: "currentColor",
554
+ strokeWidth,
555
+ children
556
+ }
557
+ );
558
+ }
559
+ function resolveTapGeometry(label, size, mobileIconOnly) {
560
+ const inline = Boolean(label);
561
+ if (size === "sm") {
562
+ return {
563
+ 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,
564
+ inlineModifier: mobileIconOnly ? "matrx-tap-pill-mobile-icon-only-sm" : "matrx-tap-pill-inline-sm"
565
+ };
566
+ }
567
+ return {
568
+ outerClassName: inline && mobileIconOnly ? `${TAP_OUTER_CLASS} matrx-tap-target-mobile-icon-only` : inline ? `${TAP_OUTER_CLASS} matrx-tap-target-inline` : TAP_OUTER_CLASS,
569
+ inlineModifier: mobileIconOnly ? "matrx-tap-pill-mobile-icon-only" : "matrx-tap-pill-inline"
570
+ };
571
+ }
572
+ function buildTapInner({
573
+ label,
574
+ pillClassName,
575
+ iconClassName,
576
+ labelClassName,
577
+ inlineModifier,
578
+ icon,
579
+ children,
580
+ strokeWidth = 2
581
+ }) {
582
+ const iconEl = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
583
+ IconContent,
584
+ {
585
+ icon,
586
+ strokeWidth,
587
+ className: iconClassName,
588
+ children
589
+ }
590
+ );
591
+ const pillClasses = label ? `${pillClassName} ${inlineModifier}`.trim() : pillClassName;
592
+ if (!label) {
593
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: pillClasses, children: iconEl });
594
+ }
595
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: pillClasses, children: [
596
+ iconEl,
597
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: labelClassName ?? "matrx-tap-label", children: label })
598
+ ] });
599
+ }
600
+ function renderTapTarget({
601
+ size = "default",
602
+ pillClassName,
603
+ iconClassName,
604
+ labelClassName,
605
+ icon,
606
+ children,
607
+ strokeWidth,
608
+ label,
609
+ mobileIconOnly = false,
610
+ onClick,
611
+ as,
612
+ htmlFor,
613
+ ariaLabel,
614
+ disabled,
615
+ href,
616
+ target,
617
+ rel,
618
+ prefetch,
619
+ linkComponent,
620
+ tooltip,
621
+ tooltipSide,
622
+ tooltipAlign,
623
+ rest,
624
+ buttonRef
625
+ }) {
626
+ const { outerClassName, inlineModifier } = resolveTapGeometry(
627
+ label,
628
+ size,
629
+ mobileIconOnly
630
+ );
631
+ const responsiveLabelClassName = mobileIconOnly ? `${labelClassName ?? "matrx-tap-label"} matrx-tap-label-mobile-icon-only` : labelClassName;
632
+ const inner = buildTapInner({
633
+ label,
634
+ pillClassName,
635
+ iconClassName,
636
+ labelClassName: responsiveLabelClassName,
637
+ inlineModifier: label ? inlineModifier : "",
638
+ icon,
639
+ children,
640
+ strokeWidth
641
+ });
642
+ const resolvedTooltip = tooltip !== void 0 ? tooltip : label ? false : void 0;
643
+ const triggerAriaLabel = label && !mobileIconOnly ? void 0 : ariaLabel ?? label;
644
+ const trigger = renderTrigger({
645
+ href,
646
+ target,
647
+ rel,
648
+ prefetch,
649
+ linkComponent,
650
+ as,
651
+ htmlFor,
652
+ onClick,
653
+ ariaLabel: triggerAriaLabel,
654
+ disabled,
655
+ outerClassName,
656
+ children: inner,
657
+ rest,
658
+ buttonRef
659
+ });
660
+ return withTooltip(trigger, {
661
+ tooltip: resolvedTooltip,
662
+ ariaLabel: triggerAriaLabel,
663
+ disabled,
664
+ tooltipSide,
665
+ tooltipAlign
666
+ });
667
+ }
668
+ function renderTrigger({
669
+ href,
670
+ target,
671
+ rel,
672
+ prefetch,
673
+ linkComponent,
674
+ as,
675
+ htmlFor,
676
+ onClick,
677
+ ariaLabel,
678
+ disabled,
679
+ outerClassName,
680
+ children,
681
+ rest,
682
+ buttonRef
683
+ }) {
684
+ if (disabled && href) {
685
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
686
+ "span",
687
+ {
688
+ "aria-disabled": "true",
689
+ "aria-label": ariaLabel,
690
+ className: `${outerClassName} opacity-40 pointer-events-none`,
691
+ children
692
+ }
693
+ );
694
+ }
695
+ if (href) {
696
+ const isExternal = EXTERNAL_RE.test(href);
697
+ if (isExternal) {
698
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
699
+ "a",
700
+ {
701
+ href,
702
+ target: target ?? "_blank",
703
+ rel: rel ?? "noopener noreferrer",
704
+ "aria-label": ariaLabel,
705
+ className: outerClassName,
706
+ children
707
+ }
708
+ );
709
+ }
710
+ const Link = linkComponent ?? getTapTargetLinkComponent();
711
+ if (Link) {
712
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
713
+ Link,
714
+ {
715
+ href,
716
+ target,
717
+ rel,
718
+ prefetch,
719
+ "aria-label": ariaLabel,
720
+ className: outerClassName,
721
+ children
722
+ }
723
+ );
724
+ }
725
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
726
+ "a",
727
+ {
728
+ href,
729
+ target,
730
+ rel,
731
+ "aria-label": ariaLabel,
732
+ className: outerClassName,
733
+ children
734
+ }
735
+ );
736
+ }
737
+ if (as === "label") {
738
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
739
+ "label",
740
+ {
741
+ htmlFor,
742
+ "aria-label": ariaLabel,
743
+ className: outerClassName,
744
+ children
745
+ }
746
+ );
747
+ }
748
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
749
+ "button",
750
+ {
751
+ ref: buttonRef,
752
+ type: "button",
753
+ onClick,
754
+ "aria-label": ariaLabel,
755
+ disabled,
756
+ ...rest,
757
+ className: outerClassName,
758
+ children
759
+ }
760
+ );
761
+ }
762
+ function withTooltip(trigger, {
763
+ tooltip,
764
+ ariaLabel,
765
+ disabled,
766
+ tooltipSide = "top",
767
+ tooltipAlign = "center"
768
+ }) {
769
+ if (tooltip === false) return trigger;
770
+ const label = typeof tooltip === "string" && tooltip.length > 0 ? tooltip : ariaLabel;
771
+ if (!label) return trigger;
772
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Tooltip, { children: [
773
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipTrigger, { asChild: true, children: disabled ? (
774
+ // Radix Tooltip triggers need a hoverable element; a disabled button
775
+ // does not dispatch pointer events, so we wrap in a span for the
776
+ // trigger target while keeping the disabled visual state.
777
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "inline-flex", children: trigger })
778
+ ) : trigger }),
779
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipContent, { side: tooltipSide, align: tooltipAlign, children: label })
780
+ ] });
781
+ }
782
+ var TapTargetButton = (0, import_react.forwardRef)(function TapTargetButton2({
783
+ icon,
784
+ children,
785
+ strokeWidth = 2,
786
+ onClick,
787
+ className,
788
+ as,
789
+ htmlFor,
790
+ ariaLabel,
791
+ disabled,
792
+ href,
793
+ target,
794
+ rel,
795
+ prefetch,
796
+ linkComponent,
797
+ tooltip,
798
+ tooltipSide,
799
+ tooltipAlign,
800
+ label,
801
+ mobileIconOnly,
802
+ ...rest
803
+ }, ref) {
804
+ const color = className ?? "text-foreground";
805
+ return renderTapTarget({
806
+ icon,
807
+ children,
808
+ strokeWidth,
809
+ onClick,
810
+ as,
811
+ htmlFor,
812
+ ariaLabel,
813
+ disabled,
814
+ href,
815
+ target,
816
+ rel,
817
+ prefetch,
818
+ linkComponent,
819
+ tooltip,
820
+ tooltipSide,
821
+ tooltipAlign,
822
+ label,
823
+ mobileIconOnly,
824
+ pillClassName: "matrx-tap-pill matrx-glass-thin-border",
825
+ iconClassName: `matrx-tap-icon ${color}`,
826
+ rest,
827
+ buttonRef: ref
828
+ });
829
+ });
830
+ var TapTargetButtonTransparent = (0, import_react.forwardRef)(function TapTargetButtonTransparent2({
831
+ icon,
832
+ children,
833
+ strokeWidth = 2,
834
+ onClick,
835
+ className,
836
+ as,
837
+ htmlFor,
838
+ ariaLabel,
839
+ disabled,
840
+ href,
841
+ target,
842
+ rel,
843
+ prefetch,
844
+ linkComponent,
845
+ tooltip,
846
+ tooltipSide,
847
+ tooltipAlign,
848
+ label,
849
+ mobileIconOnly,
850
+ ...rest
851
+ }, ref) {
852
+ const color = className ?? "text-foreground";
853
+ return renderTapTarget({
854
+ icon,
855
+ children,
856
+ strokeWidth,
857
+ onClick,
858
+ as,
859
+ htmlFor,
860
+ ariaLabel,
861
+ disabled,
862
+ href,
863
+ target,
864
+ rel,
865
+ prefetch,
866
+ linkComponent,
867
+ tooltip,
868
+ tooltipSide,
869
+ tooltipAlign,
870
+ label,
871
+ mobileIconOnly,
872
+ pillClassName: "matrx-tap-pill hover:bg-muted active:bg-muted-foreground/15",
873
+ iconClassName: `matrx-tap-icon ${color}`,
874
+ rest,
875
+ buttonRef: ref
876
+ });
877
+ });
878
+ var TapTargetButtonSolid = (0, import_react.forwardRef)(function TapTargetButtonSolid2({
879
+ icon,
880
+ children,
881
+ strokeWidth = 2,
882
+ onClick,
883
+ as,
884
+ htmlFor,
885
+ ariaLabel,
886
+ disabled,
887
+ href,
888
+ target,
889
+ rel,
890
+ prefetch,
891
+ linkComponent,
892
+ bgColor = "bg-primary",
893
+ iconColor = "text-primary-foreground",
894
+ hoverBgColor = "hover:bg-primary/80",
895
+ activeBgColor = "active:brightness-90",
896
+ tooltip,
897
+ tooltipSide,
898
+ tooltipAlign,
899
+ label,
900
+ mobileIconOnly,
901
+ ...rest
902
+ }, ref) {
903
+ return renderTapTarget({
904
+ icon,
905
+ children,
906
+ strokeWidth,
907
+ onClick,
908
+ as,
909
+ htmlFor,
910
+ ariaLabel,
911
+ disabled,
912
+ href,
913
+ target,
914
+ rel,
915
+ prefetch,
916
+ linkComponent,
917
+ tooltip,
918
+ tooltipSide,
919
+ tooltipAlign,
920
+ label,
921
+ mobileIconOnly,
922
+ pillClassName: `matrx-tap-pill ${bgColor} ${iconColor} ${hoverBgColor} ${activeBgColor}`,
923
+ iconClassName: `matrx-tap-icon ${iconColor}`,
924
+ labelClassName: `matrx-tap-label ${iconColor}`,
925
+ rest,
926
+ buttonRef: ref
927
+ });
928
+ });
929
+ var TapTargetButtonDestructive = (0, import_react.forwardRef)(function TapTargetButtonDestructive2({
930
+ bgColor = "bg-destructive",
931
+ iconColor = "text-destructive-foreground",
932
+ hoverBgColor = "hover:bg-destructive/90",
933
+ ...rest
934
+ }, ref) {
935
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
936
+ TapTargetButtonSolid,
937
+ {
938
+ ref,
939
+ bgColor,
940
+ iconColor,
941
+ hoverBgColor,
942
+ ...rest
943
+ }
944
+ );
945
+ });
946
+ var TapTargetButtonForGroup = (0, import_react.forwardRef)(function TapTargetButtonForGroup2({
947
+ icon,
948
+ children,
949
+ strokeWidth = 2,
950
+ onClick,
951
+ className,
952
+ as,
953
+ htmlFor,
954
+ ariaLabel,
955
+ disabled,
956
+ href,
957
+ target,
958
+ rel,
959
+ prefetch,
960
+ linkComponent,
961
+ tooltip,
962
+ tooltipSide,
963
+ tooltipAlign,
964
+ label,
965
+ mobileIconOnly,
966
+ ...rest
967
+ }, ref) {
968
+ const color = className ?? "text-foreground";
969
+ return renderTapTarget({
970
+ size: "sm",
971
+ icon,
972
+ children,
973
+ strokeWidth,
974
+ onClick,
975
+ as,
976
+ htmlFor,
977
+ ariaLabel,
978
+ disabled,
979
+ href,
980
+ target,
981
+ rel,
982
+ prefetch,
983
+ linkComponent,
984
+ tooltip,
985
+ tooltipSide,
986
+ tooltipAlign,
987
+ label,
988
+ mobileIconOnly,
989
+ pillClassName: "matrx-tap-pill matrx-tap-pill-sm matrx-glass-interactive",
990
+ iconClassName: `matrx-tap-icon ${color}`,
991
+ labelClassName: `matrx-tap-label ${color}`,
992
+ rest,
993
+ buttonRef: ref
994
+ });
995
+ });
996
+
488
997
  // src/content-transfer/icon.ts
489
- 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"];
490
- 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>`;
998
+ var ALCHEMY_GLYPH_PATHS = {
999
+ 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"],
1000
+ "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"]
1001
+ };
1002
+ 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>`;
1003
+ var ALCHEMY_GLYPH_SVG = svg(ALCHEMY_GLYPH_PATHS.portal);
1004
+ var ALCHEMY_COPY_TRANSFORM_SVG = svg(ALCHEMY_GLYPH_PATHS["copy-transform"]);
491
1005
 
492
1006
  // src/content-transfer/matrx-copy.tsx
493
- var React7 = __toESM(require("react"), 1);
1007
+ var React8 = __toESM(require("react"), 1);
494
1008
  var import_content_transfer = require("@ai-matrx/kit/content-transfer");
495
- var import_jsx_runtime7 = require("react/jsx-runtime");
1009
+ var import_jsx_runtime9 = require("react/jsx-runtime");
496
1010
  var resolve = (value) => typeof value === "function" ? value() : value;
497
1011
  var asPayload = (value) => ({
498
1012
  kind: "markdown",
@@ -538,7 +1052,7 @@ var sourceFor = (id, label, build) => ({
538
1052
  });
539
1053
  function MatrxCopyMenu(props) {
540
1054
  const inherited = useContentTransferCapabilities();
541
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1055
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
542
1056
  MatrxCopyMenuSession,
543
1057
  {
544
1058
  ...props
@@ -550,12 +1064,12 @@ function MatrxCopyMenu(props) {
550
1064
  );
551
1065
  }
552
1066
  function MatrxCopyMenuSession(props) {
553
- const instance = React7.useId();
554
- const controller = React7.useRef(null);
1067
+ const instance = React8.useId();
1068
+ const controller = React8.useRef(null);
555
1069
  const capabilities = useContentTransferCapabilities();
556
1070
  const transport = capabilities.transport ?? (0, import_content_transfer.createBrowserTransport)();
557
- const [modal, setModal] = React7.useState(null);
558
- const [configuration, setConfiguration] = React7.useState(null);
1071
+ const [modal, setModal] = React8.useState(null);
1072
+ const [configuration, setConfiguration] = React8.useState(null);
559
1073
  const copyVisible = !props.hide?.includes("copy");
560
1074
  const aiVisible = !props.hide?.includes("ai");
561
1075
  const exportVisible = !props.hide?.includes("export");
@@ -742,11 +1256,13 @@ function MatrxCopyMenuSession(props) {
742
1256
  const source = (props.primarySource === "table" ? table : void 0) ?? json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
743
1257
  if (!source && !actions.length) return null;
744
1258
  const target = source ?? make("actions", () => ({ kind: "text", text: props.label }));
745
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
746
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1259
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1260
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
747
1261
  ContentTransferMenu,
748
1262
  {
749
1263
  source: target,
1264
+ ...props.icon !== void 0 ? { icon: props.icon } : {},
1265
+ ...props.triggerVariant !== void 0 ? { triggerVariant: props.triggerVariant } : {},
750
1266
  controllerRef: controller,
751
1267
  label: props.label,
752
1268
  variants,
@@ -778,7 +1294,7 @@ function MatrxCopyMenuSession(props) {
778
1294
  if (!open) setModal(null);
779
1295
  }
780
1296
  }),
781
- configuration ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1297
+ configuration ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
782
1298
  SourceConfiguration,
783
1299
  {
784
1300
  restoreFocus: () => controller.current?.focusTrigger(),
@@ -805,14 +1321,14 @@ function SourceConfiguration({
805
1321
  onPrepare
806
1322
  }) {
807
1323
  const custom = configuration.custom;
808
- const handingOff = React7.useRef(false);
1324
+ const handingOff = React8.useRef(false);
809
1325
  const groomer = configuration.groomer;
810
- const [values, setValues] = React7.useState(
1326
+ const [values, setValues] = React8.useState(
811
1327
  () => Object.fromEntries(
812
1328
  custom?.options.map((option) => [option.key, option.default]) ?? []
813
1329
  )
814
1330
  );
815
- const [sections, setSections] = React7.useState(
1331
+ const [sections, setSections] = React8.useState(
816
1332
  () => Object.fromEntries(
817
1333
  groomer?.sections.map((section) => [
818
1334
  section.id,
@@ -820,8 +1336,8 @@ function SourceConfiguration({
820
1336
  ]) ?? []
821
1337
  )
822
1338
  );
823
- const [error, setError] = React7.useState(null);
824
- const [busy, setBusy] = React7.useState(false);
1339
+ const [error, setError] = React8.useState(null);
1340
+ const [busy, setBusy] = React8.useState(false);
825
1341
  const title = custom?.dialogTitle ?? groomer?.label ?? "Customize source";
826
1342
  let prepared = null;
827
1343
  let buildError = null;
@@ -858,14 +1374,14 @@ function SourceConfiguration({
858
1374
  } catch (cause) {
859
1375
  buildError = cause instanceof Error ? cause.message : "Could not prepare this source.";
860
1376
  }
861
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1377
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
862
1378
  Dialog,
863
1379
  {
864
1380
  open: true,
865
1381
  onOpenChange: (open) => {
866
1382
  if (!open && !busy) onClose();
867
1383
  },
868
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1384
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
869
1385
  DialogContent,
870
1386
  {
871
1387
  onCloseAutoFocus: (event) => {
@@ -874,23 +1390,23 @@ function SourceConfiguration({
874
1390
  },
875
1391
  className: "matrx-alchemy-workspace matrx-alchemy-configuration",
876
1392
  children: [
877
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(DialogHeader, { children: [
878
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DialogTitle, { children: title }),
879
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DialogDescription, { children: custom?.dialogDescription ?? "Choose the source detail, then prepare, edit, summarize, copy or export it in Alchemy." })
1393
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DialogHeader, { children: [
1394
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DialogTitle, { children: title }),
1395
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DialogDescription, { children: custom?.dialogDescription ?? "Choose the source detail, then prepare, edit, summarize, copy or export it in Alchemy." })
880
1396
  ] }),
881
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
882
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "matrx-alchemy-main matrx-alchemy-toolbar", children: [
883
- custom?.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { children: [
1397
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
1398
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "matrx-alchemy-main matrx-alchemy-toolbar", children: [
1399
+ custom?.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { children: [
884
1400
  option.label,
885
- "hint" in option && option.hint ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("small", { children: option.hint }) : null,
886
- option.kind === "toggle" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1401
+ "hint" in option && option.hint ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("small", { children: option.hint }) : null,
1402
+ option.kind === "toggle" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
887
1403
  "input",
888
1404
  {
889
1405
  type: "checkbox",
890
1406
  checked: Boolean(values[option.key]),
891
1407
  onChange: (event) => setValues({ ...values, [option.key]: event.target.checked })
892
1408
  }
893
- ) : option.kind === "preset" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1409
+ ) : option.kind === "preset" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
894
1410
  "select",
895
1411
  {
896
1412
  value: Number(values[option.key]),
@@ -898,10 +1414,10 @@ function SourceConfiguration({
898
1414
  ...values,
899
1415
  [option.key]: Number(event.target.value)
900
1416
  }),
901
- children: option.options.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: choice.value, children: choice.label }, choice.value))
1417
+ children: option.options.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: choice.value, children: choice.label }, choice.value))
902
1418
  }
903
- ) : option.kind === "slider" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
904
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1419
+ ) : option.kind === "slider" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1420
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
905
1421
  "input",
906
1422
  {
907
1423
  type: "range",
@@ -915,9 +1431,9 @@ function SourceConfiguration({
915
1431
  })
916
1432
  }
917
1433
  ),
918
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: option.formatValue(Number(values[option.key])) })
919
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
920
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1434
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: option.formatValue(Number(values[option.key])) })
1435
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1436
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
921
1437
  "input",
922
1438
  {
923
1439
  type: "number",
@@ -930,7 +1446,7 @@ function SourceConfiguration({
930
1446
  })
931
1447
  }
932
1448
  ),
933
- option.presets?.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1449
+ option.presets?.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
934
1450
  Button,
935
1451
  {
936
1452
  type: "button",
@@ -943,8 +1459,8 @@ function SourceConfiguration({
943
1459
  ))
944
1460
  ] })
945
1461
  ] }, option.key)),
946
- groomer ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
947
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1462
+ groomer ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1463
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { children: ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
948
1464
  Button,
949
1465
  {
950
1466
  type: "button",
@@ -962,9 +1478,9 @@ function SourceConfiguration({
962
1478
  },
963
1479
  level
964
1480
  )) }),
965
- groomer.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { children: [
1481
+ groomer.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { children: [
966
1482
  section.title,
967
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1483
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
968
1484
  "select",
969
1485
  {
970
1486
  value: sections[section.id],
@@ -973,26 +1489,26 @@ function SourceConfiguration({
973
1489
  [section.id]: event.target.value
974
1490
  }),
975
1491
  children: [
976
- ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: level, children: section.levelLabels?.[level] ?? level }, level)),
977
- section.cuttable ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "off", children: "Exclude" }) : null
1492
+ ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: level, children: section.levelLabels?.[level] ?? level }, level)),
1493
+ section.cuttable ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "off", children: "Exclude" }) : null
978
1494
  ]
979
1495
  }
980
1496
  ),
981
- section.description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: section.description }) : null
1497
+ section.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: section.description }) : null
982
1498
  ] }, section.id))
983
1499
  ] }) : null
984
1500
  ] }),
985
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { children: [
1501
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("p", { children: [
986
1502
  text.length.toLocaleString(),
987
1503
  " characters \xB7 approximately",
988
1504
  " ",
989
1505
  Math.ceil(text.length / 4).toLocaleString(),
990
1506
  " tokens"
991
1507
  ] }),
992
- error || buildError ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { role: "alert", children: error ?? buildError }) : null
1508
+ error || buildError ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { role: "alert", children: error ?? buildError }) : null
993
1509
  ] }),
994
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(DialogFooter, { children: [
995
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1510
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DialogFooter, { children: [
1511
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
996
1512
  Button,
997
1513
  {
998
1514
  type: "button",
@@ -1003,7 +1519,7 @@ function SourceConfiguration({
1003
1519
  children: "Cancel"
1004
1520
  }
1005
1521
  ),
1006
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1522
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1007
1523
  Button,
1008
1524
  {
1009
1525
  type: "button",
@@ -1094,83 +1610,108 @@ function groomerPresetVariants(getConfig) {
1094
1610
  }
1095
1611
 
1096
1612
  // src/content-transfer/index.tsx
1097
- var import_jsx_runtime8 = require("react/jsx-runtime");
1098
- function AlchemyGlyph(props) {
1099
- return /* @__PURE__ */ (0, import_jsx_runtime8.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_runtime8.jsx)("path", { d }, d)) });
1613
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1614
+ function AlchemyGlyph({ icon = "portal", ...props }) {
1615
+ 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[icon].map((d) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d }, d)) });
1100
1616
  }
1101
- var CapabilityContext = React8.createContext({});
1617
+ var CapabilityContext = React9.createContext({});
1102
1618
  function ContentTransferCapabilitiesProvider({ value, children }) {
1103
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CapabilityContext.Provider, { value, children });
1619
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CapabilityContext.Provider, { value, children });
1104
1620
  }
1105
- var useContentTransferCapabilities = () => React8.useContext(CapabilityContext);
1106
- var SurfaceContext = React8.createContext(null);
1621
+ var useContentTransferCapabilities = () => React9.useContext(CapabilityContext);
1622
+ var SurfaceContext = React9.createContext(null);
1107
1623
  function ContentTransferSurfaceProvider({ handle, children }) {
1108
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SurfaceContext.Provider, { value: handle, children });
1624
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SurfaceContext.Provider, { value: handle, children });
1109
1625
  }
1110
- var useContentTransferSurface = () => React8.useContext(SurfaceContext);
1626
+ var useContentTransferSurface = () => React9.useContext(SurfaceContext);
1111
1627
  function MenuPresentation({ label, hint, icon: Icon }) {
1112
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1113
- Icon ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { className: "matrx-alchemy-menu-icon" }) : null,
1114
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
1628
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1629
+ Icon ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { className: "matrx-alchemy-menu-icon" }) : null,
1630
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
1115
1631
  label,
1116
- hint ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
1632
+ hint ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
1117
1633
  ] })
1118
1634
  ] });
1119
1635
  }
1636
+ function DestinationPresentation({ action }) {
1637
+ const paths = {
1638
+ notes: "M5 3h14v18H5zM8 8h8M8 12h8M8 16h5",
1639
+ scratch: "M5 3h14v18H5zM9 12h6M12 9v6",
1640
+ document: "M6 3h8l4 4v14H6zM14 3v5h4M9 12h6M9 16h6",
1641
+ workbook: "M3 4h18v16H3zM3 9h18M9 4v16M15 9v11M3 15h18",
1642
+ task: "M9 6h11M9 12h11M9 18h11M3 6l1 1 2-2M3 12l1 1 2-2M3 18l1 1 2-2",
1643
+ attach: "m9 12 5-5a3 3 0 0 1 4 4l-7 7a5 5 0 0 1-7-7l8-8M7 14l7-7",
1644
+ code: "m8 6-6 6 6 6m8-12 6 6-6 6m-3-14-2 16",
1645
+ chat: "M4 4h16v13H9l-5 4zM8 9h8M8 13h5",
1646
+ assistant: "M3 4h18v16H3zM15 4v16M6 9h6M6 13h4",
1647
+ 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"
1648
+ };
1649
+ const path = paths[action.id.replace(/^matrx:/, "")];
1650
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1651
+ !action.icon ? path ? /* @__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: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: path }) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { file: true }) : null,
1652
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MenuPresentation, { ...action })
1653
+ ] });
1654
+ }
1655
+ function ReceiptLink({ target }) {
1656
+ return target?.href && /^(\/(?!\/)|https?:\/\/)/.test(target.href) ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("a", { className: "matrx-alchemy-receipt-link", href: target.href, children: [
1657
+ "Open ",
1658
+ target.kind
1659
+ ] }) : null;
1660
+ }
1120
1661
  function PaletteGlyph({ format, ai = false, file = false, kind }) {
1121
- if (kind === "ai-copy") return /* @__PURE__ */ (0, import_jsx_runtime8.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: [
1122
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("rect", { x: "5", y: "5", width: "11", height: "14", rx: "2" }),
1123
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M9 3h6a2 2 0 0 1 2 2v10" }),
1124
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "m18.5 3 .55 1.45L20.5 5l-1.45.55L18.5 7l-.55-1.45L16.5 5l1.45-.55z" })
1662
+ 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: [
1663
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { x: "5", y: "5", width: "11", height: "14", rx: "2" }),
1664
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M9 3h6a2 2 0 0 1 2 2v10" }),
1665
+ /* @__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" })
1125
1666
  ] });
1126
- if (kind === "sliders") return /* @__PURE__ */ (0, import_jsx_runtime8.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: [
1127
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M4 6h16M4 12h16M4 18h16" }),
1128
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M8 3v6M16 9v6M10 15v6" })
1667
+ 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: [
1668
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 6h16M4 12h16M4 18h16" }),
1669
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M8 3v6M16 9v6M10 15v6" })
1129
1670
  ] });
1130
- if (ai) return /* @__PURE__ */ (0, import_jsx_runtime8.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: [
1131
- /* @__PURE__ */ (0, import_jsx_runtime8.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" }),
1132
- /* @__PURE__ */ (0, import_jsx_runtime8.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" }),
1133
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M12 5v14M8 9h1M15 9h1M8 15h1M15 15h1" })
1671
+ 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: [
1672
+ /* @__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" }),
1673
+ /* @__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" }),
1674
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 5v14M8 9h1M15 9h1M8 15h1M15 15h1" })
1134
1675
  ] });
1135
- if (file) return /* @__PURE__ */ (0, import_jsx_runtime8.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: [
1136
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M6 3h8l4 4v14H6z" }),
1137
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M14 3v5h5M9 13h6M9 17h6" })
1676
+ 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: [
1677
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M6 3h8l4 4v14H6z" }),
1678
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 3v5h5M9 13h6M9 17h6" })
1138
1679
  ] });
1139
- const path = format === "json" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1140
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M9 4C7 4 7 7 5 7v3c2 0 2 1 2 2s0 2-2 2v3c2 0 2 3 4 3" }),
1141
- /* @__PURE__ */ (0, import_jsx_runtime8.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" })
1142
- ] }) : format === "compact-json" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1143
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "m14 10 7-7" }),
1144
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M20 10h-6V4" }),
1145
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "m3 21 7-7" }),
1146
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M4 14h6v6" })
1147
- ] }) : format === "csv" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1148
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("rect", { x: "4", y: "4", width: "16", height: "16", rx: "1" }),
1149
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M4 10h16M10 4v16" })
1150
- ] }) : format === "tsv" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1151
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1152
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M14 2v6h6M8 13h2M14 13h2M8 17h2M14 17h2" })
1153
- ] }) : format === "xlsx" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1154
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1155
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M14 2v6h6M8 13h8M8 17h8M12 11v8" })
1156
- ] }) : format === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1157
- /* @__PURE__ */ (0, import_jsx_runtime8.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" }),
1158
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M14 2v6h6M10 13l-2 2 2 2M14 17l2-2-2-2" })
1159
- ] }) : format === "html" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M15 6h6M3 6h7M3 12h18M3 18h12" }) }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M4 7V4h16v3M9 20h6M12 4v16" }) });
1160
- return /* @__PURE__ */ (0, import_jsx_runtime8.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 });
1680
+ const path = format === "json" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1681
+ /* @__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" }),
1682
+ /* @__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" })
1683
+ ] }) : format === "compact-json" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1684
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m14 10 7-7" }),
1685
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M20 10h-6V4" }),
1686
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m3 21 7-7" }),
1687
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 14h6v6" })
1688
+ ] }) : format === "csv" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1689
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { x: "4", y: "4", width: "16", height: "16", rx: "1" }),
1690
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 10h16M10 4v16" })
1691
+ ] }) : format === "tsv" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1692
+ /* @__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" }),
1693
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v6h6M8 13h2M14 13h2M8 17h2M14 17h2" })
1694
+ ] }) : format === "xlsx" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1695
+ /* @__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" }),
1696
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v6h6M8 13h8M8 17h8M12 11v8" })
1697
+ ] }) : format === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1698
+ /* @__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" }),
1699
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v6h6M10 13l-2 2 2 2M14 17l2-2-2-2" })
1700
+ ] }) : 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" }) });
1701
+ 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 });
1161
1702
  }
1162
1703
  function PaletteRows({ title, items, onRun, extra, ai = false, glyphKind, fallbackHint }) {
1163
1704
  if (!items.length && !extra) return null;
1164
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
1165
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: title }),
1705
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
1706
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: title }),
1166
1707
  items.map((item) => {
1167
1708
  const label = item.copyLabel ?? item.label;
1168
1709
  const hint = item.hint ?? fallbackHint;
1169
- return /* @__PURE__ */ (0, import_jsx_runtime8.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: [
1170
- item.icon ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(item.icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PaletteGlyph, { ai, ...glyphKind ? { kind: glyphKind } : {} }),
1171
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
1710
+ 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: [
1711
+ 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 } : {} }),
1712
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
1172
1713
  label,
1173
- hint ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
1714
+ hint ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
1174
1715
  ] })
1175
1716
  ] }, item.id);
1176
1717
  }),
@@ -1213,10 +1754,10 @@ function snapshotContent(snapshot) {
1213
1754
  return JSON.stringify({ sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits });
1214
1755
  }
1215
1756
  function useFence() {
1216
- const mounted = React8.useRef(true);
1217
- const nextId = React8.useRef(0);
1218
- const active = React8.useRef(/* @__PURE__ */ new Set());
1219
- React8.useEffect(() => {
1757
+ const mounted = React9.useRef(true);
1758
+ const nextId = React9.useRef(0);
1759
+ const active = React9.useRef(/* @__PURE__ */ new Set());
1760
+ React9.useEffect(() => {
1220
1761
  mounted.current = true;
1221
1762
  return () => {
1222
1763
  mounted.current = false;
@@ -1225,14 +1766,14 @@ function useFence() {
1225
1766
  active.current.clear();
1226
1767
  };
1227
1768
  }, []);
1228
- const begin = React8.useCallback(() => {
1769
+ const begin = React9.useCallback(() => {
1229
1770
  const controller = new AbortController();
1230
1771
  active.current.add(controller);
1231
1772
  return { controller, id: ++nextId.current };
1232
1773
  }, []);
1233
- const finish = React8.useCallback((controller) => active.current.delete(controller), []);
1234
- const valid = React8.useCallback((id, controller) => mounted.current && !controller.signal.aborted && nextId.current === id, []);
1235
- const abortAll = React8.useCallback(() => {
1774
+ const finish = React9.useCallback((controller) => active.current.delete(controller), []);
1775
+ const valid = React9.useCallback((id, controller) => mounted.current && !controller.signal.aborted && nextId.current === id, []);
1776
+ const abortAll = React9.useCallback(() => {
1236
1777
  nextId.current += 1;
1237
1778
  active.current.forEach((c) => c.abort());
1238
1779
  active.current.clear();
@@ -1261,45 +1802,47 @@ async function buildArtifact(draft, format, label) {
1261
1802
  return (0, import_content_transfer2.serialize)(draft, format, { spreadsheetSafe: format === "csv" || format === "tsv", filename: `${filenameFor(label)}.${extension}` });
1262
1803
  }
1263
1804
  function ContentTransferMenu(props) {
1264
- const inherited = React8.useContext(CapabilityContext);
1805
+ const inherited = React9.useContext(CapabilityContext);
1265
1806
  const identityKey = props.capabilities?.identityKey ?? inherited.identityKey;
1266
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
1807
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
1267
1808
  }
1268
- 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 }) {
1269
- const triggerRef = React8.useRef(null);
1270
- const inherited = React8.useContext(CapabilityContext);
1271
- const nearestSurface = React8.useContext(SurfaceContext);
1809
+ 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" }) {
1810
+ const triggerRef = React9.useRef(null);
1811
+ const inherited = React9.useContext(CapabilityContext);
1812
+ const nearestSurface = React9.useContext(SurfaceContext);
1272
1813
  const fence = useFence();
1273
- const [menuCapture, setMenuCapture] = React8.useState(null);
1274
- const [menuStatus, setMenuStatus] = React8.useState("idle");
1275
- const [workspaces, setWorkspaces] = React8.useState({});
1276
- const [workspaceKey, setWorkspaceKey] = React8.useState(null);
1277
- const [workspaceOpen, setWorkspaceOpen] = React8.useState(false);
1278
- const workspaceCaptures = React8.useRef(/* @__PURE__ */ new Map());
1279
- const externalWorkspaceKeys = React8.useRef(/* @__PURE__ */ new Set());
1280
- const [notice, setNotice] = React8.useState(null);
1281
- const [paletteOpen, setPaletteOpen] = React8.useState(false);
1282
- const [mode, setMode] = React8.useState("copy");
1283
- const scopes = React8.useMemo(() => table?.availableScopes ?? ["target"], [table]);
1814
+ const [menuCapture, setMenuCapture] = React9.useState(null);
1815
+ const [menuStatus, setMenuStatus] = React9.useState("idle");
1816
+ const [workspaces, setWorkspaces] = React9.useState({});
1817
+ const [workspaceKey, setWorkspaceKey] = React9.useState(null);
1818
+ const [workspaceOpen, setWorkspaceOpen] = React9.useState(false);
1819
+ const workspaceCaptures = React9.useRef(/* @__PURE__ */ new Map());
1820
+ const externalWorkspaceKeys = React9.useRef(/* @__PURE__ */ new Set());
1821
+ const [notice, setNotice] = React9.useState(null);
1822
+ const [receiptTarget, setReceiptTarget] = React9.useState();
1823
+ const [paletteOpen, setPaletteOpen] = React9.useState(false);
1824
+ const [mode, setMode] = React9.useState("copy");
1825
+ const scopes = React9.useMemo(() => table?.availableScopes ?? ["target"], [table]);
1284
1826
  const initialScope = table?.initialScope ?? "target";
1285
1827
  if (!scopes.includes(initialScope)) throw new Error("Alchemy initialScope must be included in availableScopes.");
1286
1828
  const primary = surface ?? source ?? nearestSurface;
1287
1829
  const sourceLabel = label ?? (surface?.surfaceName ?? (source && "label" in source ? source.label : nearestSurface?.surfaceName) ?? "content");
1288
1830
  const primaryWorkspaceKey = `primary:${materialIdentity(primary)}`;
1289
1831
  const nearestWorkspaceKey = source && !surface && nearestSurface ? `surface:${materialIdentity(nearestSurface)}` : null;
1290
- const variantWorkspaceKeys = React8.useMemo(() => new Map(variants.map((variant) => [variant.id, `variant:${variant.id}:${materialIdentity(variant.source)}`])), [variants]);
1832
+ const variantWorkspaceKeys = React9.useMemo(() => new Map(variants.map((variant) => [variant.id, `variant:${variant.id}:${materialIdentity(variant.source)}`])), [variants]);
1291
1833
  const transport = local?.transport ?? inherited.transport ?? (0, import_content_transfer2.createBrowserTransport)();
1292
1834
  const ai = local?.ai ?? inherited.ai;
1293
- const providerPreferences = React8.useMemo(() => (0, import_content_transfer2.resolveTransferPreferences)(inherited.preferences, local?.preferences), [inherited.preferences, local?.preferences]);
1294
- const adapters = React8.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(BUILT_INS, inherited.formats ?? [], local?.formats ?? []).filter((x) => "build" in x), [inherited.formats, local?.formats]);
1295
- const registeredActions = React8.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(inherited.actions ?? [], local?.actions ?? [], actions), [actions, inherited.actions, local?.actions]);
1296
- React8.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(variants), [variants]);
1297
- const report = React8.useCallback((result) => {
1835
+ const providerPreferences = React9.useMemo(() => (0, import_content_transfer2.resolveTransferPreferences)(inherited.preferences, local?.preferences), [inherited.preferences, local?.preferences]);
1836
+ const adapters = React9.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(BUILT_INS, inherited.formats ?? [], local?.formats ?? []).filter((x) => "build" in x), [inherited.formats, local?.formats]);
1837
+ const registeredActions = React9.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(inherited.actions ?? [], local?.actions ?? [], actions), [actions, inherited.actions, local?.actions]);
1838
+ React9.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(variants), [variants]);
1839
+ const report = React9.useCallback((result) => {
1298
1840
  inherited.onOutcome?.(result);
1299
1841
  local?.onOutcome?.(result);
1300
1842
  setNotice(outcomeMessage(result));
1843
+ setReceiptTarget("target" in result ? result.target : void 0);
1301
1844
  }, [inherited, local]);
1302
- React8.useEffect(() => {
1845
+ React9.useEffect(() => {
1303
1846
  const valid = /* @__PURE__ */ new Set([primaryWorkspaceKey, ...nearestWorkspaceKey ? [nearestWorkspaceKey] : [], ...variantWorkspaceKeys.values(), ...externalWorkspaceKeys.current]);
1304
1847
  setWorkspaces((current) => Object.fromEntries(Object.entries(current).filter(([key]) => valid.has(key))));
1305
1848
  for (const key of workspaceCaptures.current.keys()) if (!valid.has(key)) workspaceCaptures.current.delete(key);
@@ -1308,7 +1851,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1308
1851
  setWorkspaceOpen(false);
1309
1852
  }
1310
1853
  }, [nearestWorkspaceKey, primaryWorkspaceKey, variantWorkspaceKeys, workspaceKey]);
1311
- const captureOne = React8.useCallback(async (material, scope, signal, applyMenuProjection = false, collectPages = true) => {
1854
+ const captureOne = React9.useCallback(async (material, scope, signal, applyMenuProjection = false, collectPages = true) => {
1312
1855
  if (!material) throw new Error("Alchemy needs a source or a mounted transfer surface.");
1313
1856
  let sourceMaterial;
1314
1857
  if ("instanceId" in material) {
@@ -1342,14 +1885,14 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1342
1885
  if (result.snapshot.payload.kind !== "rows") throw new Error("All-matching export requires tabular content.");
1343
1886
  return { snapshot: (0, import_content_transfer2.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 } : {} };
1344
1887
  }, [preferences, projection, providerPreferences, sections, sourceLabel]);
1345
- const capturePrimary = React8.useCallback((scope, signal) => captureOne(primary, scope, signal, true), [captureOne, primary]);
1888
+ const capturePrimary = React9.useCallback((scope, signal) => captureOne(primary, scope, signal, true), [captureOne, primary]);
1346
1889
  workspaceCaptures.current.set(primaryWorkspaceKey, capturePrimary);
1347
1890
  if (nearestWorkspaceKey && nearestSurface) workspaceCaptures.current.set(nearestWorkspaceKey, (scope, signal) => captureOne(nearestSurface, scope, signal, true));
1348
1891
  for (const variant of variants) {
1349
1892
  const key = variantWorkspaceKeys.get(variant.id);
1350
1893
  workspaceCaptures.current.set(key, (scope, signal) => captureOne(variant.source, scope, signal, true));
1351
1894
  }
1352
- const preflight = React8.useCallback(async () => {
1895
+ const preflight = React9.useCallback(async () => {
1353
1896
  const { controller, id } = fence.begin();
1354
1897
  setMenuCapture(null);
1355
1898
  setMenuStatus("loading");
@@ -1368,7 +1911,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1368
1911
  fence.finish(controller);
1369
1912
  }
1370
1913
  }, [captureOne, fence, initialScope, primary]);
1371
- const transfer = React8.useCallback(async (format, download, alternate) => {
1914
+ const transfer = React9.useCallback(async (format, download, alternate) => {
1372
1915
  const { controller, id } = fence.begin();
1373
1916
  try {
1374
1917
  const explicit = alternate?.source ?? (typeof format === "string" && format !== "xlsx" ? formatSources?.[format] : void 0);
@@ -1393,7 +1936,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1393
1936
  fence.finish(controller);
1394
1937
  }
1395
1938
  }, [captureOne, capturePrimary, fence, formatSources, initialScope, preferences, providerPreferences, report, transport]);
1396
- const openWorkspace = React8.useCallback(
1939
+ const openWorkspace = React9.useCallback(
1397
1940
  async (key = primaryWorkspaceKey, variant) => {
1398
1941
  const variantMaterial = variant && "kind" in variant.source ? {
1399
1942
  id: `variant:${key}`,
@@ -1487,7 +2030,8 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1487
2030
  setWorkspaceOpen(true);
1488
2031
  } catch (error) {
1489
2032
  if (fence.valid(id, controller))
1490
- setNotice(errorMessage(error, "Could not capture content"));
2033
+ setReceiptTarget(void 0);
2034
+ setNotice(errorMessage(error, "Could not capture content"));
1491
2035
  } finally {
1492
2036
  fence.finish(controller);
1493
2037
  }
@@ -1504,7 +2048,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1504
2048
  workspaces
1505
2049
  ]
1506
2050
  );
1507
- React8.useImperativeHandle(controllerRef, () => ({
2051
+ React9.useImperativeHandle(controllerRef, () => ({
1508
2052
  focusTrigger: () => triggerRef.current?.focus(),
1509
2053
  prepare: async (requestedSource, options) => {
1510
2054
  const requestedLabel = options?.label ?? ("label" in requestedSource ? requestedSource.label : "content");
@@ -1513,14 +2057,15 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1513
2057
  await openWorkspace(requestedKey, { source: requestedSource, label: requestedLabel });
1514
2058
  }
1515
2059
  }), [openWorkspace]);
1516
- const runAction = React8.useCallback(async (action) => {
2060
+ const runAction = React9.useCallback(async (action) => {
1517
2061
  const { controller, id } = fence.begin();
1518
2062
  try {
1519
2063
  const actionSource = action.source;
1520
2064
  const { snapshot } = actionSource ? await captureOne(actionSource, initialScope, controller.signal, true) : await capturePrimary(initialScope, controller.signal);
1521
2065
  const resolved = (0, import_content_transfer2.resolveTransferPreferences)(providerPreferences, preferences, snapshot.limits);
1522
2066
  const draft = (0, import_content_transfer2.applyTransferLimits)((0, import_content_transfer2.createDraft)(snapshot), resolved.limits);
1523
- if (!action.supports(snapshot)) throw new Error(`${action.label} is unavailable for this content.`);
2067
+ 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.");
2068
+ if (!action.supports(snapshot, draft)) throw new Error(`${action.label} is unavailable for this content.`);
1524
2069
  const result = await action.run({ snapshot, draft, signal: controller.signal });
1525
2070
  if (fence.valid(id, controller) && draft.snapshotId === snapshot.id) report(result);
1526
2071
  } catch (error) {
@@ -1535,99 +2080,128 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1535
2080
  const visibleCopies = sourceFormats ? COPIES.filter((f) => Boolean(formatSources?.[f]) || !["csv", "tsv"].includes(f) || payload?.kind === "rows") : [];
1536
2081
  const visibleDownloads = sourceFormats ? DOWNLOADS.filter((f) => f !== "xlsx" && Boolean(formatSources?.[f]) || !["csv", "tsv", "xlsx"].includes(f) || payload?.kind === "rows") : [];
1537
2082
  const visibleAdapters = sourceFormats && menuCapture ? adapters.filter((a) => a.supports(menuCapture.snapshot.payload)) : [];
1538
- const visibleActions = menuCapture ? registeredActions.filter((a) => a.supports(menuCapture.snapshot)) : [];
2083
+ const visibleActions = menuCapture ? registeredActions.filter((a) => a.supports(menuCapture.snapshot, (0, import_content_transfer2.applyTransferLimits)((0, import_content_transfer2.createDraft)(menuCapture.snapshot), (0, import_content_transfer2.resolveTransferPreferences)(providerPreferences, preferences, menuCapture.snapshot.limits).limits))) : [];
1539
2084
  const downloadActions = visibleActions.filter((action) => action.placement === "download");
1540
2085
  const ordinaryActions = visibleActions.filter((action) => action.placement !== "download");
2086
+ const preparedActions = registeredActions.filter((action) => action.prepared && !action.source);
1541
2087
  const copyAvailable = !hide.includes("copy") && visibleCopies.length + visibleAdapters.length + quickVariants("copy").length > 0;
1542
2088
  const downloadAvailable = !hide.includes("download") && visibleDownloads.length + visibleAdapters.length + downloadActions.length > 0;
1543
2089
  const prepareAvailable = !hide.includes("prepare") && (quickVariants("ai").length > 0 || Boolean(primary) || Boolean(nearestWorkspaceKey) || variants.length > 0);
1544
2090
  const resolvedMode = mode === "copy" && !copyAvailable ? "download" : mode === "download" && !downloadAvailable ? "copy" : mode;
2091
+ const nativeAiFormat = {
2092
+ id: "ai-context",
2093
+ label: "AI context",
2094
+ supports: () => true,
2095
+ build: async (draft) => {
2096
+ const json = (0, import_content_transfer2.serialize)(draft, "json");
2097
+ return (0, import_content_transfer2.sealTransferArtifact)({ snapshotId: draft.snapshotId, draftRevision: draft.revision, format: "ai-context", plainText: (0, import_content_transfer2.buildAgentPayload)({ kind: "matrx_content", location: sourceLabel, description: "Captured content for an assistant", data: JSON.parse(json.plainText), attributes: { source: draft.sourceId } }), omissions: [...json.omissions] });
2098
+ }
2099
+ };
1545
2100
  const closePalette = () => setPaletteOpen(false);
1546
2101
  const tile = (id, label2, onClick, options = {}) => {
1547
2102
  const presentation = options.action;
1548
2103
  const Icon = presentation?.icon;
1549
2104
  const fallbackLabel = options.file && !/^download\b/i.test(label2) ? `Download ${label2}` : label2;
1550
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-tile", "aria-label": presentation?.ariaLabel ?? (presentation ? fallbackLabel : options.ariaLabel ?? `${resolvedMode === "copy" ? "Copy" : "Download"} ${label2}`), onClick: () => {
2105
+ 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: () => {
1551
2106
  closePalette();
1552
2107
  onClick();
1553
2108
  }, children: [
1554
- Icon ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PaletteGlyph, { ...!options.custom ? { format: id } : {}, ...options.ai ? { ai: true } : {}, ...options.file ? { file: true } : {} }),
1555
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2109
+ Icon ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { ...!options.custom ? { format: id } : {}, ...options.ai ? { ai: true } : {}, ...options.file ? { file: true } : {} }),
2110
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
1556
2111
  label2,
1557
- presentation?.hint ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("small", { className: "matrx-alchemy-menu-hint", children: presentation.hint }) : null
2112
+ presentation?.hint ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: presentation.hint }) : null
1558
2113
  ] })
1559
2114
  ] }, id);
1560
2115
  };
1561
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: cn("matrx-alchemy", className), onClick: stopPropagation ? (event) => event.stopPropagation() : void 0, children: [
1562
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Popover, { open: paletteOpen, onOpenChange: (open) => {
2116
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: cn("matrx-alchemy", className), onClick: stopPropagation ? (event) => event.stopPropagation() : void 0, children: [
2117
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Popover, { open: paletteOpen, onOpenChange: (open) => {
1563
2118
  setPaletteOpen(open);
1564
2119
  if (open) {
1565
2120
  setMode("copy");
1566
2121
  void preflight();
1567
2122
  }
1568
2123
  }, children: [
1569
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.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_runtime8.jsx)(AlchemyGlyph, {}) }) }),
1570
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(PopoverContent, { align: "end", className: "matrx-alchemy-menu matrx-alchemy-palette", "aria-label": "Alchemy output options", onCloseAutoFocus: () => triggerRef.current?.focus(), children: [
1571
- menuStatus === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "matrx-alchemy-palette-status", children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "matrx-alchemy-error", children: menuStatus }) : null,
1572
- copyAvailable || downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("section", { className: "matrx-alchemy-output", children: [
1573
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
1574
- copyAvailable && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
1575
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
1576
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
2124
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PopoverTrigger, { asChild: true, children: triggerVariant === "glass" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TapTargetButton, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "glass" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TapTargetButtonTransparent, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "transparent" }) }),
2125
+ /* @__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: [
2126
+ 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,
2127
+ copyAvailable || downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "matrx-alchemy-output", children: [
2128
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
2129
+ copyAvailable && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
2130
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
2131
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
1577
2132
  ] }) : null,
1578
- resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1579
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
2133
+ resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2134
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
1580
2135
  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]}` })),
1581
2136
  visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, false), { custom: true }))
1582
2137
  ] }),
1583
- quickVariants("copy").length ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
2138
+ quickVariants("copy").length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
1584
2139
  closePalette();
1585
2140
  void transfer("markdown", false, variant);
1586
2141
  } }) : null
1587
2142
  ] }) : null,
1588
- resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
2143
+ 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: [
1589
2144
  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]}` })),
1590
2145
  visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, true), { custom: true })),
1591
2146
  downloadActions.map((action) => tile(action.id, action.label, () => void runAction(action), { custom: true, action, file: true }))
1592
2147
  ] }) }) : null
1593
2148
  ] }) : null,
1594
- prepareAvailable ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1595
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", items: quickVariants("ai"), onRun: (variant) => {
2149
+ prepareAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2150
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", extra: sourceFormats ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
2151
+ closePalette();
2152
+ void transfer(nativeAiFormat, false);
2153
+ }, children: [
2154
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { kind: "ai-copy" }),
2155
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
2156
+ "Copy with AI context",
2157
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Content, source and capture details" })
2158
+ ] })
2159
+ ] }) : null, items: quickVariants("ai"), onRun: (variant) => {
1596
2160
  closePalette();
1597
2161
  void transfer("markdown", false, variant);
1598
2162
  } }),
1599
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PaletteRows, { title: "Edit and prepare", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": "Prepare for AI", onClick: () => {
2163
+ /* @__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: () => {
1600
2164
  closePalette();
1601
2165
  void openWorkspace();
1602
2166
  }, children: [
1603
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PaletteGlyph, { kind: "sliders" }),
1604
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2167
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { kind: "sliders" }),
2168
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
1605
2169
  "Prepare for AI",
1606
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Review and edit before copying" })
2170
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Review and edit before copying" })
1607
2171
  ] })
1608
2172
  ] }) })
1609
2173
  ] }) : null,
1610
- prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PaletteRows, { title: "Other sources", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1611
- nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
2174
+ 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: [
2175
+ nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
1612
2176
  closePalette();
1613
2177
  void openWorkspace(nearestWorkspaceKey, { source: nearestSurface, label: nearestSurface.surfaceName });
1614
- }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Prepare this surface" }) }) : null,
1615
- variants.map((variant) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
2178
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Prepare this surface" }) }) : null,
2179
+ variants.map((variant) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
1616
2180
  closePalette();
1617
2181
  void openWorkspace(variantWorkspaceKeys.get(variant.id), variant);
1618
- }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
2182
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
1619
2183
  ] }) }) : null,
1620
- ordinaryActions.length ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PaletteRows, { title: "Actions", items: [], extra: ordinaryActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
1621
- closePalette();
1622
- void runAction(action);
1623
- }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MenuPresentation, { ...action, label: action.label }) }, action.id)) }) : null
2184
+ ["save", "chat", "other"].map((group) => {
2185
+ const entries = ordinaryActions.filter((action) => (action.group ?? "other") === group);
2186
+ return entries.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-palette-destinations", children: [
2187
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
2188
+ group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : "Actions",
2189
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: entries.length })
2190
+ ] }),
2191
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { children: entries.map((action) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
2192
+ closePalette();
2193
+ void runAction(action);
2194
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DestinationPresentation, { action }) }, action.id)) })
2195
+ ] }, group) : null;
2196
+ })
1624
2197
  ] })
1625
2198
  ] }),
1626
- notice && triggerRef.current ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "matrx-alchemy-feedback", children: [
1627
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { role: "status", children: notice }),
1628
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", "aria-label": "Dismiss Alchemy feedback", onClick: () => setNotice(null), children: "\xD7" })
2199
+ notice && triggerRef.current ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-feedback", children: [
2200
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { role: "status", children: notice }),
2201
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ReceiptLink, { target: receiptTarget }),
2202
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": "Dismiss Alchemy feedback", onClick: () => setNotice(null), children: "\xD7" })
1629
2203
  ] }), triggerRef.current.ownerDocument.body) : null,
1630
- Object.values(workspaces).map((saved) => /* @__PURE__ */ (0, import_jsx_runtime8.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))
2204
+ 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, actions: preparedActions, captureScope: workspaceCaptures.current.get(saved.key) ?? capturePrimary, ...ai ? { ai } : {}, onOutcome: report }, saved.key))
1631
2205
  ] });
1632
2206
  }
1633
2207
  function initialControls(state) {
@@ -1679,30 +2253,34 @@ function preview(draft, format) {
1679
2253
  const resolved = isBuiltInFormat(format) ? format : "plain";
1680
2254
  return (0, import_content_transfer2.serialize)(draft, resolved === "xlsx" ? "tsv" : resolved, { spreadsheetSafe: resolved === "csv" || resolved === "tsv" || resolved === "xlsx" }).plainText;
1681
2255
  }
1682
- function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onChange, transport, ai, adapters, onOutcome, captureScope }) {
2256
+ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onChange, transport, ai, adapters, actions, onOutcome, captureScope }) {
1683
2257
  const fence = useFence();
1684
- const latest = React8.useRef(state);
2258
+ const latest = React9.useRef(state);
1685
2259
  latest.current = state;
1686
- const aiSession = React8.useRef(void 0);
2260
+ const aiSession = React9.useRef(void 0);
1687
2261
  if (!aiSession.current && ai) aiSession.current = ai.fork?.() ?? ai;
1688
- const [controls, setControls] = React8.useState(() => initialControls(state));
1689
- const [controlsHistory, setControlsHistory] = React8.useState([]);
1690
- const [pendingControls, setPendingControls] = React8.useState(null);
2262
+ const [controls, setControls] = React9.useState(() => initialControls(state));
2263
+ const [controlsHistory, setControlsHistory] = React9.useState([]);
2264
+ const [pendingControls, setPendingControls] = React9.useState(null);
1691
2265
  const requestedFormat = state.preferences.initialFormat;
1692
- 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");
1693
- const [buffer, setBuffer] = React8.useState(() => isBuiltInFormat(format) ? preview(state.draft, format) : "Preparing format preview\u2026");
1694
- const [bufferError, setBufferError] = React8.useState(null);
1695
- const [formatError, setFormatError] = React8.useState(null);
1696
- const [preparedArtifact, setPreparedArtifact] = React8.useState(null);
1697
- const [instruction, setInstruction] = React8.useState("");
1698
- const [busy, setBusy] = React8.useState(null);
1699
- const [aiFailed, setAiFailed] = React8.useState(false);
1700
- React8.useEffect(() => {
2266
+ const [format, setFormat] = React9.useState(() => isBuiltInFormat(requestedFormat) ? supportsBuiltIn(requestedFormat, state.draft.payload) ? requestedFormat : "plain" : adapters.some((adapter) => adapter.id === requestedFormat && adapter.supports(state.draft.payload)) ? requestedFormat : "plain");
2267
+ const [buffer, setBuffer] = React9.useState(() => isBuiltInFormat(format) ? preview(state.draft, format) : "Preparing format preview\u2026");
2268
+ const [bufferError, setBufferError] = React9.useState(null);
2269
+ const [formatError, setFormatError] = React9.useState(null);
2270
+ const [preparedArtifact, setPreparedArtifact] = React9.useState(null);
2271
+ const [instruction, setInstruction] = React9.useState("");
2272
+ const [busy, setBusy] = React9.useState(null);
2273
+ const [aiFailed, setAiFailed] = React9.useState(false);
2274
+ React9.useEffect(() => {
1701
2275
  setAiFailed(false);
1702
2276
  }, [state.snapshot.id, state.draft.revision]);
1703
- const activeAi = React8.useRef(null);
1704
- const activeCapture = React8.useRef(null);
1705
- React8.useEffect(() => {
2277
+ const handingOff = React9.useRef(false);
2278
+ React9.useEffect(() => {
2279
+ if (open) handingOff.current = false;
2280
+ }, [open]);
2281
+ const activeAi = React9.useRef(null);
2282
+ const activeCapture = React9.useRef(null);
2283
+ React9.useEffect(() => {
1706
2284
  if (bufferError) return;
1707
2285
  const adapter = adapters.find((candidate) => candidate.id === format);
1708
2286
  const controller = new AbortController();
@@ -1722,7 +2300,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1722
2300
  });
1723
2301
  return () => controller.abort();
1724
2302
  }, [adapters, bufferError, format, state.draft, state.snapshot.id]);
1725
- const close = React8.useCallback(() => {
2303
+ const close = React9.useCallback(() => {
1726
2304
  activeAi.current?.abort();
1727
2305
  activeCapture.current?.abort();
1728
2306
  activeAi.current = null;
@@ -1851,8 +2429,8 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1851
2429
  if (fence.valid(id, controller)) setBusy(null);
1852
2430
  }
1853
2431
  };
1854
- const [deliveryNotice, setDeliveryNotice] = React8.useState(null);
1855
- React8.useEffect(() => {
2432
+ const [deliveryNotice, setDeliveryNotice] = React9.useState(null);
2433
+ React9.useEffect(() => {
1856
2434
  setDeliveryNotice(null);
1857
2435
  }, [state.draft.revision]);
1858
2436
  const reportDelivery = (outcome) => {
@@ -1879,45 +2457,64 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1879
2457
  if (fence.valid(id, controller)) setBusy(null);
1880
2458
  }
1881
2459
  };
2460
+ const deliverAction = async (action) => {
2461
+ if (busy || bufferError || formatError || !preparedArtifact) return;
2462
+ const { controller, id } = fence.begin();
2463
+ const current = latest.current;
2464
+ setBusy("action");
2465
+ try {
2466
+ if (!action.supports(current.snapshot, current.draft)) throw new Error(`${action.label} is unavailable for this prepared content.`);
2467
+ handingOff.current = true;
2468
+ (0, import_react_dom.flushSync)(() => onClose());
2469
+ const result = await action.run({ snapshot: current.snapshot, draft: current.draft, signal: controller.signal });
2470
+ if (fence.valid(id, controller)) reportDelivery(result);
2471
+ } catch (error) {
2472
+ if (fence.valid(id, controller)) reportDelivery({ status: "error", code: "destination-failed", message: errorMessage(error, "Could not deliver prepared content"), retryable: false });
2473
+ } finally {
2474
+ fence.finish(controller);
2475
+ if (fence.valid(id, controller)) setBusy(null);
2476
+ }
2477
+ };
2478
+ const eligibleActions = actions.filter((action) => action.supports(state.snapshot, state.draft));
1882
2479
  const rows = state.original.payload.kind === "rows" ? state.original.payload : null;
1883
2480
  const formats = COPIES.filter((f) => supportsBuiltIn(f, state.draft.payload));
1884
2481
  const workspaceAdapters = adapters.filter((adapter) => adapter.supports(state.draft.payload));
1885
2482
  const displayedOmissions = preparedArtifact?.omissions ?? state.draft.omissions;
1886
2483
  const limitText = Object.entries(state.preferences.limits).filter(([, value]) => value != null).map(([key, value]) => `${key.replace(/^max/, "max ")} ${Number(value).toLocaleString()}`).join(" \xB7 ");
1887
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Dialog, { open, onOpenChange: (next) => {
2484
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Dialog, { open, onOpenChange: (next) => {
1888
2485
  if (!next) close();
1889
- }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(DialogContent, { onCloseAutoFocus: (event) => {
2486
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogContent, { onCloseAutoFocus: (event) => {
1890
2487
  event.preventDefault();
1891
- restoreFocus();
2488
+ if (!handingOff.current) restoreFocus();
1892
2489
  }, className: "matrx-alchemy-workspace max-w-5xl", "aria-busy": busy !== null, children: [
1893
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(DialogHeader, { children: [
1894
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(DialogTitle, { children: [
2490
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogHeader, { children: [
2491
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogTitle, { children: [
1895
2492
  "Prepare ",
1896
2493
  state.snapshot.label
1897
2494
  ] }),
1898
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(DialogDescription, { children: [
2495
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogDescription, { children: [
1899
2496
  state.snapshot.unsavedChanges ? "Includes your unsaved changes. " : "",
1900
2497
  "Review and edit this copy. Your original stays unchanged."
1901
2498
  ] })
1902
2499
  ] }),
1903
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
1904
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "matrx-alchemy-workspace-grid", children: [
1905
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("section", { className: "matrx-alchemy-main", children: [
1906
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
1907
- scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { children: [
2500
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
2501
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-workspace-grid", children: [
2502
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "matrx-alchemy-main", children: [
2503
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
2504
+ scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
1908
2505
  "Scope",
1909
- /* @__PURE__ */ (0, import_jsx_runtime8.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_runtime8.jsx)("option", { value: scope, children: SCOPE_LABEL[scope] }, scope)) })
2506
+ /* @__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)) })
1910
2507
  ] }) : null,
1911
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { children: [
2508
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
1912
2509
  "Detail",
1913
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("select", { "aria-label": "Detail preset", value: controls.preset, onChange: (e) => changeControls({ ...controls, preset: e.target.value }), children: [
1914
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "full", children: "Full" }),
1915
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "compact", children: "Compact" }),
1916
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "brief", children: "Brief" }),
1917
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "custom", children: "Custom" })
2510
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { "aria-label": "Detail preset", value: controls.preset, onChange: (e) => changeControls({ ...controls, preset: e.target.value }), children: [
2511
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "full", children: "Full" }),
2512
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "compact", children: "Compact" }),
2513
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "brief", children: "Brief" }),
2514
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "custom", children: "Custom" })
1918
2515
  ] })
1919
2516
  ] }),
1920
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: !state.draft.history?.length && !controlsHistory.length || busy !== null, onClick: () => {
2517
+ /* @__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: () => {
1921
2518
  setBufferError(null);
1922
2519
  if (controlsHistory.length) {
1923
2520
  const next = controlsHistory[controlsHistory.length - 1];
@@ -1926,7 +2523,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1926
2523
  onChange({ ...state, draft: rebuild(state, next), error: void 0 });
1927
2524
  } else onChange({ ...state, draft: (0, import_content_transfer2.undoDraft)(state.draft), error: void 0 });
1928
2525
  }, children: "Undo" }),
1929
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => {
2526
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => {
1930
2527
  const next = initialControls(state);
1931
2528
  setControls(next);
1932
2529
  setControlsHistory([]);
@@ -1934,64 +2531,64 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1934
2531
  setBufferError(null);
1935
2532
  onChange({ ...state, draft: rebuild(state, next), error: void 0 });
1936
2533
  }, children: "Reset" }),
1937
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => void requestCapture(state.scope), children: "Refresh source" })
2534
+ /* @__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" })
1938
2535
  ] }),
1939
- controls.preset === "custom" && (state.draft.payload.kind === "json" || state.draft.payload.kind === "registered") ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("fieldset", { className: "matrx-alchemy-options", children: [
1940
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("legend", { children: "JSON limits" }),
1941
- [["maxDepth", "Maximum depth"], ["maxStringChars", "Maximum string characters"], ["maxArrayItems", "Maximum array items"]].map(([key, text]) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { children: [
2536
+ controls.preset === "custom" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("fieldset", { className: "matrx-alchemy-options", children: [
2537
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("legend", { children: state.draft.payload.kind === "json" || state.draft.payload.kind === "registered" ? "JSON limits" : "Content limits" }),
2538
+ [["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_runtime10.jsxs)("label", { children: [
1942
2539
  text,
1943
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "number", min: "0", value: controls[key] ?? "", onChange: (e) => changeControls({ ...controls, [key]: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
2540
+ /* @__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 }) })
1944
2541
  ] }, key))
1945
2542
  ] }) : null,
1946
- rows ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-data-controls", children: [
1947
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("summary", { children: [
2543
+ rows ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-data-controls", children: [
2544
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
1948
2545
  "Data selection \xB7 ",
1949
2546
  controls.visibleColumns.length,
1950
2547
  " columns",
1951
2548
  controls.search || controls.sort || controls.top != null || controls.selectedOnly || Object.values(controls.filters).some(Boolean) ? " \xB7 customized" : " \xB7 all rows"
1952
2549
  ] }),
1953
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "matrx-alchemy-data-controls-body", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(RowControls, { rows, controls, change: changeControls }) })
2550
+ /* @__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 }) })
1954
2551
  ] }) : null,
1955
- state.snapshot.sections.length ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("details", { className: "matrx-alchemy-options", children: [
1956
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("summary", { children: [
2552
+ state.snapshot.sections.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options", children: [
2553
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
1957
2554
  "Sections \xB7 ",
1958
2555
  controls.sections.length,
1959
2556
  " included"
1960
2557
  ] }),
1961
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("fieldset", { "aria-label": "Included sections", children: state.snapshot.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { children: [
1962
- /* @__PURE__ */ (0, import_jsx_runtime8.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) }) }),
2558
+ /* @__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: [
2559
+ /* @__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) }) }),
1963
2560
  " ",
1964
2561
  section.label
1965
2562
  ] }, section.id)) })
1966
2563
  ] }) : null,
1967
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "matrx-alchemy-preview-label", children: [
2564
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "matrx-alchemy-preview-label", children: [
1968
2565
  "Output format",
1969
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("select", { "aria-label": "Output format", value: format, onChange: (e) => setFormat(e.target.value), children: [
1970
- formats.map((f) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: f, children: LABEL[f] }, f)),
1971
- state.draft.payload.kind === "rows" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "xlsx", children: "Excel workbook" }) : null,
1972
- workspaceAdapters.map((adapter) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: adapter.id, children: adapter.label }, adapter.id))
2566
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { "aria-label": "Output format", value: format, onChange: (e) => setFormat(e.target.value), children: [
2567
+ formats.map((f) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: f, children: LABEL[f] }, f)),
2568
+ state.draft.payload.kind === "rows" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "xlsx", children: "Excel workbook" }) : null,
2569
+ workspaceAdapters.map((adapter) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: adapter.id, children: adapter.label }, adapter.id))
1973
2570
  ] })
1974
2571
  ] }),
1975
- /* @__PURE__ */ (0, import_jsx_runtime8.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) }),
1976
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "matrx-alchemy-coverage", children: [
1977
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2572
+ /* @__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) }),
2573
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-coverage", children: [
2574
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
1978
2575
  state.snapshot.coverage.included.toLocaleString(),
1979
2576
  " included",
1980
2577
  state.snapshot.coverage.total == null ? "" : ` of ${state.snapshot.coverage.total.toLocaleString()}`,
1981
2578
  " \xB7 ",
1982
2579
  state.snapshot.coverage.status
1983
2580
  ] }),
1984
- state.snapshot.coverage.reason ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: state.snapshot.coverage.reason }) : null,
1985
- limitText ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2581
+ state.snapshot.coverage.reason ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: state.snapshot.coverage.reason }) : null,
2582
+ limitText ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
1986
2583
  "Limits: ",
1987
2584
  limitText
1988
2585
  ] }) : null,
1989
- displayedOmissions.length ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("details", { children: [
1990
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("summary", { children: [
2586
+ displayedOmissions.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { children: [
2587
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
1991
2588
  displayedOmissions.length,
1992
2589
  " omissions or adjustments"
1993
2590
  ] }),
1994
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("ul", { children: displayedOmissions.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("li", { children: [
2591
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { children: displayedOmissions.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("li", { children: [
1995
2592
  o.path || "/",
1996
2593
  ": ",
1997
2594
  o.reason,
@@ -1999,57 +2596,79 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1999
2596
  ] }, `${o.path}-${o.reason}-${i}`)) })
2000
2597
  ] }) : null
2001
2598
  ] }),
2002
- bufferError ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { id: "alchemy-buffer-error", role: "alert", className: "matrx-alchemy-error", children: bufferError }) : null,
2003
- formatError ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: formatError }) : null,
2004
- bufferError ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: busy !== null, onClick: () => {
2599
+ bufferError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { id: "alchemy-buffer-error", role: "alert", className: "matrx-alchemy-error", children: bufferError }) : null,
2600
+ formatError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: formatError }) : null,
2601
+ bufferError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: busy !== null, onClick: () => {
2005
2602
  const fallback = (0, import_content_transfer2.editDraft)(state.draft, { kind: "text", text: buffer });
2006
2603
  setBufferError(null);
2007
2604
  onChange({ ...state, draft: fallback, error: void 0 });
2008
2605
  setFormat("plain");
2009
2606
  }, children: "Use invalid JSON as plain text" }) : null
2010
2607
  ] }),
2011
- ai || busy === "capture" || state.error ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("aside", { children: [
2012
- ai ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
2013
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { children: [
2608
+ ai || busy === "capture" || state.error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("aside", { children: [
2609
+ ai ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2610
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2611
+ "Start with",
2612
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { "aria-label": "AI preparation recipe", defaultValue: "", onChange: (event) => {
2613
+ if (event.target.value) setInstruction(event.target.value);
2614
+ }, children: [
2615
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "Choose an instruction" }),
2616
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Summarize this content concisely. Preserve important facts, names, decisions, and source references.", children: "Summarize" }),
2617
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Extract decisions, action items, owners, and due dates. Mark missing details as unspecified.", children: "Extract action items" }),
2618
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Prepare a complete handoff for another assistant. Include the objective, relevant facts, constraints, decisions, and unresolved questions.", children: "Assistant handoff" }),
2619
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Condense this content by removing repetition and formatting noise. Preserve every unique fact and all identifiers.", children: "Condense without losing facts" }),
2620
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Turn this content into a clear structured outline. Keep the original meaning and explicitly flag uncertainty.", children: "Create an outline" }),
2621
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Analyze this data. Identify patterns, anomalies, and useful comparisons. Distinguish observations from inferences.", children: "Analyze the data" })
2622
+ ] })
2623
+ ] }),
2624
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2014
2625
  "AI instruction",
2015
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value), placeholder: "Tell AI how to prepare this content" })
2626
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value), placeholder: "Tell AI how to prepare this content" })
2016
2627
  ] }),
2017
- /* @__PURE__ */ (0, import_jsx_runtime8.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" }),
2018
- busy === "ai" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void cancelAi(), children: aiSession.current?.cancel ? "Cancel AI" : "Stop waiting" }) : null
2628
+ /* @__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" }),
2629
+ 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
2019
2630
  ] }) : null,
2020
- busy === "capture" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => {
2631
+ busy === "capture" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => {
2021
2632
  activeCapture.current?.abort();
2022
2633
  activeCapture.current = null;
2023
2634
  setBusy(null);
2024
2635
  }, children: "Stop loading rows" }) : null,
2025
- ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ (0, import_jsx_runtime8.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,
2026
- ai ? /* @__PURE__ */ (0, import_jsx_runtime8.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,
2027
- state.error ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
2636
+ 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,
2637
+ 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,
2638
+ state.error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
2028
2639
  ] }) : null
2029
2640
  ] }),
2030
- pendingControls ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
2031
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "This control would replace your manual edit." }),
2032
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
2033
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
2641
+ pendingControls ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
2642
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "This control would replace your manual edit." }),
2643
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
2644
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
2034
2645
  ] }) : null,
2035
- state.sourceStale ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
2036
- state.pending ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
2037
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "A fresh source snapshot is ready." }),
2038
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
2039
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: () => resolveCapture("regenerate"), children: "Regenerate from fresh source" })
2646
+ 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,
2647
+ state.pending ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
2648
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "A fresh source snapshot is ready." }),
2649
+ /* @__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" }),
2650
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: () => resolveCapture("regenerate"), children: "Regenerate from fresh source" })
2651
+ ] }) : null,
2652
+ eligibleActions.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-destinations", children: [
2653
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
2654
+ "Use prepared content \xB7 ",
2655
+ eligibleActions.length,
2656
+ " destinations"
2657
+ ] }),
2658
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "matrx-alchemy-destination-grid", children: eligibleActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime10.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_runtime10.jsx)(DestinationPresentation, { action }) }, action.id)) })
2040
2659
  ] }) : null,
2041
- deliveryNotice ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { role: "status", className: "matrx-alchemy-meta", children: deliveryNotice }) : null
2660
+ deliveryNotice ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "status", className: "matrx-alchemy-meta", children: deliveryNotice }) : null
2042
2661
  ] }),
2043
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(DialogFooter, { children: [
2044
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "matrx-alchemy-meta", children: [
2662
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogFooter, { children: [
2663
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "matrx-alchemy-meta", children: [
2045
2664
  buffer.length.toLocaleString(),
2046
2665
  " characters \xB7 ~",
2047
2666
  estimateTokens(buffer).toLocaleString(),
2048
2667
  " tokens"
2049
2668
  ] }),
2050
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", onClick: close, children: "Close" }),
2051
- /* @__PURE__ */ (0, import_jsx_runtime8.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" }),
2052
- /* @__PURE__ */ (0, import_jsx_runtime8.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" })
2669
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", onClick: close, children: "Close" }),
2670
+ /* @__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" }),
2671
+ /* @__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" })
2053
2672
  ] })
2054
2673
  ] }) });
2055
2674
  }
@@ -2057,59 +2676,59 @@ function RowControls({ rows, controls, change }) {
2057
2676
  const filterCount = Object.values(controls.filters).filter(Boolean).length;
2058
2677
  const selectionSummary = controls.selectedOnly ? `${controls.selectedIndices.length} selected row${controls.selectedIndices.length === 1 ? "" : "s"}` : "All rows";
2059
2678
  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 ");
2060
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
2061
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
2062
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { children: [
2679
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2680
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
2681
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2063
2682
  "Search",
2064
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { value: controls.search, onChange: (e) => change({ ...controls, search: e.target.value }) })
2683
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { value: controls.search, onChange: (e) => change({ ...controls, search: e.target.value }) })
2065
2684
  ] }),
2066
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { children: [
2685
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2067
2686
  "Sort",
2068
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("select", { value: controls.sort, onChange: (e) => change({ ...controls, sort: e.target.value }), children: [
2069
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "", children: "None" }),
2070
- rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: column.id, children: column.label }, column.id))
2687
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { value: controls.sort, onChange: (e) => change({ ...controls, sort: e.target.value }), children: [
2688
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "None" }),
2689
+ rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: column.id, children: column.label }, column.id))
2071
2690
  ] })
2072
2691
  ] }),
2073
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { children: [
2692
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2074
2693
  "Direction",
2075
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("select", { value: controls.direction, disabled: !controls.sort, onChange: (e) => change({ ...controls, direction: e.target.value }), children: [
2076
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "asc", children: "Ascending" }),
2077
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "desc", children: "Descending" })
2694
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { value: controls.direction, disabled: !controls.sort, onChange: (e) => change({ ...controls, direction: e.target.value }), children: [
2695
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "asc", children: "Ascending" }),
2696
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "desc", children: "Descending" })
2078
2697
  ] })
2079
2698
  ] }),
2080
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { children: [
2699
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2081
2700
  "Top rows",
2082
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "number", min: "0", value: controls.top ?? "", onChange: (e) => change({ ...controls, top: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
2701
+ /* @__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 }) })
2083
2702
  ] })
2084
2703
  ] }),
2085
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("details", { className: "matrx-alchemy-options", children: [
2086
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("summary", { children: [
2704
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options", children: [
2705
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
2087
2706
  "Columns and filters",
2088
2707
  dataSummary ? ` \u2014 ${dataSummary}` : ""
2089
2708
  ] }),
2090
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("fieldset", { "aria-label": "Columns and filters", children: rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "matrx-alchemy-column", children: [
2091
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { children: [
2092
- /* @__PURE__ */ (0, import_jsx_runtime8.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) }) }),
2709
+ /* @__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: [
2710
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2711
+ /* @__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) }) }),
2093
2712
  " ",
2094
2713
  column.label
2095
2714
  ] }),
2096
- /* @__PURE__ */ (0, import_jsx_runtime8.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 } }) })
2715
+ /* @__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 } }) })
2097
2716
  ] }, column.id)) })
2098
2717
  ] }),
2099
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("details", { className: "matrx-alchemy-options", children: [
2100
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("summary", { children: [
2718
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options", children: [
2719
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
2101
2720
  "Rows \u2014 ",
2102
2721
  selectionSummary
2103
2722
  ] }),
2104
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("fieldset", { "aria-label": "Row selection", children: [
2105
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { children: [
2106
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "checkbox", checked: controls.selectedOnly, onChange: (e) => change({ ...controls, selectedOnly: e.target.checked }) }),
2723
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("fieldset", { "aria-label": "Row selection", children: [
2724
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2725
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: controls.selectedOnly, onChange: (e) => change({ ...controls, selectedOnly: e.target.checked }) }),
2107
2726
  " Only selected rows"
2108
2727
  ] }),
2109
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "matrx-alchemy-row-list", children: rows.rows.map((row, index) => {
2728
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "matrx-alchemy-row-list", children: rows.rows.map((row, index) => {
2110
2729
  const summary = rows.columns.filter((column) => column.visible).slice(0, 2).map((column) => String((0, import_content_transfer2.readTransferCell)(row, column) ?? "")).filter(Boolean).join(" \xB7 ");
2111
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { children: [
2112
- /* @__PURE__ */ (0, import_jsx_runtime8.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) }) }),
2730
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2731
+ /* @__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) }) }),
2113
2732
  " Row ",
2114
2733
  index + 1,
2115
2734
  summary ? ` \u2014 ${summary}` : ""