@ai-matrx/design-system 0.18.22 → 0.19.0

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