@ai-matrx/design-system 0.19.17 → 0.20.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 (64) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/content-transfer/alchemy.svg +1 -1
  3. package/dist/content-transfer/icon.cjs +1 -1
  4. package/dist/content-transfer/icon.cjs.map +1 -1
  5. package/dist/content-transfer/icon.js +1 -1
  6. package/dist/content-transfer/icon.js.map +1 -1
  7. package/dist/content-transfer/portal.svg +1 -1
  8. package/dist/content-transfer.cjs +692 -407
  9. package/dist/content-transfer.cjs.map +1 -1
  10. package/dist/content-transfer.css +15 -0
  11. package/dist/content-transfer.d.cts +19 -4
  12. package/dist/content-transfer.d.ts +19 -4
  13. package/dist/content-transfer.js +684 -396
  14. package/dist/content-transfer.js.map +1 -1
  15. package/dist/data-table/copy-helpers.d.cts +3 -1
  16. package/dist/data-table/copy-helpers.d.ts +3 -1
  17. package/dist/data-table/copy-types.cjs.map +1 -1
  18. package/dist/data-table/copy-types.d.cts +4 -0
  19. package/dist/data-table/copy-types.d.ts +4 -0
  20. package/dist/data-table/data-row-inspector.cjs +659 -465
  21. package/dist/data-table/data-row-inspector.cjs.map +1 -1
  22. package/dist/data-table/data-row-inspector.js +662 -463
  23. package/dist/data-table/data-row-inspector.js.map +1 -1
  24. package/dist/data-table/data-row-window.cjs +657 -463
  25. package/dist/data-table/data-row-window.cjs.map +1 -1
  26. package/dist/data-table/data-row-window.js +663 -464
  27. package/dist/data-table/data-row-window.js.map +1 -1
  28. package/dist/data-table/filter-engine.d.cts +3 -1
  29. package/dist/data-table/filter-engine.d.ts +3 -1
  30. package/dist/data-table/host.cjs.map +1 -1
  31. package/dist/data-table/host.d.cts +6 -1
  32. package/dist/data-table/host.d.ts +6 -1
  33. package/dist/data-table/host.js.map +1 -1
  34. package/dist/data-table/index.cjs +1211 -980
  35. package/dist/data-table/index.cjs.map +1 -1
  36. package/dist/data-table/index.d.cts +4 -2
  37. package/dist/data-table/index.d.ts +4 -2
  38. package/dist/data-table/index.js +1350 -1114
  39. package/dist/data-table/index.js.map +1 -1
  40. package/dist/data-table/infer-filter.d.cts +3 -1
  41. package/dist/data-table/infer-filter.d.ts +3 -1
  42. package/dist/data-table/layered-filters.d.cts +3 -1
  43. package/dist/data-table/layered-filters.d.ts +3 -1
  44. package/dist/data-table/pagination.cjs +2 -2
  45. package/dist/data-table/pagination.cjs.map +1 -1
  46. package/dist/data-table/pagination.js +2 -2
  47. package/dist/data-table/pagination.js.map +1 -1
  48. package/dist/data-table/query-control.d.cts +3 -1
  49. package/dist/data-table/query-control.d.ts +3 -1
  50. package/dist/data-table/types.cjs.map +1 -1
  51. package/dist/data-table/types.d.cts +3 -1
  52. package/dist/data-table/types.d.ts +3 -1
  53. package/dist/data-table/url-state.d.cts +3 -1
  54. package/dist/data-table/url-state.d.ts +3 -1
  55. package/dist/data-table/uuid-cell.cjs.map +1 -1
  56. package/dist/data-table/uuid-cell.js.map +1 -1
  57. package/dist/data-table/xlsx.d.cts +3 -1
  58. package/dist/data-table/xlsx.d.ts +3 -1
  59. package/dist/extensions-DCHtNwG3.d.cts +32 -0
  60. package/dist/extensions-DCHtNwG3.d.ts +32 -0
  61. package/dist/tap-target.css +2 -2
  62. package/dist/{types-DqlfNcC5.d.cts → types-C2yaTspG.d.cts} +6 -1
  63. package/dist/{types-lNw7TnTM.d.ts → types-DB30aCHu.d.ts} +6 -1
  64. package/package.json +1 -1
@@ -42,16 +42,18 @@ __export(content_transfer_exports, {
42
42
  MatrxCopyMenu: () => MatrxCopyMenu,
43
43
  applyGroomerPreset: () => applyGroomerPreset,
44
44
  buildGroomerPresetPayload: () => buildGroomerPresetPayload,
45
+ createTransferEmailActions: () => createTransferEmailActions,
45
46
  defaultGroomerSelections: () => defaultGroomerSelections,
46
47
  groomerPresetVariants: () => groomerPresetVariants,
48
+ tableDataFormat: () => tableDataFormat,
49
+ tableSchemaFormat: () => tableSchemaFormat,
47
50
  useContentTransferCapabilities: () => useContentTransferCapabilities,
48
51
  useContentTransferSurface: () => useContentTransferSurface
49
52
  });
50
53
  module.exports = __toCommonJS(content_transfer_exports);
51
- var React9 = __toESM(require("react"), 1);
52
- var import_react_dom = require("react-dom");
53
- var import_content_transfer2 = require("@ai-matrx/kit/content-transfer");
54
- var import_format2 = require("@ai-matrx/kit/format");
54
+
55
+ // src/content-transfer/email-review.tsx
56
+ var React6 = __toESM(require("react"), 1);
55
57
 
56
58
  // src/button.tsx
57
59
  var import_react_slot = require("@radix-ui/react-slot");
@@ -447,13 +449,133 @@ var DialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @
447
449
  ));
448
450
  DialogDescription.displayName = DialogPrimitive.Description.displayName;
449
451
 
452
+ // src/content-transfer/email-review.tsx
453
+ var import_jsx_runtime6 = require("react/jsx-runtime");
454
+ var cancelled = () => ({ status: "cancelled" });
455
+ var failed = (error) => ({
456
+ status: "error",
457
+ code: "email-failed",
458
+ message: error instanceof Error ? error.message : "Could not send email.",
459
+ retryable: true
460
+ });
461
+ function useReviewedTransferEmail(email) {
462
+ const [pending, setPending] = React6.useState(null);
463
+ const [sending, setSending] = React6.useState(false);
464
+ const pendingRef = React6.useRef(null);
465
+ const sendingRef = React6.useRef(false);
466
+ const settle = React6.useCallback((request, outcome, render = true) => {
467
+ if (pendingRef.current !== request) return;
468
+ pendingRef.current = null;
469
+ request.context.signal.removeEventListener("abort", request.onAbort);
470
+ request.resolve(outcome);
471
+ sendingRef.current = false;
472
+ if (render) {
473
+ setSending(false);
474
+ setPending(null);
475
+ }
476
+ }, []);
477
+ React6.useEffect(
478
+ () => () => {
479
+ const request = pendingRef.current;
480
+ if (!request) return;
481
+ pendingRef.current = null;
482
+ request.context.signal.removeEventListener("abort", request.onAbort);
483
+ request.resolve(cancelled());
484
+ sendingRef.current = false;
485
+ },
486
+ []
487
+ );
488
+ const reviewed = React6.useMemo(() => {
489
+ if (!email) return void 0;
490
+ return {
491
+ send: (artifact, context) => {
492
+ if (context.signal.aborted) return Promise.resolve(cancelled());
493
+ if (pendingRef.current)
494
+ return Promise.resolve({
495
+ status: "error",
496
+ code: "email-review-active",
497
+ message: "Finish reviewing the current email before starting another.",
498
+ retryable: true
499
+ });
500
+ return new Promise((resolve2) => {
501
+ const request = {
502
+ artifact,
503
+ context,
504
+ resolve: resolve2,
505
+ onAbort: () => settle(request, cancelled())
506
+ };
507
+ pendingRef.current = request;
508
+ context.signal.addEventListener("abort", request.onAbort, { once: true });
509
+ setSending(false);
510
+ setPending(request);
511
+ });
512
+ }
513
+ };
514
+ }, [email, settle]);
515
+ const cancel = React6.useCallback(() => {
516
+ const request = pendingRef.current;
517
+ if (request && !sendingRef.current) settle(request, cancelled());
518
+ }, [settle]);
519
+ const confirm = React6.useCallback(() => {
520
+ const request = pendingRef.current;
521
+ if (!request || sendingRef.current || request.context.signal.aborted) return;
522
+ sendingRef.current = true;
523
+ setSending(true);
524
+ void email?.send(request.artifact, request.context).then(
525
+ (outcome) => settle(request, outcome),
526
+ (error) => settle(request, failed(error))
527
+ );
528
+ }, [email, settle]);
529
+ const review = pending ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog, { open: true, onOpenChange: (open) => {
530
+ if (!open) cancel();
531
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogContent, { className: "matrx-alchemy-workspace matrx-alchemy-email-review", "aria-busy": sending, children: [
532
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogHeader, { children: [
533
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogTitle, { children: "Review email attachment" }),
534
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogDescription, { children: [
535
+ "Email ",
536
+ pending.artifact.file?.filename ?? `${pending.artifact.format} output`,
537
+ " from ",
538
+ pending.context.label,
539
+ ". Review this exact attachment before sending."
540
+ ] })
541
+ ] }),
542
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("textarea", { "aria-label": "Email attachment preview", readOnly: true, value: pending.artifact.plainText, className: "matrx-alchemy-preview" }),
543
+ pending.artifact.omissions.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("details", { className: "matrx-alchemy-email-adjustments", open: true, children: [
544
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("summary", { children: [
545
+ pending.artifact.omissions.length,
546
+ " omission",
547
+ pending.artifact.omissions.length === 1 ? "" : "s",
548
+ " or adjustment",
549
+ pending.artifact.omissions.length === 1 ? "" : "s"
550
+ ] }),
551
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { children: pending.artifact.omissions.map((omission, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("li", { children: [
552
+ omission.path || "/",
553
+ ": ",
554
+ omission.reason,
555
+ omission.count == null ? "" : ` (${omission.count})`
556
+ ] }, `${omission.path}-${omission.reason}-${index}`)) })
557
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "matrx-alchemy-meta", children: "No omissions or adjustments." }),
558
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogFooter, { children: [
559
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: sending, onClick: cancel, children: "Cancel" }),
560
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Button, { type: "button", className: "matrx-alchemy-workspace-primary", disabled: sending, onClick: confirm, children: sending ? "Sending email\u2026" : "Send email" })
561
+ ] })
562
+ ] }) }) : null;
563
+ return { email: reviewed, review };
564
+ }
565
+
566
+ // src/content-transfer/index.tsx
567
+ var React10 = __toESM(require("react"), 1);
568
+ var import_react_dom = require("react-dom");
569
+ var import_content_transfer3 = require("@ai-matrx/kit/content-transfer");
570
+ var import_format2 = require("@ai-matrx/kit/format");
571
+
450
572
  // src/popover.tsx
451
573
  var PopoverPrimitive = __toESM(require("@radix-ui/react-popover"), 1);
452
- var React6 = __toESM(require("react"), 1);
453
- var import_jsx_runtime6 = require("react/jsx-runtime");
574
+ var React7 = __toESM(require("react"), 1);
575
+ var import_jsx_runtime7 = require("react/jsx-runtime");
454
576
  var Popover = PopoverPrimitive.Root;
455
577
  var PopoverTrigger = PopoverPrimitive.Trigger;
456
- var PopoverContent = React6.forwardRef(
578
+ var PopoverContent = React7.forwardRef(
457
579
  ({
458
580
  className,
459
581
  align = "center",
@@ -463,7 +585,7 @@ var PopoverContent = React6.forwardRef(
463
585
  ...props
464
586
  }, ref) => {
465
587
  const portalContainer = usePortalContainer(container);
466
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PopoverPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
588
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PopoverPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
467
589
  PopoverPrimitive.Content,
468
590
  {
469
591
  ref,
@@ -492,13 +614,13 @@ var import_react = require("react");
492
614
 
493
615
  // src/tooltip.tsx
494
616
  var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"), 1);
495
- var React7 = __toESM(require("react"), 1);
496
- var import_jsx_runtime7 = require("react/jsx-runtime");
617
+ var React8 = __toESM(require("react"), 1);
618
+ var import_jsx_runtime8 = require("react/jsx-runtime");
497
619
  var Tooltip = TooltipPrimitive.Root;
498
620
  var TooltipTrigger = TooltipPrimitive.Trigger;
499
- var TooltipContent = React7.forwardRef(({ className, sideOffset = 4, container, animated = true, ...props }, ref) => {
621
+ var TooltipContent = React8.forwardRef(({ className, sideOffset = 4, container, animated = true, ...props }, ref) => {
500
622
  const resolved = usePortalContainer(container);
501
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TooltipPrimitive.Portal, { container: resolved ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
623
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipPrimitive.Portal, { container: resolved ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
502
624
  TooltipPrimitive.Content,
503
625
  {
504
626
  ref,
@@ -527,7 +649,7 @@ function getTapTargetLinkComponent() {
527
649
  }
528
650
 
529
651
  // src/tap-target/tap-target-button.tsx
530
- var import_jsx_runtime8 = require("react/jsx-runtime");
652
+ var import_jsx_runtime9 = require("react/jsx-runtime");
531
653
  var EXTERNAL_RE = /^(https?:|mailto:|tel:)/i;
532
654
  var TAP_OUTER_CLASS = "matrx-tap-target group";
533
655
  var TAP_GROUP_OUTER_CLASS = "matrx-tap-target matrx-tap-target-sm group";
@@ -543,9 +665,9 @@ function IconContent({
543
665
  className: cn2(className, icon.props.className)
544
666
  });
545
667
  }
546
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className, children: icon });
668
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className, children: icon });
547
669
  }
548
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
670
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
549
671
  "svg",
550
672
  {
551
673
  className,
@@ -582,7 +704,7 @@ function buildTapInner({
582
704
  children,
583
705
  strokeWidth = 2
584
706
  }) {
585
- const iconEl = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
707
+ const iconEl = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
586
708
  IconContent,
587
709
  {
588
710
  icon,
@@ -593,11 +715,11 @@ function buildTapInner({
593
715
  );
594
716
  const pillClasses = label ? `${pillClassName} ${inlineModifier}`.trim() : pillClassName;
595
717
  if (!label) {
596
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: pillClasses, children: iconEl });
718
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: pillClasses, children: iconEl });
597
719
  }
598
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: pillClasses, children: [
720
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: pillClasses, children: [
599
721
  iconEl,
600
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: labelClassName ?? "matrx-tap-label", children: label })
722
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: labelClassName ?? "matrx-tap-label", children: label })
601
723
  ] });
602
724
  }
603
725
  function renderTapTarget({
@@ -685,7 +807,7 @@ function renderTrigger({
685
807
  buttonRef
686
808
  }) {
687
809
  if (disabled && href) {
688
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
810
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
689
811
  "span",
690
812
  {
691
813
  "aria-disabled": "true",
@@ -698,7 +820,7 @@ function renderTrigger({
698
820
  if (href) {
699
821
  const isExternal = EXTERNAL_RE.test(href);
700
822
  if (isExternal) {
701
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
823
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
702
824
  "a",
703
825
  {
704
826
  href,
@@ -712,7 +834,7 @@ function renderTrigger({
712
834
  }
713
835
  const Link = linkComponent ?? getTapTargetLinkComponent();
714
836
  if (Link) {
715
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
837
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
716
838
  Link,
717
839
  {
718
840
  href,
@@ -725,7 +847,7 @@ function renderTrigger({
725
847
  }
726
848
  );
727
849
  }
728
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
850
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
729
851
  "a",
730
852
  {
731
853
  href,
@@ -738,7 +860,7 @@ function renderTrigger({
738
860
  );
739
861
  }
740
862
  if (as === "label") {
741
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
863
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
742
864
  "label",
743
865
  {
744
866
  htmlFor,
@@ -748,7 +870,7 @@ function renderTrigger({
748
870
  }
749
871
  );
750
872
  }
751
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
873
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
752
874
  "button",
753
875
  {
754
876
  ref: buttonRef,
@@ -772,14 +894,14 @@ function withTooltip(trigger, {
772
894
  if (tooltip === false) return trigger;
773
895
  const label = typeof tooltip === "string" && tooltip.length > 0 ? tooltip : ariaLabel;
774
896
  if (!label) return trigger;
775
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Tooltip, { children: [
776
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipTrigger, { asChild: true, children: disabled ? (
897
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { children: [
898
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: disabled ? (
777
899
  // Radix Tooltip triggers need a hoverable element; a disabled button
778
900
  // does not dispatch pointer events, so we wrap in a span for the
779
901
  // trigger target while keeping the disabled visual state.
780
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "inline-flex", children: trigger })
902
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "inline-flex", children: trigger })
781
903
  ) : trigger }),
782
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipContent, { side: tooltipSide, align: tooltipAlign, children: label })
904
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipContent, { side: tooltipSide, align: tooltipAlign, children: label })
783
905
  ] });
784
906
  }
785
907
  var TapTargetButton = (0, import_react.forwardRef)(function TapTargetButton2({
@@ -935,7 +1057,7 @@ var TapTargetButtonDestructive = (0, import_react.forwardRef)(function TapTarget
935
1057
  hoverBgColor = "hover:bg-destructive/90",
936
1058
  ...rest
937
1059
  }, ref) {
938
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1060
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
939
1061
  TapTargetButtonSolid,
940
1062
  {
941
1063
  ref,
@@ -999,7 +1121,7 @@ var TapTargetButtonForGroup = (0, import_react.forwardRef)(function TapTargetBut
999
1121
 
1000
1122
  // src/content-transfer/icon.ts
1001
1123
  var ALCHEMY_GLYPH_PATHS = {
1002
- 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"],
1124
+ 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-4M12 8v8m-3-3 3 3 3-3"],
1003
1125
  "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"]
1004
1126
  };
1005
1127
  var ALCHEMY_GLYPH_VIEWBOX = { portal: "0 0 24 24", "copy-transform": "0 0 24 24" };
@@ -1007,15 +1129,119 @@ var svg = (paths, viewBox) => `<svg xmlns="http://www.w3.org/2000/svg" width="18
1007
1129
  var ALCHEMY_GLYPH_SVG = svg(ALCHEMY_GLYPH_PATHS.portal, ALCHEMY_GLYPH_VIEWBOX.portal);
1008
1130
  var ALCHEMY_COPY_TRANSFORM_SVG = svg(ALCHEMY_GLYPH_PATHS["copy-transform"], ALCHEMY_GLYPH_VIEWBOX["copy-transform"]);
1009
1131
 
1010
- // src/content-transfer/matrx-copy.tsx
1011
- var React8 = __toESM(require("react"), 1);
1132
+ // src/content-transfer/extensions.ts
1012
1133
  var import_content_transfer = require("@ai-matrx/kit/content-transfer");
1134
+ var exportableColumns = (payload) => payload.columns.filter(
1135
+ (column) => column.visible && column.exportable !== false && column.classification !== "secret" && column.classification !== "credential"
1136
+ );
1137
+ var tableSchemaFormat = {
1138
+ id: "table-schema",
1139
+ label: "Schema + rows",
1140
+ supports: (payload) => payload.kind === "rows",
1141
+ async build(draft, signal) {
1142
+ if (signal.aborted) throw new DOMException("Cancelled", "AbortError");
1143
+ if (draft.payload.kind !== "rows")
1144
+ throw new import_content_transfer.ContentTransferError(
1145
+ "unsupported-format",
1146
+ "Schema + rows requires tabular content; manually edited text cannot carry a table schema."
1147
+ );
1148
+ const rowColumns = exportableColumns(draft.payload);
1149
+ const columns = rowColumns.map((column) => ({
1150
+ id: column.id,
1151
+ label: column.label,
1152
+ path: column.path,
1153
+ ...column.schema === void 0 ? {} : { schema: column.schema }
1154
+ }));
1155
+ const body = {
1156
+ sourceId: draft.sourceId,
1157
+ columns,
1158
+ rows: draft.payload.rows.map(
1159
+ (row) => Object.fromEntries(rowColumns.map((column) => [column.id, (0, import_content_transfer.readTransferCell)(row, column) ?? null]))
1160
+ )
1161
+ };
1162
+ const plainText = JSON.stringify(body, null, 2);
1163
+ return (0, import_content_transfer.sealTransferArtifact)({
1164
+ snapshotId: draft.snapshotId,
1165
+ draftRevision: draft.revision,
1166
+ format: "table-schema",
1167
+ plainText,
1168
+ file: {
1169
+ filename: "table-schema.json",
1170
+ mime: "application/json",
1171
+ bytes: new TextEncoder().encode(plainText)
1172
+ },
1173
+ omissions: [...draft.omissions]
1174
+ });
1175
+ }
1176
+ };
1177
+ function displayLabels(payload) {
1178
+ const columns = exportableColumns(payload);
1179
+ const counts = /* @__PURE__ */ new Map();
1180
+ for (const column of columns) counts.set(column.label, (counts.get(column.label) ?? 0) + 1);
1181
+ const used = /* @__PURE__ */ new Set();
1182
+ return columns.map((column) => {
1183
+ const base = counts.get(column.label) === 1 ? column.label : `${column.label} [${column.id}]`;
1184
+ let label = base;
1185
+ for (let suffix = 2; used.has(label); suffix += 1) label = `${base} (${suffix})`;
1186
+ used.add(label);
1187
+ return [label, column];
1188
+ });
1189
+ }
1190
+ var tableDataFormat = {
1191
+ id: "table-data",
1192
+ label: "JSON (display labels)",
1193
+ supports: (payload) => payload.kind === "rows",
1194
+ async build(draft, signal) {
1195
+ if (signal.aborted) throw new DOMException("Cancelled", "AbortError");
1196
+ if (draft.payload.kind !== "rows")
1197
+ throw new import_content_transfer.ContentTransferError("unsupported-format", "Display-label JSON requires tabular content.");
1198
+ const columns = displayLabels(draft.payload);
1199
+ const plainText = JSON.stringify(
1200
+ draft.payload.rows.map(
1201
+ (row) => Object.fromEntries(columns.map(([label, column]) => [label, (0, import_content_transfer.readTransferCell)(row, column) ?? null]))
1202
+ ),
1203
+ null,
1204
+ 2
1205
+ );
1206
+ return (0, import_content_transfer.sealTransferArtifact)({
1207
+ snapshotId: draft.snapshotId,
1208
+ draftRevision: draft.revision,
1209
+ format: "json",
1210
+ plainText,
1211
+ file: {
1212
+ filename: "data.json",
1213
+ mime: "application/json;charset=utf-8",
1214
+ bytes: new TextEncoder().encode(plainText)
1215
+ },
1216
+ omissions: [...draft.omissions]
1217
+ });
1218
+ }
1219
+ };
1220
+ var emailArtifact = (draft, format, signal, jsonFormat) => format === "json" && jsonFormat?.supports(draft.payload) ? jsonFormat.build(draft, signal) : Promise.resolve((0, import_content_transfer.serialize)(draft, format, { spreadsheetSafe: format === "csv" }));
1221
+ function createTransferEmailActions(email, options = {}) {
1222
+ return ["csv", "json", "markdown"].map((format) => ({
1223
+ id: `email-${format}`,
1224
+ label: `Email ${format === "csv" ? "CSV" : format === "json" ? "JSON" : "Markdown"}`,
1225
+ prepared: true,
1226
+ group: "email",
1227
+ supports: (_snapshot, draft) => Boolean(draft) && (format !== "csv" || draft?.payload.kind === "rows"),
1228
+ async run({ draft, signal, snapshot }) {
1229
+ if (signal.aborted) return { status: "cancelled" };
1230
+ const artifact = await emailArtifact(draft, format, signal, options.jsonFormat);
1231
+ return email.send(artifact, { label: snapshot.label, signal });
1232
+ }
1233
+ }));
1234
+ }
1235
+
1236
+ // src/content-transfer/matrx-copy.tsx
1237
+ var React9 = __toESM(require("react"), 1);
1238
+ var import_content_transfer2 = require("@ai-matrx/kit/content-transfer");
1013
1239
  var import_format = require("@ai-matrx/kit/format");
1014
- var import_jsx_runtime9 = require("react/jsx-runtime");
1240
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1015
1241
  var resolve = (value) => typeof value === "function" ? value() : value;
1016
1242
  var asPayload = (value) => ({
1017
1243
  kind: "markdown",
1018
- text: typeof value === "string" ? value : (0, import_content_transfer.buildAgentPayload)(value)
1244
+ text: typeof value === "string" ? value : (0, import_content_transfer2.buildAgentPayload)(value)
1019
1245
  });
1020
1246
  var structuredPayload = (value) => {
1021
1247
  if (typeof value === "string") return { kind: "markdown", text: value };
@@ -1024,7 +1250,7 @@ var structuredPayload = (value) => {
1024
1250
  );
1025
1251
  return {
1026
1252
  kind: "json",
1027
- value: (0, import_content_transfer.normalizeTransferJson)(
1253
+ value: (0, import_content_transfer2.normalizeTransferJson)(
1028
1254
  {
1029
1255
  kind: value.kind,
1030
1256
  location: value.location,
@@ -1052,12 +1278,12 @@ var sourceFor = (id, label, build) => ({
1052
1278
  signal.throwIfAborted();
1053
1279
  const payload = await build();
1054
1280
  signal.throwIfAborted();
1055
- return (0, import_content_transfer.directSource)(payload, { sourceId: id, label });
1281
+ return (0, import_content_transfer2.directSource)(payload, { sourceId: id, label });
1056
1282
  }
1057
1283
  });
1058
1284
  function MatrxCopyMenu(props) {
1059
1285
  const inherited = useContentTransferCapabilities();
1060
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1286
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1061
1287
  MatrxCopyMenuSession,
1062
1288
  {
1063
1289
  ...props
@@ -1069,12 +1295,12 @@ function MatrxCopyMenu(props) {
1069
1295
  );
1070
1296
  }
1071
1297
  function MatrxCopyMenuSession(props) {
1072
- const instance = React8.useId();
1073
- const controller = React8.useRef(null);
1298
+ const instance = React9.useId();
1299
+ const controller = React9.useRef(null);
1074
1300
  const capabilities = useContentTransferCapabilities();
1075
- const transport = capabilities.transport ?? (0, import_content_transfer.createBrowserTransport)();
1076
- const [modal, setModal] = React8.useState(null);
1077
- const [configuration, setConfiguration] = React8.useState(null);
1301
+ const transport = capabilities.transport ?? (0, import_content_transfer2.createBrowserTransport)();
1302
+ const [modal, setModal] = React9.useState(null);
1303
+ const [configuration, setConfiguration] = React9.useState(null);
1078
1304
  const copyVisible = !props.hide?.includes("copy");
1079
1305
  const aiVisible = !props.hide?.includes("ai");
1080
1306
  const exportVisible = !props.hide?.includes("export");
@@ -1090,14 +1316,14 @@ function MatrxCopyMenuSession(props) {
1090
1316
  })) : void 0;
1091
1317
  const json = aiVisible && props.json !== void 0 ? make("json", () => ({
1092
1318
  kind: "json",
1093
- value: (0, import_content_transfer.normalizeTransferJson)(resolve(props.json), {
1319
+ value: (0, import_content_transfer2.normalizeTransferJson)(resolve(props.json), {
1094
1320
  omitUndefinedObjectProperties: true
1095
1321
  })
1096
1322
  })) : void 0;
1097
1323
  const agent = aiVisible && props.agent !== void 0 ? make("agent", () => asPayload(resolve(props.agent))) : void 0;
1098
1324
  const structuredAgent = aiVisible && props.agent !== void 0 ? make("structured-agent", () => structuredPayload(resolve(props.agent))) : void 0;
1099
1325
  const table = (exportVisible || props.primarySource === "table") && props.export?.sheetRows ? make("rows", () => {
1100
- const value = (0, import_content_transfer.normalizeTransferJson)(props.export.sheetRows(), {
1326
+ const value = (0, import_content_transfer2.normalizeTransferJson)(props.export.sheetRows(), {
1101
1327
  omitUndefinedObjectProperties: true
1102
1328
  });
1103
1329
  if (!Array.isArray(value) || value.some(
@@ -1234,7 +1460,7 @@ function MatrxCopyMenuSession(props) {
1234
1460
  const bytes = new Uint8Array(value.bytes);
1235
1461
  const filename = typeof value.filename === "string" ? value.filename : `${props.label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "export"}.${value.extension.replace(/[^a-zA-Z0-9.-]/g, "") || "bin"}`;
1236
1462
  return transport.download(
1237
- (0, import_content_transfer.sealTransferArtifact)({
1463
+ (0, import_content_transfer2.sealTransferArtifact)({
1238
1464
  snapshotId: snapshot.id,
1239
1465
  draftRevision: draft.revision,
1240
1466
  format: `export:${item.id}`,
@@ -1261,11 +1487,14 @@ function MatrxCopyMenuSession(props) {
1261
1487
  const source = (props.primarySource === "table" ? table : void 0) ?? json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
1262
1488
  if (!source && !actions.length) return null;
1263
1489
  const target = source ?? make("actions", () => ({ kind: "text", text: props.label }));
1264
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1265
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1490
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1491
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1266
1492
  ContentTransferMenu,
1267
1493
  {
1494
+ triggerSize: props.size === "xs" || props.size === "toolbar" ? "compact" : "default",
1268
1495
  source: target,
1496
+ ...props.references ? { references: props.references } : {},
1497
+ ...props.referenceActions ? { referenceActions: props.referenceActions } : {},
1269
1498
  ...props.icon !== void 0 ? { icon: props.icon } : {},
1270
1499
  ...props.triggerVariant !== void 0 ? { triggerVariant: props.triggerVariant } : {},
1271
1500
  controllerRef: controller,
@@ -1299,7 +1528,7 @@ function MatrxCopyMenuSession(props) {
1299
1528
  if (!open) setModal(null);
1300
1529
  }
1301
1530
  }),
1302
- configuration ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1531
+ configuration ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1303
1532
  SourceConfiguration,
1304
1533
  {
1305
1534
  restoreFocus: () => controller.current?.focusTrigger(),
@@ -1326,14 +1555,14 @@ function SourceConfiguration({
1326
1555
  onPrepare
1327
1556
  }) {
1328
1557
  const custom = configuration.custom;
1329
- const handingOff = React8.useRef(false);
1558
+ const handingOff = React9.useRef(false);
1330
1559
  const groomer = configuration.groomer;
1331
- const [values, setValues] = React8.useState(
1560
+ const [values, setValues] = React9.useState(
1332
1561
  () => Object.fromEntries(
1333
1562
  custom?.options.map((option) => [option.key, option.default]) ?? []
1334
1563
  )
1335
1564
  );
1336
- const [sections, setSections] = React8.useState(
1565
+ const [sections, setSections] = React9.useState(
1337
1566
  () => Object.fromEntries(
1338
1567
  groomer?.sections.map((section) => [
1339
1568
  section.id,
@@ -1341,8 +1570,8 @@ function SourceConfiguration({
1341
1570
  ]) ?? []
1342
1571
  )
1343
1572
  );
1344
- const [error, setError] = React8.useState(null);
1345
- const [busy, setBusy] = React8.useState(false);
1573
+ const [error, setError] = React9.useState(null);
1574
+ const [busy, setBusy] = React9.useState(false);
1346
1575
  const title = custom?.dialogTitle ?? groomer?.label ?? "Customize source";
1347
1576
  let prepared = null;
1348
1577
  let buildError = null;
@@ -1375,18 +1604,18 @@ function SourceConfiguration({
1375
1604
  ...groomer.context ? { context: groomer.context } : {}
1376
1605
  };
1377
1606
  }
1378
- text = prepared ? (0, import_content_transfer.buildAgentPayload)(prepared) : "";
1607
+ text = prepared ? (0, import_content_transfer2.buildAgentPayload)(prepared) : "";
1379
1608
  } catch (cause) {
1380
1609
  buildError = cause instanceof Error ? cause.message : "Could not prepare this source.";
1381
1610
  }
1382
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1611
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1383
1612
  Dialog,
1384
1613
  {
1385
1614
  open: true,
1386
1615
  onOpenChange: (open) => {
1387
1616
  if (!open && !busy) onClose();
1388
1617
  },
1389
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1618
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1390
1619
  DialogContent,
1391
1620
  {
1392
1621
  onCloseAutoFocus: (event) => {
@@ -1395,23 +1624,23 @@ function SourceConfiguration({
1395
1624
  },
1396
1625
  className: "matrx-alchemy-workspace matrx-alchemy-configuration",
1397
1626
  children: [
1398
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DialogHeader, { children: [
1399
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DialogTitle, { children: title }),
1400
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DialogDescription, { children: custom?.dialogDescription ?? "Choose the source detail, then prepare, edit, summarize, copy or export it in Alchemy." })
1627
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogHeader, { children: [
1628
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DialogTitle, { children: title }),
1629
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DialogDescription, { children: custom?.dialogDescription ?? "Choose the source detail, then prepare, edit, summarize, copy or export it in Alchemy." })
1401
1630
  ] }),
1402
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
1403
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "matrx-alchemy-main matrx-alchemy-toolbar", children: [
1404
- custom?.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { children: [
1631
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
1632
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-main matrx-alchemy-toolbar", children: [
1633
+ custom?.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
1405
1634
  option.label,
1406
- "hint" in option && option.hint ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("small", { children: option.hint }) : null,
1407
- option.kind === "toggle" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1635
+ "hint" in option && option.hint ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { children: option.hint }) : null,
1636
+ option.kind === "toggle" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1408
1637
  "input",
1409
1638
  {
1410
1639
  type: "checkbox",
1411
1640
  checked: Boolean(values[option.key]),
1412
1641
  onChange: (event) => setValues({ ...values, [option.key]: event.target.checked })
1413
1642
  }
1414
- ) : option.kind === "preset" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1643
+ ) : option.kind === "preset" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1415
1644
  "select",
1416
1645
  {
1417
1646
  value: Number(values[option.key]),
@@ -1419,10 +1648,10 @@ function SourceConfiguration({
1419
1648
  ...values,
1420
1649
  [option.key]: Number(event.target.value)
1421
1650
  }),
1422
- children: option.options.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: choice.value, children: choice.label }, choice.value))
1651
+ children: option.options.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: choice.value, children: choice.label }, choice.value))
1423
1652
  }
1424
- ) : option.kind === "slider" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1425
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1653
+ ) : option.kind === "slider" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1654
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1426
1655
  "input",
1427
1656
  {
1428
1657
  type: "range",
@@ -1436,9 +1665,9 @@ function SourceConfiguration({
1436
1665
  })
1437
1666
  }
1438
1667
  ),
1439
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: option.formatValue(Number(values[option.key])) })
1440
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1441
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1668
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: option.formatValue(Number(values[option.key])) })
1669
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1670
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1442
1671
  "input",
1443
1672
  {
1444
1673
  type: "number",
@@ -1451,7 +1680,7 @@ function SourceConfiguration({
1451
1680
  })
1452
1681
  }
1453
1682
  ),
1454
- option.presets?.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1683
+ option.presets?.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1455
1684
  Button,
1456
1685
  {
1457
1686
  type: "button",
@@ -1464,8 +1693,8 @@ function SourceConfiguration({
1464
1693
  ))
1465
1694
  ] })
1466
1695
  ] }, option.key)),
1467
- groomer ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1468
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { children: ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1696
+ groomer ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1697
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { children: ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1469
1698
  Button,
1470
1699
  {
1471
1700
  type: "button",
@@ -1483,9 +1712,9 @@ function SourceConfiguration({
1483
1712
  },
1484
1713
  level
1485
1714
  )) }),
1486
- groomer.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { children: [
1715
+ groomer.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
1487
1716
  section.title,
1488
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1717
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1489
1718
  "select",
1490
1719
  {
1491
1720
  value: sections[section.id],
@@ -1494,26 +1723,26 @@ function SourceConfiguration({
1494
1723
  [section.id]: event.target.value
1495
1724
  }),
1496
1725
  children: [
1497
- ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: level, children: section.levelLabels?.[level] ?? level }, level)),
1498
- section.cuttable ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "off", children: "Exclude" }) : null
1726
+ ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: level, children: section.levelLabels?.[level] ?? level }, level)),
1727
+ section.cuttable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "off", children: "Exclude" }) : null
1499
1728
  ]
1500
1729
  }
1501
1730
  ),
1502
- section.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: section.description }) : null
1731
+ section.description ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: section.description }) : null
1503
1732
  ] }, section.id))
1504
1733
  ] }) : null
1505
1734
  ] }),
1506
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("p", { children: [
1735
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { children: [
1507
1736
  (0, import_format.formatCount)(text.length),
1508
1737
  " characters \xB7 approximately",
1509
1738
  " ",
1510
1739
  (0, import_format.formatCount)(Math.ceil(text.length / 4)),
1511
1740
  " tokens"
1512
1741
  ] }),
1513
- error || buildError ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { role: "alert", children: error ?? buildError }) : null
1742
+ error || buildError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", children: error ?? buildError }) : null
1514
1743
  ] }),
1515
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DialogFooter, { children: [
1516
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1744
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogFooter, { children: [
1745
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1517
1746
  Button,
1518
1747
  {
1519
1748
  type: "button",
@@ -1524,7 +1753,7 @@ function SourceConfiguration({
1524
1753
  children: "Cancel"
1525
1754
  }
1526
1755
  ),
1527
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1756
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1528
1757
  Button,
1529
1758
  {
1530
1759
  type: "button",
@@ -1615,26 +1844,26 @@ function groomerPresetVariants(getConfig) {
1615
1844
  }
1616
1845
 
1617
1846
  // src/content-transfer/index.tsx
1618
- var import_jsx_runtime10 = require("react/jsx-runtime");
1847
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1619
1848
  function AlchemyGlyph({ icon = "portal", ...props }) {
1620
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { width: "18", height: "18", viewBox: ALCHEMY_GLYPH_VIEWBOX[icon], fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", ...props, children: ALCHEMY_GLYPH_PATHS[icon].map((d) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d }, d)) });
1849
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { width: "18", height: "18", viewBox: ALCHEMY_GLYPH_VIEWBOX[icon], fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", ...props, children: ALCHEMY_GLYPH_PATHS[icon].map((d) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d }, d)) });
1621
1850
  }
1622
- var CapabilityContext = React9.createContext({});
1851
+ var CapabilityContext = React10.createContext({});
1623
1852
  function ContentTransferCapabilitiesProvider({ value, children }) {
1624
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CapabilityContext.Provider, { value, children });
1853
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CapabilityContext.Provider, { value, children });
1625
1854
  }
1626
- var useContentTransferCapabilities = () => React9.useContext(CapabilityContext);
1627
- var SurfaceContext = React9.createContext(null);
1855
+ var useContentTransferCapabilities = () => React10.useContext(CapabilityContext);
1856
+ var SurfaceContext = React10.createContext(null);
1628
1857
  function ContentTransferSurfaceProvider({ handle, children }) {
1629
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SurfaceContext.Provider, { value: handle, children });
1858
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SurfaceContext.Provider, { value: handle, children });
1630
1859
  }
1631
- var useContentTransferSurface = () => React9.useContext(SurfaceContext);
1860
+ var useContentTransferSurface = () => React10.useContext(SurfaceContext);
1632
1861
  function MenuPresentation({ label, hint, icon: Icon }) {
1633
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1634
- Icon ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { className: "matrx-alchemy-menu-icon" }) : null,
1635
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
1862
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1863
+ Icon ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { className: "matrx-alchemy-menu-icon" }) : null,
1864
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
1636
1865
  label,
1637
- hint ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
1866
+ hint ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
1638
1867
  ] })
1639
1868
  ] });
1640
1869
  }
@@ -1652,71 +1881,71 @@ function DestinationPresentation({ action }) {
1652
1881
  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"
1653
1882
  };
1654
1883
  const path = paths[action.id.replace(/^matrx:/, "")];
1655
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1656
- !action.icon ? path ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: path }) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { file: true }) : null,
1657
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MenuPresentation, { ...action })
1884
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1885
+ !action.icon ? path ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: path }) }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteGlyph, { file: true }) : null,
1886
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MenuPresentation, { ...action })
1658
1887
  ] });
1659
1888
  }
1660
1889
  function ReceiptLink({ target }) {
1661
- return target?.href && /^(\/(?!\/)|https?:\/\/)/.test(target.href) ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("a", { className: "matrx-alchemy-receipt-link", href: target.href, children: [
1890
+ return target?.href && /^(\/(?!\/)|https?:\/\/)/.test(target.href) ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("a", { className: "matrx-alchemy-receipt-link", href: target.href, children: [
1662
1891
  "Open ",
1663
1892
  target.kind
1664
1893
  ] }) : null;
1665
1894
  }
1666
1895
  function PaletteGlyph({ format, ai = false, file = false, kind }) {
1667
- if (kind === "ai-copy") return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1668
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { x: "5", y: "5", width: "11", height: "14", rx: "2" }),
1669
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M9 3h6a2 2 0 0 1 2 2v10" }),
1670
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m18.5 3 .55 1.45L20.5 5l-1.45.55L18.5 7l-.55-1.45L16.5 5l1.45-.55z" })
1896
+ if (kind === "ai-copy") return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1897
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("rect", { x: "5", y: "5", width: "11", height: "14", rx: "2" }),
1898
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M9 3h6a2 2 0 0 1 2 2v10" }),
1899
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "m18.5 3 .55 1.45L20.5 5l-1.45.55L18.5 7l-.55-1.45L16.5 5l1.45-.55z" })
1671
1900
  ] });
1672
- if (kind === "sliders") return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1673
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 6h16M4 12h16M4 18h16" }),
1674
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M8 3v6M16 9v6M10 15v6" })
1901
+ if (kind === "sliders") return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1902
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M4 6h16M4 12h16M4 18h16" }),
1903
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M8 3v6M16 9v6M10 15v6" })
1675
1904
  ] });
1676
- if (ai) return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1677
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 5a3 3 0 1 0-5.997.125A4 4 0 0 0 3.5 10.9a4 4 0 0 0 .556 6.588A4 4 0 0 0 12 19" }),
1678
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.503 5.775 4 4 0 0 1-.556 6.588A4 4 0 0 1 12 19" }),
1679
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 5v14M8 9h1M15 9h1M8 15h1M15 15h1" })
1905
+ if (ai) return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1906
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M12 5a3 3 0 1 0-5.997.125A4 4 0 0 0 3.5 10.9a4 4 0 0 0 .556 6.588A4 4 0 0 0 12 19" }),
1907
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.503 5.775 4 4 0 0 1-.556 6.588A4 4 0 0 1 12 19" }),
1908
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M12 5v14M8 9h1M15 9h1M8 15h1M15 15h1" })
1680
1909
  ] });
1681
- if (file) return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1682
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M6 3h8l4 4v14H6z" }),
1683
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 3v5h5M9 13h6M9 17h6" })
1910
+ if (file) return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1911
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M6 3h8l4 4v14H6z" }),
1912
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M14 3v5h5M9 13h6M9 17h6" })
1684
1913
  ] });
1685
- const path = format === "json" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1686
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M9 4C7 4 7 7 5 7v3c2 0 2 1 2 2s0 2-2 2v3c2 0 2 3 4 3" }),
1687
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M15 4c2 0 2 3 4 3v3c-2 0-2 1-2 2s0 2 2 2v3c-2 0-2 3-4 3" })
1688
- ] }) : format === "compact-json" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1689
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m14 10 7-7" }),
1690
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M20 10h-6V4" }),
1691
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m3 21 7-7" }),
1692
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 14h6v6" })
1693
- ] }) : format === "csv" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1694
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { x: "4", y: "4", width: "16", height: "16", rx: "1" }),
1695
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 10h16M10 4v16" })
1696
- ] }) : format === "tsv" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1697
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1698
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v6h6M8 13h2M14 13h2M8 17h2M14 17h2" })
1699
- ] }) : format === "xlsx" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1700
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1701
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v6h6M8 13h8M8 17h8M12 11v8" })
1702
- ] }) : format === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1703
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5z" }),
1704
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v6h6M10 13l-2 2 2 2M14 17l2-2-2-2" })
1705
- ] }) : format === "html" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M15 6h6M3 6h7M3 12h18M3 18h12" }) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 7V4h16v3M9 20h6M12 4v16" }) });
1706
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: path });
1914
+ const path = format === "json" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1915
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M9 4C7 4 7 7 5 7v3c2 0 2 1 2 2s0 2-2 2v3c2 0 2 3 4 3" }),
1916
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M15 4c2 0 2 3 4 3v3c-2 0-2 1-2 2s0 2 2 2v3c-2 0-2 3-4 3" })
1917
+ ] }) : format === "compact-json" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1918
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "m14 10 7-7" }),
1919
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M20 10h-6V4" }),
1920
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "m3 21 7-7" }),
1921
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M4 14h6v6" })
1922
+ ] }) : format === "csv" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1923
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("rect", { x: "4", y: "4", width: "16", height: "16", rx: "1" }),
1924
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M4 10h16M10 4v16" })
1925
+ ] }) : format === "tsv" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1926
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1927
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M14 2v6h6M8 13h2M14 13h2M8 17h2M14 17h2" })
1928
+ ] }) : format === "xlsx" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1929
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1930
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M14 2v6h6M8 13h8M8 17h8M12 11v8" })
1931
+ ] }) : format === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1932
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5z" }),
1933
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M14 2v6h6M10 13l-2 2 2 2M14 17l2-2-2-2" })
1934
+ ] }) : format === "html" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M15 6h6M3 6h7M3 12h18M3 18h12" }) }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M4 7V4h16v3M9 20h6M12 4v16" }) });
1935
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: path });
1707
1936
  }
1708
1937
  function PaletteRows({ title, items, onRun, extra, ai = false, glyphKind, fallbackHint }) {
1709
1938
  if (!items.length && !extra) return null;
1710
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
1711
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: title }),
1939
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
1940
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { children: title }),
1712
1941
  items.map((item) => {
1713
1942
  const label = item.copyLabel ?? item.label;
1714
1943
  const hint = item.hint ?? fallbackHint;
1715
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", className: cn("matrx-alchemy-palette-row", ai && "matrx-alchemy-palette-row-ai"), "aria-label": item.ariaLabel ?? `${label}${hint ? ` ${hint}` : ""}`, onClick: () => onRun?.(item), children: [
1716
- item.icon ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(item.icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { ai, ...glyphKind ? { kind: glyphKind } : {} }),
1717
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
1944
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { type: "button", className: cn("matrx-alchemy-palette-row", ai && "matrx-alchemy-palette-row-ai"), "aria-label": item.ariaLabel ?? `${label}${hint ? ` ${hint}` : ""}`, onClick: () => onRun?.(item), children: [
1945
+ item.icon ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(item.icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteGlyph, { ai, ...glyphKind ? { kind: glyphKind } : {} }),
1946
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
1718
1947
  label,
1719
- hint ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
1948
+ hint ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
1720
1949
  ] })
1721
1950
  ] }, item.id);
1722
1951
  }),
@@ -1759,10 +1988,10 @@ function snapshotContent(snapshot) {
1759
1988
  return JSON.stringify({ sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits });
1760
1989
  }
1761
1990
  function useFence() {
1762
- const mounted = React9.useRef(true);
1763
- const nextId = React9.useRef(0);
1764
- const active = React9.useRef(/* @__PURE__ */ new Set());
1765
- React9.useEffect(() => {
1991
+ const mounted = React10.useRef(true);
1992
+ const nextId = React10.useRef(0);
1993
+ const active = React10.useRef(/* @__PURE__ */ new Set());
1994
+ React10.useEffect(() => {
1766
1995
  mounted.current = true;
1767
1996
  return () => {
1768
1997
  mounted.current = false;
@@ -1771,14 +2000,14 @@ function useFence() {
1771
2000
  active.current.clear();
1772
2001
  };
1773
2002
  }, []);
1774
- const begin = React9.useCallback(() => {
2003
+ const begin = React10.useCallback(() => {
1775
2004
  const controller = new AbortController();
1776
2005
  active.current.add(controller);
1777
2006
  return { controller, id: ++nextId.current };
1778
2007
  }, []);
1779
- const finish = React9.useCallback((controller) => active.current.delete(controller), []);
1780
- const valid = React9.useCallback((id, controller) => mounted.current && !controller.signal.aborted && nextId.current === id, []);
1781
- const abortAll = React9.useCallback(() => {
2008
+ const finish = React10.useCallback((controller) => active.current.delete(controller), []);
2009
+ const valid = React10.useCallback((id, controller) => mounted.current && !controller.signal.aborted && nextId.current === id, []);
2010
+ const abortAll = React10.useCallback(() => {
1782
2011
  nextId.current += 1;
1783
2012
  active.current.forEach((c) => c.abort());
1784
2013
  active.current.clear();
@@ -1790,73 +2019,79 @@ async function xlsxArtifact(draft, label) {
1790
2019
  const XLSX = await import("xlsx");
1791
2020
  const columns = draft.payload.columns.filter((c) => c.visible && c.exportable !== false && c.classification !== "secret" && c.classification !== "credential");
1792
2021
  const cells = draft.payload.rows.map((row) => columns.map((column) => {
1793
- const value = (0, import_content_transfer2.readTransferCell)(row, column);
2022
+ const value = (0, import_content_transfer3.readTransferCell)(row, column);
1794
2023
  return value === null || ["string", "number", "boolean"].includes(typeof value) ? value : value === void 0 ? "" : JSON.stringify(value);
1795
2024
  }));
1796
2025
  const sheet = XLSX.utils.aoa_to_sheet([columns.map((c) => c.label), ...cells]);
1797
2026
  const book = XLSX.utils.book_new();
1798
2027
  XLSX.utils.book_append_sheet(book, sheet, label.replace(/[\\/?*[\]:]/g, " ").trim().slice(0, 31) || "Data");
1799
2028
  const written = XLSX.write(book, { type: "array", bookType: "xlsx", compression: true });
1800
- return (0, import_content_transfer2.sealTransferArtifact)({ snapshotId: draft.snapshotId, draftRevision: draft.revision, format: "xlsx", plainText: (0, import_content_transfer2.serialize)(draft, "tsv", { spreadsheetSafe: true }).plainText, file: { filename: `${filenameFor(label)}.xlsx`, mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", bytes: written instanceof Uint8Array ? written : new Uint8Array(written) }, omissions: [...draft.omissions] });
2029
+ return (0, import_content_transfer3.sealTransferArtifact)({ snapshotId: draft.snapshotId, draftRevision: draft.revision, format: "xlsx", plainText: (0, import_content_transfer3.serialize)(draft, "tsv", { spreadsheetSafe: true }).plainText, file: { filename: `${filenameFor(label)}.xlsx`, mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", bytes: written instanceof Uint8Array ? written : new Uint8Array(written) }, omissions: [...draft.omissions] });
1801
2030
  }
1802
2031
  async function buildArtifact(draft, format, label) {
1803
2032
  if (!supportsBuiltIn(format, draft.payload)) throw new Error(`${LABEL[format]} is available for tabular content only.`);
1804
2033
  if (format === "xlsx") return xlsxArtifact(draft, label);
1805
- if (format === "html" && draft.payload.kind === "markdown") return (0, import_content_transfer2.serializeMarkdownRich)(draft, `${filenameFor(label)}.html`);
2034
+ if (format === "html" && draft.payload.kind === "markdown") return (0, import_content_transfer3.serializeMarkdownRich)(draft, `${filenameFor(label)}.html`);
1806
2035
  const extension = format === "plain" ? "txt" : format === "compact-json" ? "json" : format;
1807
- return (0, import_content_transfer2.serialize)(draft, format, { spreadsheetSafe: format === "csv" || format === "tsv", filename: `${filenameFor(label)}.${extension}` });
2036
+ return (0, import_content_transfer3.serialize)(draft, format, { spreadsheetSafe: format === "csv" || format === "tsv", filename: `${filenameFor(label)}.${extension}` });
1808
2037
  }
1809
2038
  function ContentTransferMenu(props) {
1810
- const inherited = React9.useContext(CapabilityContext);
2039
+ const inherited = React10.useContext(CapabilityContext);
1811
2040
  const identityKey = props.capabilities?.identityKey ?? inherited.identityKey;
1812
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
2041
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
1813
2042
  }
1814
- 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" }) {
1815
- const triggerRef = React9.useRef(null);
1816
- const inherited = React9.useContext(CapabilityContext);
1817
- const nearestSurface = React9.useContext(SurfaceContext);
2043
+ function ContentTransferMenuSession({ references = [], referenceActions = [], 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", triggerSize = "default" }) {
2044
+ const triggerRef = React10.useRef(null);
2045
+ const inherited = React10.useContext(CapabilityContext);
2046
+ const nearestSurface = React10.useContext(SurfaceContext);
1818
2047
  const fence = useFence();
1819
- const [menuCapture, setMenuCapture] = React9.useState(null);
1820
- const [menuStatus, setMenuStatus] = React9.useState("idle");
1821
- const [workspaces, setWorkspaces] = React9.useState({});
1822
- const [workspaceKey, setWorkspaceKey] = React9.useState(null);
1823
- const [workspaceOpen, setWorkspaceOpen] = React9.useState(false);
1824
- const workspaceCaptures = React9.useRef(/* @__PURE__ */ new Map());
1825
- const externalWorkspaceKeys = React9.useRef(/* @__PURE__ */ new Set());
1826
- const [notice, setNotice] = React9.useState(null);
1827
- const [receiptTarget, setReceiptTarget] = React9.useState();
1828
- const [paletteOpen, setPaletteOpen] = React9.useState(false);
1829
- const [mode, setMode] = React9.useState("copy");
1830
- const scopes = React9.useMemo(() => table?.availableScopes ?? ["target"], [table]);
1831
- const initialScope = table?.initialScope ?? "target";
2048
+ const [menuCapture, setMenuCapture] = React10.useState(null);
2049
+ const [menuStatus, setMenuStatus] = React10.useState("idle");
2050
+ const [workspaces, setWorkspaces] = React10.useState({});
2051
+ const [workspaceKey, setWorkspaceKey] = React10.useState(null);
2052
+ const [workspaceOpen, setWorkspaceOpen] = React10.useState(false);
2053
+ const workspaceCaptures = React10.useRef(/* @__PURE__ */ new Map());
2054
+ const externalWorkspaceKeys = React10.useRef(/* @__PURE__ */ new Set());
2055
+ const [notice, setNotice] = React10.useState(null);
2056
+ const [receiptTarget, setReceiptTarget] = React10.useState();
2057
+ const [paletteOpen, setPaletteOpen] = React10.useState(false);
2058
+ const [mode, setMode] = React10.useState("copy");
2059
+ const scopes = React10.useMemo(() => table?.availableScopes ?? ["target"], [table]);
2060
+ const [requestedScope, setRequestedScope] = React10.useState(table?.initialScope ?? "target");
2061
+ const initialScope = scopes.includes(requestedScope) ? requestedScope : table?.initialScope ?? "target";
1832
2062
  if (!scopes.includes(initialScope)) throw new Error("Alchemy initialScope must be included in availableScopes.");
1833
2063
  const primary = surface ?? source ?? nearestSurface;
1834
2064
  const sourceLabel = label ?? (surface?.surfaceName ?? (source && "label" in source ? source.label : nearestSurface?.surfaceName) ?? "content");
1835
- const primaryWorkspaceKey = `primary:${materialIdentity(primary)}`;
2065
+ const primaryWorkspaceBase = `primary:${materialIdentity(primary)}`;
2066
+ const primaryWorkspaceKey = `${primaryWorkspaceBase}:${initialScope}`;
1836
2067
  const nearestWorkspaceKey = source && !surface && nearestSurface ? `surface:${materialIdentity(nearestSurface)}` : null;
1837
- const variantWorkspaceKeys = React9.useMemo(() => new Map(variants.map((variant) => [variant.id, `variant:${variant.id}:${materialIdentity(variant.source)}`])), [variants]);
1838
- const transport = local?.transport ?? inherited.transport ?? (0, import_content_transfer2.createBrowserTransport)();
2068
+ const variantWorkspaceKeys = React10.useMemo(() => new Map(variants.map((variant) => [variant.id, `variant:${variant.id}:${materialIdentity(variant.source)}`])), [variants]);
2069
+ const transport = local?.transport ?? inherited.transport ?? (0, import_content_transfer3.createBrowserTransport)();
1839
2070
  const ai = local?.ai ?? inherited.ai;
1840
- const providerPreferences = React9.useMemo(() => (0, import_content_transfer2.resolveTransferPreferences)(inherited.preferences, local?.preferences), [inherited.preferences, local?.preferences]);
1841
- const adapters = React9.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(BUILT_INS, inherited.formats ?? [], local?.formats ?? []).filter((x) => "build" in x), [inherited.formats, local?.formats]);
1842
- const registeredActions = React9.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(inherited.actions ?? [], local?.actions ?? [], actions), [actions, inherited.actions, local?.actions]);
1843
- React9.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(variants), [variants]);
1844
- const report = React9.useCallback((result) => {
2071
+ const referencePort = local?.reference ?? inherited.reference;
2072
+ const { email: emailPort, review: emailReview } = useReviewedTransferEmail(local?.email ?? inherited.email);
2073
+ const providerPreferences = React10.useMemo(() => (0, import_content_transfer3.resolveTransferPreferences)(inherited.preferences, local?.preferences), [inherited.preferences, local?.preferences]);
2074
+ const adapters = React10.useMemo(() => (0, import_content_transfer3.resolveTransferRegistry)(BUILT_INS, inherited.formats ?? [], local?.formats ?? []).filter((x) => "build" in x), [inherited.formats, local?.formats]);
2075
+ const emailJsonFormat = adapters.find((adapter) => adapter.id === "table-data");
2076
+ const emailActions = React10.useMemo(() => emailPort ? createTransferEmailActions(emailPort, emailJsonFormat ? { jsonFormat: emailJsonFormat } : {}) : [], [emailPort, emailJsonFormat]);
2077
+ const registeredActions = React10.useMemo(() => (0, import_content_transfer3.resolveTransferRegistry)(emailActions, inherited.actions ?? [], local?.actions ?? [], actions), [actions, emailActions, inherited.actions, local?.actions]);
2078
+ React10.useMemo(() => (0, import_content_transfer3.resolveTransferRegistry)(variants), [variants]);
2079
+ const report = React10.useCallback((result) => {
1845
2080
  inherited.onOutcome?.(result);
1846
2081
  local?.onOutcome?.(result);
1847
2082
  setNotice(outcomeMessage(result));
1848
2083
  setReceiptTarget("target" in result ? result.target : void 0);
1849
2084
  }, [inherited, local]);
1850
- React9.useEffect(() => {
1851
- const valid = /* @__PURE__ */ new Set([primaryWorkspaceKey, ...nearestWorkspaceKey ? [nearestWorkspaceKey] : [], ...variantWorkspaceKeys.values(), ...externalWorkspaceKeys.current]);
2085
+ React10.useEffect(() => {
2086
+ const valid = /* @__PURE__ */ new Set([...scopes.map((scope) => `${primaryWorkspaceBase}:${scope}`), ...nearestWorkspaceKey ? [nearestWorkspaceKey] : [], ...variantWorkspaceKeys.values(), ...externalWorkspaceKeys.current]);
1852
2087
  setWorkspaces((current) => Object.fromEntries(Object.entries(current).filter(([key]) => valid.has(key))));
1853
2088
  for (const key of workspaceCaptures.current.keys()) if (!valid.has(key)) workspaceCaptures.current.delete(key);
1854
2089
  if (workspaceKey && !valid.has(workspaceKey)) {
1855
2090
  setWorkspaceKey(null);
1856
2091
  setWorkspaceOpen(false);
1857
2092
  }
1858
- }, [nearestWorkspaceKey, primaryWorkspaceKey, variantWorkspaceKeys, workspaceKey]);
1859
- const captureOne = React9.useCallback(async (material, scope, signal, applyMenuProjection = false, collectPages = true) => {
2093
+ }, [nearestWorkspaceKey, primaryWorkspaceBase, scopes, variantWorkspaceKeys, workspaceKey]);
2094
+ const captureOne = React10.useCallback(async (material, scope, signal, applyMenuProjection = false, collectPages = true) => {
1860
2095
  if (!material) throw new Error("Alchemy needs a source or a mounted transfer surface.");
1861
2096
  let sourceMaterial;
1862
2097
  if ("instanceId" in material) {
@@ -1864,7 +2099,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1864
2099
  const captured = await material.capture(signal);
1865
2100
  sourceMaterial = { id: captured.snapshot.sourceId, label: captured.snapshot.label, capture: async () => captured };
1866
2101
  } else if ("kind" in material) {
1867
- sourceMaterial = { id: materialIdentity(material), label: sourceLabel, capture: async () => (0, import_content_transfer2.directSource)(material, { sourceId: materialIdentity(material), label: sourceLabel, ...applyMenuProjection && projection ? { projection } : {}, ...applyMenuProjection && sections ? { sections } : {} }) };
2102
+ sourceMaterial = { id: materialIdentity(material), label: sourceLabel, capture: async () => (0, import_content_transfer3.directSource)(material, { sourceId: materialIdentity(material), label: sourceLabel, ...applyMenuProjection && projection ? { projection } : {}, ...applyMenuProjection && sections ? { sections } : {} }) };
1868
2103
  } else if (applyMenuProjection && (projection || sections)) {
1869
2104
  sourceMaterial = {
1870
2105
  id: material.id,
@@ -1882,27 +2117,27 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1882
2117
  sourceMaterial = material;
1883
2118
  }
1884
2119
  const raw = await sourceMaterial.capture({ scope, signal });
1885
- const constrained = (0, import_content_transfer2.resolveTransferPreferences)(providerPreferences, preferences, raw.snapshot.limits);
1886
- const result = await (0, import_content_transfer2.capture)({ id: raw.snapshot.sourceId, label: raw.snapshot.label, capture: async () => ({ ...raw, snapshot: { ...raw.snapshot, limits: constrained.limits } }) }, signal, scope);
2120
+ const constrained = (0, import_content_transfer3.resolveTransferPreferences)(providerPreferences, preferences, raw.snapshot.limits);
2121
+ const result = await (0, import_content_transfer3.capture)({ id: raw.snapshot.sourceId, label: raw.snapshot.label, capture: async () => ({ ...raw, snapshot: { ...raw.snapshot, limits: constrained.limits } }) }, signal, scope);
1887
2122
  if (scope !== "all-matching" || !collectPages) return result;
1888
2123
  if (!result.allMatching) throw new Error("This source cannot provide a stable all-matching export.");
1889
- const collected = await (0, import_content_transfer2.collectAllMatching)(result.allMatching, signal);
2124
+ const collected = await (0, import_content_transfer3.collectAllMatching)(result.allMatching, signal);
1890
2125
  if (result.snapshot.payload.kind !== "rows") throw new Error("All-matching export requires tabular content.");
1891
- return { snapshot: (0, import_content_transfer2.projectSnapshot)({ ...result.snapshot, payload: { kind: "rows", rows: collected.rows, columns: result.snapshot.payload.columns }, coverage: collected.coverage, omissions: [...collected.omissions] }, { rules: [] }), allMatching: result.allMatching, ...collected.error ? { collectionError: collected.error.message } : {} };
2126
+ return { snapshot: (0, import_content_transfer3.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 } : {} };
1892
2127
  }, [preferences, projection, providerPreferences, sections, sourceLabel]);
1893
- const capturePrimary = React9.useCallback((scope, signal) => captureOne(primary, scope, signal, true), [captureOne, primary]);
2128
+ const capturePrimary = React10.useCallback((scope, signal) => captureOne(primary, scope, signal, true), [captureOne, primary]);
1894
2129
  workspaceCaptures.current.set(primaryWorkspaceKey, capturePrimary);
1895
2130
  if (nearestWorkspaceKey && nearestSurface) workspaceCaptures.current.set(nearestWorkspaceKey, (scope, signal) => captureOne(nearestSurface, scope, signal, true));
1896
2131
  for (const variant of variants) {
1897
2132
  const key = variantWorkspaceKeys.get(variant.id);
1898
2133
  workspaceCaptures.current.set(key, (scope, signal) => captureOne(variant.source, scope, signal, true));
1899
2134
  }
1900
- const preflight = React9.useCallback(async () => {
2135
+ const preflight = React10.useCallback(async (scope = initialScope) => {
1901
2136
  const { controller, id } = fence.begin();
1902
2137
  setMenuCapture(null);
1903
2138
  setMenuStatus("loading");
1904
2139
  try {
1905
- const result = await captureOne(primary, initialScope, controller.signal, true, false);
2140
+ const result = await captureOne(primary, scope, controller.signal, true, false);
1906
2141
  if (fence.valid(id, controller)) {
1907
2142
  setMenuCapture(result);
1908
2143
  setMenuStatus("idle");
@@ -1916,7 +2151,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1916
2151
  fence.finish(controller);
1917
2152
  }
1918
2153
  }, [captureOne, fence, initialScope, primary]);
1919
- const transfer = React9.useCallback(async (format, download, alternate) => {
2154
+ const transfer = React10.useCallback(async (format, download, alternate) => {
1920
2155
  const { controller, id } = fence.begin();
1921
2156
  try {
1922
2157
  const explicit = alternate?.source ?? (typeof format === "string" && format !== "xlsx" ? formatSources?.[format] : void 0);
@@ -1926,8 +2161,8 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1926
2161
  const reason = result.snapshot.coverage.reason ?? `${result.snapshot.omissions.length} omission${result.snapshot.omissions.length === 1 ? "" : "s"}`;
1927
2162
  throw new Error(`Quick transfer is partial (${reason}). Open Prepare for AI to review it before delivery.`);
1928
2163
  }
1929
- const resolved = (0, import_content_transfer2.resolveTransferPreferences)(providerPreferences, preferences, result.snapshot.limits);
1930
- const draft = (0, import_content_transfer2.applyTransferLimits)((0, import_content_transfer2.createDraft)(result.snapshot), resolved.limits);
2164
+ const resolved = (0, import_content_transfer3.resolveTransferPreferences)(providerPreferences, preferences, result.snapshot.limits);
2165
+ const draft = (0, import_content_transfer3.applyTransferLimits)((0, import_content_transfer3.createDraft)(result.snapshot), resolved.limits);
1931
2166
  const revision = draft.revision;
1932
2167
  if (draft.omissions.length > result.snapshot.omissions.length) throw new Error("Quick transfer requires content reductions. Open Prepare for AI to review them before delivery.");
1933
2168
  const artifact = typeof format === "string" ? await buildArtifact(draft, format, result.snapshot.label) : await format.build(draft, controller.signal);
@@ -1941,12 +2176,12 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1941
2176
  fence.finish(controller);
1942
2177
  }
1943
2178
  }, [captureOne, capturePrimary, fence, formatSources, initialScope, preferences, providerPreferences, report, transport]);
1944
- const openWorkspace = React9.useCallback(
2179
+ const openWorkspace = React10.useCallback(
1945
2180
  async (key = primaryWorkspaceKey, variant) => {
1946
2181
  const variantMaterial = variant && "kind" in variant.source ? {
1947
2182
  id: `variant:${key}`,
1948
2183
  label: variant.label,
1949
- capture: async () => (0, import_content_transfer2.directSource)(variant.source, {
2184
+ capture: async () => (0, import_content_transfer3.directSource)(variant.source, {
1950
2185
  sourceId: `variant:${key}`,
1951
2186
  label: variant.label
1952
2187
  })
@@ -1957,15 +2192,16 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1957
2192
  const { controller, id } = fence.begin();
1958
2193
  if (existing) {
1959
2194
  try {
1960
- const allMatching = existing.scope === "all-matching";
2195
+ const scopeChanged = existing.scope !== initialScope;
2196
+ const allMatching = initialScope === "all-matching";
1961
2197
  const fresh = await captureWorkspace(
1962
- existing.scope,
2198
+ initialScope,
1963
2199
  controller.signal,
1964
- !allMatching
2200
+ scopeChanged || !allMatching
1965
2201
  );
1966
2202
  if (!fence.valid(id, controller) || !workspaceCaptures.current.has(key))
1967
2203
  return;
1968
- if (allMatching && (!existing.allMatching || !fresh.allMatching))
2204
+ if (allMatching && (!fresh.allMatching || !scopeChanged && !existing.allMatching))
1969
2205
  throw new Error(
1970
2206
  "This source can no longer provide an all-matching snapshot."
1971
2207
  );
@@ -1975,7 +2211,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1975
2211
  columns: value.columns,
1976
2212
  limits: value.limits
1977
2213
  };
1978
- const changed = allMatching ? JSON.stringify(collectionIdentity(existing.allMatching)) !== JSON.stringify(collectionIdentity(fresh.allMatching)) : snapshotContent(existing.snapshot) !== snapshotContent(fresh.snapshot);
2214
+ const changed = scopeChanged || (allMatching ? JSON.stringify(collectionIdentity(existing.allMatching)) !== JSON.stringify(collectionIdentity(fresh.allMatching)) : snapshotContent(existing.snapshot) !== snapshotContent(fresh.snapshot));
1979
2215
  setWorkspaces((current) => {
1980
2216
  const retained = current[key];
1981
2217
  if (!retained) return current;
@@ -1984,7 +2220,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1984
2220
  [key]: {
1985
2221
  ...retained,
1986
2222
  error: fresh.collectionError,
1987
- ...allMatching ? { sourceStale: changed } : changed ? { pending: { ...fresh, scope: retained.scope } } : { pending: void 0 }
2223
+ ...allMatching && !scopeChanged ? { sourceStale: changed } : changed ? { pending: { ...fresh, scope: initialScope } } : { pending: void 0 }
1988
2224
  }
1989
2225
  };
1990
2226
  });
@@ -2012,12 +2248,12 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
2012
2248
  try {
2013
2249
  const result = await captureWorkspace(initialScope, controller.signal);
2014
2250
  if (!fence.valid(id, controller)) return;
2015
- const resolved = (0, import_content_transfer2.resolveTransferPreferences)(
2251
+ const resolved = (0, import_content_transfer3.resolveTransferPreferences)(
2016
2252
  providerPreferences,
2017
2253
  preferences,
2018
2254
  result.snapshot.limits
2019
2255
  );
2020
- const original = (0, import_content_transfer2.createDraft)(result.snapshot);
2256
+ const original = (0, import_content_transfer3.createDraft)(result.snapshot);
2021
2257
  const base = {
2022
2258
  ...result,
2023
2259
  key,
@@ -2053,7 +2289,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
2053
2289
  workspaces
2054
2290
  ]
2055
2291
  );
2056
- React9.useImperativeHandle(controllerRef, () => ({
2292
+ React10.useImperativeHandle(controllerRef, () => ({
2057
2293
  focusTrigger: () => triggerRef.current?.focus(),
2058
2294
  prepare: async (requestedSource, options) => {
2059
2295
  const requestedLabel = options?.label ?? ("label" in requestedSource ? requestedSource.label : "content");
@@ -2062,13 +2298,13 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
2062
2298
  await openWorkspace(requestedKey, { source: requestedSource, label: requestedLabel });
2063
2299
  }
2064
2300
  }), [openWorkspace]);
2065
- const runAction = React9.useCallback(async (action) => {
2301
+ const runAction = React10.useCallback(async (action) => {
2066
2302
  const { controller, id } = fence.begin();
2067
2303
  try {
2068
2304
  const actionSource = action.source;
2069
2305
  const { snapshot } = actionSource ? await captureOne(actionSource, initialScope, controller.signal, true) : await capturePrimary(initialScope, controller.signal);
2070
- const resolved = (0, import_content_transfer2.resolveTransferPreferences)(providerPreferences, preferences, snapshot.limits);
2071
- const draft = (0, import_content_transfer2.applyTransferLimits)((0, import_content_transfer2.createDraft)(snapshot), resolved.limits);
2306
+ const resolved = (0, import_content_transfer3.resolveTransferPreferences)(providerPreferences, preferences, snapshot.limits);
2307
+ const draft = (0, import_content_transfer3.applyTransferLimits)((0, import_content_transfer3.createDraft)(snapshot), resolved.limits);
2072
2308
  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.");
2073
2309
  if (!action.supports(snapshot, draft)) throw new Error(`${action.label} is unavailable for this content.`);
2074
2310
  const result = await action.run({ snapshot, draft, signal: controller.signal });
@@ -2079,13 +2315,38 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
2079
2315
  fence.finish(controller);
2080
2316
  }
2081
2317
  }, [captureOne, capturePrimary, fence, initialScope, preferences, providerPreferences, report]);
2318
+ const copyReference = async (reference) => {
2319
+ const { controller, id } = fence.begin();
2320
+ closePalette();
2321
+ try {
2322
+ if (!referencePort?.supports(reference)) throw new Error("This reference is not registered or its identity is incomplete.");
2323
+ const text = await referencePort.build(reference);
2324
+ if (!text.trim()) throw new Error("The reference serializer returned no content.");
2325
+ const artifact = (0, import_content_transfer3.sealTransferArtifact)({ snapshotId: `reference:${reference.id}`, draftRevision: 0, format: "matrx-reference", plainText: text, omissions: [] });
2326
+ if (!fence.valid(id, controller)) return;
2327
+ const outcome = await transport.copy(artifact, controller.signal);
2328
+ if (fence.valid(id, controller)) report(outcome);
2329
+ } catch (error) {
2330
+ if (fence.valid(id, controller)) report({ status: "error", code: "reference-failed", message: errorMessage(error, "Could not copy reference"), retryable: true });
2331
+ } finally {
2332
+ fence.finish(controller);
2333
+ }
2334
+ };
2335
+ const openReference = async (action) => {
2336
+ closePalette();
2337
+ try {
2338
+ await action.run();
2339
+ } catch (error) {
2340
+ report({ status: "error", code: "reference-failed", message: errorMessage(error, "Could not open reference picker"), retryable: true });
2341
+ }
2342
+ };
2082
2343
  if (!enabled) return null;
2083
2344
  const payload = menuCapture?.snapshot.payload ?? (source && "kind" in source ? source : void 0);
2084
2345
  const quickVariants = (section) => variants.filter((v) => v.copyLabel && (v.section ?? "ai") === section);
2085
2346
  const visibleCopies = sourceFormats ? COPIES.filter((f) => Boolean(formatSources?.[f]) || !["csv", "tsv"].includes(f) || payload?.kind === "rows") : [];
2086
2347
  const visibleDownloads = sourceFormats ? DOWNLOADS.filter((f) => f !== "xlsx" && Boolean(formatSources?.[f]) || !["csv", "tsv", "xlsx"].includes(f) || payload?.kind === "rows") : [];
2087
2348
  const visibleAdapters = sourceFormats && menuCapture ? adapters.filter((a) => a.supports(menuCapture.snapshot.payload)) : [];
2088
- const visibleActions = menuCapture ? registeredActions.filter((a) => a.supports(menuCapture.snapshot, (0, import_content_transfer2.applyTransferLimits)((0, import_content_transfer2.createDraft)(menuCapture.snapshot), (0, import_content_transfer2.resolveTransferPreferences)(providerPreferences, preferences, menuCapture.snapshot.limits).limits))) : [];
2349
+ const visibleActions = menuCapture ? registeredActions.filter((a) => a.supports(menuCapture.snapshot, (0, import_content_transfer3.applyTransferLimits)((0, import_content_transfer3.createDraft)(menuCapture.snapshot), (0, import_content_transfer3.resolveTransferPreferences)(providerPreferences, preferences, menuCapture.snapshot.limits).limits))) : [];
2089
2350
  const downloadActions = visibleActions.filter((action) => action.placement === "download");
2090
2351
  const ordinaryActions = visibleActions.filter((action) => action.placement !== "download");
2091
2352
  const preparedActions = registeredActions.filter((action) => action.prepared && !action.source);
@@ -2098,8 +2359,8 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
2098
2359
  label: "AI context",
2099
2360
  supports: () => true,
2100
2361
  build: async (draft) => {
2101
- const json = (0, import_content_transfer2.serialize)(draft, "json");
2102
- return (0, import_content_transfer2.sealTransferArtifact)({ snapshotId: draft.snapshotId, draftRevision: draft.revision, format: "ai-context", plainText: (0, import_content_transfer2.buildAgentPayload)({ kind: "matrx_content", location: sourceLabel, description: "Captured content for an assistant", data: JSON.parse(json.plainText), attributes: { source: draft.sourceId } }), omissions: [...json.omissions] });
2362
+ const json = (0, import_content_transfer3.serialize)(draft, "json");
2363
+ return (0, import_content_transfer3.sealTransferArtifact)({ snapshotId: draft.snapshotId, draftRevision: draft.revision, format: "ai-context", plainText: (0, import_content_transfer3.buildAgentPayload)({ kind: "matrx_content", location: sourceLabel, description: "Captured content for an assistant", data: JSON.parse(json.plainText), attributes: { source: draft.sourceId } }), omissions: [...json.omissions] });
2103
2364
  }
2104
2365
  };
2105
2366
  const closePalette = () => setPaletteOpen(false);
@@ -2107,106 +2368,123 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
2107
2368
  const presentation = options.action;
2108
2369
  const Icon = presentation?.icon;
2109
2370
  const fallbackLabel = options.file && !/^download\b/i.test(label2) ? `Download ${label2}` : label2;
2110
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-tile", "aria-label": presentation?.ariaLabel ?? (presentation ? fallbackLabel : options.ariaLabel ?? `${resolvedMode === "copy" ? "Copy" : "Download"} ${label2}`), onClick: () => {
2371
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-tile", "aria-label": presentation?.ariaLabel ?? (presentation ? fallbackLabel : options.ariaLabel ?? `${resolvedMode === "copy" ? "Copy" : "Download"} ${label2}`), onClick: () => {
2111
2372
  closePalette();
2112
2373
  onClick();
2113
2374
  }, children: [
2114
- Icon ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { ...!options.custom ? { format: id } : {}, ...options.ai ? { ai: true } : {}, ...options.file ? { file: true } : {} }),
2115
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
2375
+ Icon ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteGlyph, { ...!options.custom ? { format: id } : {}, ...options.ai ? { ai: true } : {}, ...options.file ? { file: true } : {} }),
2376
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
2116
2377
  label2,
2117
- presentation?.hint ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: presentation.hint }) : null
2378
+ presentation?.hint ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { className: "matrx-alchemy-menu-hint", children: presentation.hint }) : null
2118
2379
  ] })
2119
2380
  ] }, id);
2120
2381
  };
2121
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: cn("matrx-alchemy", className), onClick: stopPropagation ? (event) => event.stopPropagation() : void 0, children: [
2122
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Popover, { open: paletteOpen, onOpenChange: (open) => {
2382
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: cn("matrx-alchemy", className), onClick: stopPropagation ? (event) => event.stopPropagation() : void 0, children: [
2383
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Popover, { open: paletteOpen, onOpenChange: (open) => {
2123
2384
  setPaletteOpen(open);
2124
2385
  if (open) {
2125
2386
  setMode("copy");
2126
2387
  void preflight();
2127
2388
  }
2128
2389
  }, children: [
2129
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PopoverTrigger, { asChild: true, children: triggerVariant === "glass" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TapTargetButton, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "glass", disabled }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TapTargetButtonTransparent, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "transparent", disabled }) }),
2130
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(PopoverContent, { align: "end", className: "matrx-alchemy-menu matrx-alchemy-palette", "aria-label": "Alchemy output options", onCloseAutoFocus: () => triggerRef.current?.focus(), children: [
2131
- menuStatus === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "matrx-alchemy-palette-status", children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "matrx-alchemy-error", children: menuStatus }) : null,
2132
- copyAvailable || downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "matrx-alchemy-output", children: [
2133
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
2134
- copyAvailable && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
2135
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
2136
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
2390
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PopoverTrigger, { asChild: true, children: triggerVariant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { ref: triggerRef, variant: "outline", size: "icon-sm", "aria-label": `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "outline", disabled, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AlchemyGlyph, { icon }) }) : triggerVariant === "glass" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TapTargetButton, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "glass", "data-alchemy-size": triggerSize, disabled }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TapTargetButtonTransparent, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "transparent", "data-alchemy-size": triggerSize, disabled }) }),
2391
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(PopoverContent, { align: "end", className: "matrx-alchemy-menu matrx-alchemy-palette", "aria-label": "Alchemy output options", onCloseAutoFocus: () => triggerRef.current?.focus(), children: [
2392
+ menuStatus === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "matrx-alchemy-palette-status", children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "matrx-alchemy-error", children: menuStatus }) : null,
2393
+ table && scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "matrx-alchemy-scope", children: [
2394
+ "Content scope",
2395
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("select", { "aria-label": "Content scope", value: initialScope, onChange: (event) => {
2396
+ const next = scopes.find((scope) => scope === event.target.value);
2397
+ if (next) {
2398
+ setRequestedScope(next);
2399
+ void preflight(next);
2400
+ }
2401
+ }, children: scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: scope, children: table.scopeLabels?.[scope] ?? SCOPE_LABEL[scope] }, scope)) })
2402
+ ] }) : null,
2403
+ copyAvailable || downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("section", { className: "matrx-alchemy-output", children: [
2404
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
2405
+ copyAvailable && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
2406
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
2407
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
2137
2408
  ] }) : null,
2138
- resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2139
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
2409
+ resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2410
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
2140
2411
  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]}` })),
2141
2412
  visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, false), { custom: true }))
2142
2413
  ] }),
2143
- quickVariants("copy").length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
2414
+ quickVariants("copy").length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
2144
2415
  closePalette();
2145
2416
  void transfer("markdown", false, variant);
2146
2417
  } }) : null
2147
2418
  ] }) : null,
2148
- resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
2419
+ resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
2149
2420
  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]}` })),
2150
2421
  visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, true), { custom: true })),
2151
2422
  downloadActions.map((action) => tile(action.id, action.label, () => void runAction(action), { custom: true, action, file: true }))
2152
2423
  ] }) }) : null
2153
2424
  ] }) : null,
2154
- prepareAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2155
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", extra: sourceFormats ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
2425
+ prepareAvailable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2426
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", extra: sourceFormats ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
2156
2427
  closePalette();
2157
2428
  void transfer(nativeAiFormat, false);
2158
2429
  }, children: [
2159
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { kind: "ai-copy" }),
2160
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
2430
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteGlyph, { kind: "ai-copy" }),
2431
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
2161
2432
  "Copy with AI context",
2162
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Content, source and capture details" })
2433
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Content, source and capture details" })
2163
2434
  ] })
2164
2435
  ] }) : null, items: quickVariants("ai"), onRun: (variant) => {
2165
2436
  closePalette();
2166
2437
  void transfer("markdown", false, variant);
2167
2438
  } }),
2168
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Edit and prepare", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": "Prepare for AI", onClick: () => {
2439
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteRows, { title: "Edit and prepare", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": "Prepare for AI", onClick: () => {
2169
2440
  closePalette();
2170
2441
  void openWorkspace();
2171
2442
  }, children: [
2172
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { kind: "sliders" }),
2173
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
2443
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteGlyph, { kind: "sliders" }),
2444
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
2174
2445
  "Prepare for AI",
2175
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Review and edit before copying" })
2446
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Review and edit before copying" })
2176
2447
  ] })
2177
2448
  ] }) })
2178
2449
  ] }) : null,
2179
- prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Other sources", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2180
- nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
2450
+ prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteRows, { title: "Other sources", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2451
+ nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
2181
2452
  closePalette();
2182
2453
  void openWorkspace(nearestWorkspaceKey, { source: nearestSurface, label: nearestSurface.surfaceName });
2183
- }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Prepare this surface" }) }) : null,
2184
- variants.map((variant) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
2454
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Prepare this surface" }) }) : null,
2455
+ variants.map((variant) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
2185
2456
  closePalette();
2186
2457
  void openWorkspace(variantWorkspaceKeys.get(variant.id), variant);
2187
- }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
2458
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
2188
2459
  ] }) }) : null,
2189
- ["save", "chat", "other"].map((group) => {
2460
+ references.length || referenceActions.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
2461
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { children: "Live references" }),
2462
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "matrx-alchemy-menu-hint", children: "Pointers to saved data, independent of filters and edits." }),
2463
+ references.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => void copyReference(reference), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: reference.label }) }, reference.id)),
2464
+ referenceActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => void openReference(action), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: action.label }) }, action.id))
2465
+ ] }) : null,
2466
+ ["save", "chat", "email", "other"].map((group) => {
2190
2467
  const entries = ordinaryActions.filter((action) => (action.group ?? "other") === group);
2191
- return entries.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-palette-destinations", children: [
2192
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
2193
- group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : "Actions",
2194
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: entries.length })
2468
+ return entries.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("details", { className: "matrx-alchemy-palette-destinations", children: [
2469
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { children: [
2470
+ group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : group === "email" ? "Email to me" : "Actions",
2471
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: entries.length })
2195
2472
  ] }),
2196
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { children: entries.map((action) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
2473
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { children: entries.map((action) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
2197
2474
  closePalette();
2198
2475
  void runAction(action);
2199
- }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DestinationPresentation, { action }) }, action.id)) })
2476
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DestinationPresentation, { action }) }, action.id)) })
2200
2477
  ] }, group) : null;
2201
2478
  })
2202
2479
  ] })
2203
2480
  ] }),
2204
- notice && triggerRef.current ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-feedback", children: [
2205
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { role: "status", children: notice }),
2206
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ReceiptLink, { target: receiptTarget }),
2207
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": "Dismiss Alchemy feedback", onClick: () => setNotice(null), children: "\xD7" })
2481
+ notice && triggerRef.current ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-feedback", children: [
2482
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { role: "status", children: notice }),
2483
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ReceiptLink, { target: receiptTarget }),
2484
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-label": "Dismiss Alchemy feedback", onClick: () => setNotice(null), children: "\xD7" })
2208
2485
  ] }), triggerRef.current.ownerDocument.body) : null,
2209
- Object.values(workspaces).map((saved) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PreparationWorkspace, { restoreFocus: () => triggerRef.current?.focus(), open: workspaceOpen && workspaceKey === saved.key, state: saved, scopes, onClose: () => setWorkspaceOpen(false), onChange: (next) => setWorkspaces((current) => ({ ...current, [saved.key]: next })), transport, adapters, actions: preparedActions, captureScope: workspaceCaptures.current.get(saved.key) ?? capturePrimary, ...ai ? { ai } : {}, onOutcome: report }, saved.key))
2486
+ Object.values(workspaces).map((saved) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PreparationWorkspace, { restoreFocus: () => triggerRef.current?.focus(), open: workspaceOpen && workspaceKey === saved.key, state: saved, scopes, scopeLabels: table?.scopeLabels, 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)),
2487
+ emailReview
2210
2488
  ] });
2211
2489
  }
2212
2490
  function initialControls(state) {
@@ -2234,9 +2512,9 @@ function presetLimits(preset, controls, preferences) {
2234
2512
  return { ...preferences.limits, maxDepth: min(request.maxDepth, preferences.limits.maxDepth), maxStringChars: min(request.maxStringChars, preferences.limits.maxStringChars), maxArrayItems: min(request.maxArrayItems, preferences.limits.maxArrayItems ?? null) };
2235
2513
  }
2236
2514
  function rebuild(state, controls) {
2237
- let draft = (0, import_content_transfer2.resetDraft)(state.snapshot);
2238
- if (state.snapshot.sections.length) draft = (0, import_content_transfer2.applySectionSelection)(draft, state.snapshot, controls.sections);
2239
- if (draft.payload.kind === "rows") draft = (0, import_content_transfer2.transformRows)(draft, {
2515
+ let draft = (0, import_content_transfer3.resetDraft)(state.snapshot);
2516
+ if (state.snapshot.sections.length) draft = (0, import_content_transfer3.applySectionSelection)(draft, state.snapshot, controls.sections);
2517
+ if (draft.payload.kind === "rows") draft = (0, import_content_transfer3.transformRows)(draft, {
2240
2518
  search: controls.search,
2241
2519
  filters: controls.filters,
2242
2520
  ...controls.sort ? { sort: { column: controls.sort, direction: controls.direction } } : {},
@@ -2247,45 +2525,45 @@ function rebuild(state, controls) {
2247
2525
  });
2248
2526
  const limits = presetLimits(controls.preset, controls, state.preferences);
2249
2527
  if (draft.payload.kind === "json" || draft.payload.kind === "registered") {
2250
- draft = (0, import_content_transfer2.reduceJson)(draft, { maxDepth: limits.maxDepth, maxStringChars: limits.maxStringChars, maxArrayItems: limits.maxArrayItems ?? null });
2528
+ draft = (0, import_content_transfer3.reduceJson)(draft, { maxDepth: limits.maxDepth, maxStringChars: limits.maxStringChars, maxArrayItems: limits.maxArrayItems ?? null });
2251
2529
  }
2252
- return (0, import_content_transfer2.applyTransferLimits)(draft, limits);
2530
+ return (0, import_content_transfer3.applyTransferLimits)(draft, limits);
2253
2531
  }
2254
2532
  function isBuiltInFormat(format) {
2255
2533
  return format in LABEL;
2256
2534
  }
2257
2535
  function preview(draft, format) {
2258
2536
  const resolved = isBuiltInFormat(format) ? format : "plain";
2259
- return (0, import_content_transfer2.serialize)(draft, resolved === "xlsx" ? "tsv" : resolved, { spreadsheetSafe: resolved === "csv" || resolved === "tsv" || resolved === "xlsx" }).plainText;
2537
+ return (0, import_content_transfer3.serialize)(draft, resolved === "xlsx" ? "tsv" : resolved, { spreadsheetSafe: resolved === "csv" || resolved === "tsv" || resolved === "xlsx" }).plainText;
2260
2538
  }
2261
- function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onChange, transport, ai, adapters, actions, onOutcome, captureScope }) {
2539
+ function PreparationWorkspace({ restoreFocus, open, state, scopes, scopeLabels, onClose, onChange, transport, ai, adapters, actions, onOutcome, captureScope }) {
2262
2540
  const fence = useFence();
2263
- const latest = React9.useRef(state);
2541
+ const latest = React10.useRef(state);
2264
2542
  latest.current = state;
2265
- const aiSession = React9.useRef(void 0);
2543
+ const aiSession = React10.useRef(void 0);
2266
2544
  if (!aiSession.current && ai) aiSession.current = ai.fork?.() ?? ai;
2267
- const [controls, setControls] = React9.useState(() => initialControls(state));
2268
- const [controlsHistory, setControlsHistory] = React9.useState([]);
2269
- const [pendingControls, setPendingControls] = React9.useState(null);
2545
+ const [controls, setControls] = React10.useState(() => initialControls(state));
2546
+ const [controlsHistory, setControlsHistory] = React10.useState([]);
2547
+ const [pendingControls, setPendingControls] = React10.useState(null);
2270
2548
  const requestedFormat = state.preferences.initialFormat;
2271
- 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");
2272
- const [buffer, setBuffer] = React9.useState(() => isBuiltInFormat(format) ? preview(state.draft, format) : "Preparing format preview\u2026");
2273
- const [bufferError, setBufferError] = React9.useState(null);
2274
- const [formatError, setFormatError] = React9.useState(null);
2275
- const [preparedArtifact, setPreparedArtifact] = React9.useState(null);
2276
- const [instruction, setInstruction] = React9.useState("");
2277
- const [busy, setBusy] = React9.useState(null);
2278
- const [aiFailed, setAiFailed] = React9.useState(false);
2279
- React9.useEffect(() => {
2549
+ const [format, setFormat] = React10.useState(() => isBuiltInFormat(requestedFormat) ? supportsBuiltIn(requestedFormat, state.draft.payload) ? requestedFormat : "plain" : adapters.some((adapter) => adapter.id === requestedFormat && adapter.supports(state.draft.payload)) ? requestedFormat : "plain");
2550
+ const [buffer, setBuffer] = React10.useState(() => isBuiltInFormat(format) ? preview(state.draft, format) : "Preparing format preview\u2026");
2551
+ const [bufferError, setBufferError] = React10.useState(null);
2552
+ const [formatError, setFormatError] = React10.useState(null);
2553
+ const [preparedArtifact, setPreparedArtifact] = React10.useState(null);
2554
+ const [instruction, setInstruction] = React10.useState("");
2555
+ const [busy, setBusy] = React10.useState(null);
2556
+ const [aiFailed, setAiFailed] = React10.useState(false);
2557
+ React10.useEffect(() => {
2280
2558
  setAiFailed(false);
2281
2559
  }, [state.snapshot.id, state.draft.revision]);
2282
- const handingOff = React9.useRef(false);
2283
- React9.useEffect(() => {
2560
+ const handingOff = React10.useRef(false);
2561
+ React10.useEffect(() => {
2284
2562
  if (open) handingOff.current = false;
2285
2563
  }, [open]);
2286
- const activeAi = React9.useRef(null);
2287
- const activeCapture = React9.useRef(null);
2288
- React9.useEffect(() => {
2564
+ const activeAi = React10.useRef(null);
2565
+ const activeCapture = React10.useRef(null);
2566
+ React10.useEffect(() => {
2289
2567
  if (bufferError) return;
2290
2568
  const adapter = adapters.find((candidate) => candidate.id === format);
2291
2569
  const controller = new AbortController();
@@ -2305,7 +2583,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
2305
2583
  });
2306
2584
  return () => controller.abort();
2307
2585
  }, [adapters, bufferError, format, state.draft, state.snapshot.id]);
2308
- const close = React9.useCallback(() => {
2586
+ const close = React10.useCallback(() => {
2309
2587
  activeAi.current?.abort();
2310
2588
  activeCapture.current?.abort();
2311
2589
  activeAi.current = null;
@@ -2341,7 +2619,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
2341
2619
  const value = JSON.parse(text);
2342
2620
  const next = payload.kind === "json" ? { kind: "json", value } : { kind: "registered", format: payload.format, value };
2343
2621
  setBufferError(null);
2344
- onChange({ ...state, draft: (0, import_content_transfer2.editDraft)(state.draft, next), error: void 0 });
2622
+ onChange({ ...state, draft: (0, import_content_transfer3.editDraft)(state.draft, next), error: void 0 });
2345
2623
  } catch {
2346
2624
  setBufferError("JSON is incomplete or invalid. Fix it before copying or downloading.");
2347
2625
  }
@@ -2350,7 +2628,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
2350
2628
  setBufferError(null);
2351
2629
  const kind = payload.kind === "markdown" || format === "markdown" ? "markdown" : "text";
2352
2630
  if (payload.kind === "rows" || !isBuiltInFormat(format)) setFormat("plain");
2353
- onChange({ ...state, draft: (0, import_content_transfer2.editDraft)(state.draft, { kind, text }), error: void 0 });
2631
+ onChange({ ...state, draft: (0, import_content_transfer3.editDraft)(state.draft, { kind, text }), error: void 0 });
2354
2632
  };
2355
2633
  const requestCapture = async (scope) => {
2356
2634
  activeCapture.current?.abort();
@@ -2377,8 +2655,8 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
2377
2655
  return;
2378
2656
  }
2379
2657
  const pending = state.pending;
2380
- const preferences = (0, import_content_transfer2.resolveTransferPreferences)({}, state.preferences, pending.snapshot.limits);
2381
- const base = { ...pending, key: state.key, original: (0, import_content_transfer2.createDraft)(pending.snapshot), draft: (0, import_content_transfer2.createDraft)(pending.snapshot), scope: pending.scope, preferences, ...pending.collectionError ? { error: pending.collectionError } : {} };
2658
+ const preferences = (0, import_content_transfer3.resolveTransferPreferences)({}, state.preferences, pending.snapshot.limits);
2659
+ const base = { ...pending, key: state.key, original: (0, import_content_transfer3.createDraft)(pending.snapshot), draft: (0, import_content_transfer3.createDraft)(pending.snapshot), scope: pending.scope, preferences, ...pending.collectionError ? { error: pending.collectionError } : {} };
2382
2660
  const nextControls = initialControls(base);
2383
2661
  setControls(nextControls);
2384
2662
  setControlsHistory([]);
@@ -2401,7 +2679,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
2401
2679
  const current = latest.current;
2402
2680
  if (!fence.valid(id, controller) || current.snapshot.id !== snapshotId || current.draft.revision !== revision || next.snapshotId !== snapshotId || next.sourceId !== state.draft.sourceId || next.sourceRevision !== state.draft.sourceRevision || next.revision <= revision) return;
2403
2681
  try {
2404
- (0, import_content_transfer2.serialize)(next, "plain");
2682
+ (0, import_content_transfer3.serialize)(next, "plain");
2405
2683
  } catch {
2406
2684
  onChange({ ...current, error: "AI returned an invalid transfer draft." });
2407
2685
  setAiFailed(true);
@@ -2434,8 +2712,8 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
2434
2712
  if (fence.valid(id, controller)) setBusy(null);
2435
2713
  }
2436
2714
  };
2437
- const [deliveryNotice, setDeliveryNotice] = React9.useState(null);
2438
- React9.useEffect(() => {
2715
+ const [deliveryNotice, setDeliveryNotice] = React10.useState(null);
2716
+ React10.useEffect(() => {
2439
2717
  setDeliveryNotice(null);
2440
2718
  }, [state.draft.revision]);
2441
2719
  const reportDelivery = (outcome) => {
@@ -2486,49 +2764,49 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
2486
2764
  const workspaceAdapters = adapters.filter((adapter) => adapter.supports(state.draft.payload));
2487
2765
  const displayedOmissions = preparedArtifact?.omissions ?? state.draft.omissions;
2488
2766
  const limitText = Object.entries(state.preferences.limits).filter(([, value]) => value != null).map(([key, value]) => `${key.replace(/^max/, "max ")} ${(0, import_format2.formatCount)(Number(value))}`).join(" \xB7 ");
2489
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Dialog, { open, onOpenChange: (next) => {
2767
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Dialog, { open, onOpenChange: (next) => {
2490
2768
  if (!next) close();
2491
- }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogContent, { onCloseAutoFocus: (event) => {
2769
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogContent, { onCloseAutoFocus: (event) => {
2492
2770
  event.preventDefault();
2493
2771
  if (!handingOff.current) restoreFocus();
2494
2772
  }, className: "matrx-alchemy-workspace max-w-5xl", "aria-busy": busy !== null, children: [
2495
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogHeader, { children: [
2496
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogTitle, { children: [
2773
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogHeader, { children: [
2774
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogTitle, { children: [
2497
2775
  "Prepare ",
2498
2776
  state.snapshot.label
2499
2777
  ] }),
2500
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogDescription, { children: [
2778
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogDescription, { children: [
2501
2779
  state.snapshot.unsavedChanges ? "Includes your unsaved changes. " : "",
2502
2780
  "Review and edit this copy. Your original stays unchanged."
2503
2781
  ] })
2504
2782
  ] }),
2505
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
2506
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-workspace-grid", children: [
2507
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "matrx-alchemy-main", children: [
2508
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
2509
- scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2783
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
2784
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-workspace-grid", children: [
2785
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("section", { className: "matrx-alchemy-main", children: [
2786
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
2787
+ scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
2510
2788
  "Scope",
2511
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("select", { "aria-label": "Transfer scope", value: state.scope, disabled: busy !== null, onChange: (e) => void requestCapture(e.target.value), children: scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: scope, children: SCOPE_LABEL[scope] }, scope)) })
2789
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("select", { "aria-label": "Transfer scope", value: state.scope, disabled: busy !== null, onChange: (e) => void requestCapture(e.target.value), children: scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: scope, children: scopeLabels?.[scope] ?? SCOPE_LABEL[scope] }, scope)) })
2512
2790
  ] }) : null,
2513
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2791
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
2514
2792
  "Detail",
2515
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { "aria-label": "Detail preset", value: controls.preset, onChange: (e) => changeControls({ ...controls, preset: e.target.value }), children: [
2516
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "full", children: "Full" }),
2517
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "compact", children: "Compact" }),
2518
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "brief", children: "Brief" }),
2519
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "custom", children: "Custom" })
2793
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("select", { "aria-label": "Detail preset", value: controls.preset, onChange: (e) => changeControls({ ...controls, preset: e.target.value }), children: [
2794
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "full", children: "Full" }),
2795
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "compact", children: "Compact" }),
2796
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "brief", children: "Brief" }),
2797
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "custom", children: "Custom" })
2520
2798
  ] })
2521
2799
  ] }),
2522
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: !state.draft.history?.length && !controlsHistory.length || busy !== null, onClick: () => {
2800
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: !state.draft.history?.length && !controlsHistory.length || busy !== null, onClick: () => {
2523
2801
  setBufferError(null);
2524
2802
  if (controlsHistory.length) {
2525
2803
  const next = controlsHistory[controlsHistory.length - 1];
2526
2804
  setControls(next);
2527
2805
  setControlsHistory((history) => history.slice(0, -1));
2528
2806
  onChange({ ...state, draft: rebuild(state, next), error: void 0 });
2529
- } else onChange({ ...state, draft: (0, import_content_transfer2.undoDraft)(state.draft), error: void 0 });
2807
+ } else onChange({ ...state, draft: (0, import_content_transfer3.undoDraft)(state.draft), error: void 0 });
2530
2808
  }, children: "Undo" }),
2531
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => {
2809
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => {
2532
2810
  const next = initialControls(state);
2533
2811
  setControls(next);
2534
2812
  setControlsHistory([]);
@@ -2536,64 +2814,64 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
2536
2814
  setBufferError(null);
2537
2815
  onChange({ ...state, draft: rebuild(state, next), error: void 0 });
2538
2816
  }, children: "Reset" }),
2539
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => void requestCapture(state.scope), children: "Refresh source" })
2817
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => void requestCapture(state.scope), children: "Refresh source" })
2540
2818
  ] }),
2541
- controls.preset === "custom" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("fieldset", { className: "matrx-alchemy-options", children: [
2542
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("legend", { children: state.draft.payload.kind === "json" || state.draft.payload.kind === "registered" ? "JSON limits" : "Content limits" }),
2543
- [["maxDepth", "Maximum depth"], ["maxStringChars", state.draft.payload.kind === "rows" ? "Maximum characters per cell" : "Maximum string characters"], ["maxArrayItems", "Maximum array items"]].filter(([key]) => key === "maxStringChars" || state.draft.payload.kind === "json" || state.draft.payload.kind === "registered").map(([key, text]) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2819
+ controls.preset === "custom" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("fieldset", { className: "matrx-alchemy-options", children: [
2820
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("legend", { children: state.draft.payload.kind === "json" || state.draft.payload.kind === "registered" ? "JSON limits" : "Content limits" }),
2821
+ [["maxDepth", "Maximum depth"], ["maxStringChars", state.draft.payload.kind === "rows" ? "Maximum characters per cell" : "Maximum string characters"], ["maxArrayItems", "Maximum array items"]].filter(([key]) => key === "maxStringChars" || state.draft.payload.kind === "json" || state.draft.payload.kind === "registered").map(([key, text]) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
2544
2822
  text,
2545
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "number", min: "0", value: controls[key] ?? "", onChange: (e) => changeControls({ ...controls, [key]: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
2823
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "number", min: "0", value: controls[key] ?? "", onChange: (e) => changeControls({ ...controls, [key]: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
2546
2824
  ] }, key))
2547
2825
  ] }) : null,
2548
- rows ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-data-controls", children: [
2549
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
2826
+ rows ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-data-controls", children: [
2827
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { children: [
2550
2828
  "Data selection \xB7 ",
2551
2829
  controls.visibleColumns.length,
2552
2830
  " columns",
2553
2831
  controls.search || controls.sort || controls.top != null || controls.selectedOnly || Object.values(controls.filters).some(Boolean) ? " \xB7 customized" : " \xB7 all rows"
2554
2832
  ] }),
2555
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "matrx-alchemy-data-controls-body", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RowControls, { rows, controls, change: changeControls }) })
2833
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "matrx-alchemy-data-controls-body", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RowControls, { rows, controls, change: changeControls }) })
2556
2834
  ] }) : null,
2557
- state.snapshot.sections.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options", children: [
2558
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
2835
+ state.snapshot.sections.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("details", { className: "matrx-alchemy-options", children: [
2836
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { children: [
2559
2837
  "Sections \xB7 ",
2560
2838
  controls.sections.length,
2561
2839
  " included"
2562
2840
  ] }),
2563
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("fieldset", { "aria-label": "Included sections", children: state.snapshot.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2564
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: controls.sections.includes(section.id), onChange: (e) => changeControls({ ...controls, sections: e.target.checked ? [...controls.sections, section.id] : controls.sections.filter((id) => id !== section.id) }) }),
2841
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("fieldset", { "aria-label": "Included sections", children: state.snapshot.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
2842
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "checkbox", checked: controls.sections.includes(section.id), onChange: (e) => changeControls({ ...controls, sections: e.target.checked ? [...controls.sections, section.id] : controls.sections.filter((id) => id !== section.id) }) }),
2565
2843
  " ",
2566
2844
  section.label
2567
2845
  ] }, section.id)) })
2568
2846
  ] }) : null,
2569
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "matrx-alchemy-preview-label", children: [
2847
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "matrx-alchemy-preview-label", children: [
2570
2848
  "Output format",
2571
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { "aria-label": "Output format", value: format, onChange: (e) => setFormat(e.target.value), children: [
2572
- formats.map((f) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: f, children: LABEL[f] }, f)),
2573
- state.draft.payload.kind === "rows" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "xlsx", children: "Excel workbook" }) : null,
2574
- workspaceAdapters.map((adapter) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: adapter.id, children: adapter.label }, adapter.id))
2849
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("select", { "aria-label": "Output format", value: format, onChange: (e) => setFormat(e.target.value), children: [
2850
+ formats.map((f) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: f, children: LABEL[f] }, f)),
2851
+ state.draft.payload.kind === "rows" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "xlsx", children: "Excel workbook" }) : null,
2852
+ workspaceAdapters.map((adapter) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: adapter.id, children: adapter.label }, adapter.id))
2575
2853
  ] })
2576
2854
  ] }),
2577
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("textarea", { className: "matrx-alchemy-preview", "aria-label": "Prepared output", "aria-invalid": bufferError ? true : void 0, "aria-describedby": bufferError ? "alchemy-buffer-error" : void 0, value: buffer, onChange: (e) => editBuffer(e.target.value) }),
2578
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-coverage", children: [
2579
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
2855
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("textarea", { className: "matrx-alchemy-preview", "aria-label": "Prepared output", "aria-invalid": bufferError ? true : void 0, "aria-describedby": bufferError ? "alchemy-buffer-error" : void 0, value: buffer, onChange: (e) => editBuffer(e.target.value) }),
2856
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-coverage", children: [
2857
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
2580
2858
  state.snapshot.coverage.included.toLocaleString(),
2581
2859
  " included",
2582
2860
  state.snapshot.coverage.total == null ? "" : ` of ${state.snapshot.coverage.total.toLocaleString()}`,
2583
2861
  " \xB7 ",
2584
2862
  state.snapshot.coverage.status
2585
2863
  ] }),
2586
- state.snapshot.coverage.reason ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: state.snapshot.coverage.reason }) : null,
2587
- limitText ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
2864
+ state.snapshot.coverage.reason ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: state.snapshot.coverage.reason }) : null,
2865
+ limitText ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
2588
2866
  "Limits: ",
2589
2867
  limitText
2590
2868
  ] }) : null,
2591
- displayedOmissions.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { children: [
2592
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
2869
+ displayedOmissions.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("details", { children: [
2870
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { children: [
2593
2871
  displayedOmissions.length,
2594
2872
  " omissions or adjustments"
2595
2873
  ] }),
2596
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { children: displayedOmissions.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("li", { children: [
2874
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { children: displayedOmissions.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("li", { children: [
2597
2875
  o.path || "/",
2598
2876
  ": ",
2599
2877
  o.reason,
@@ -2601,79 +2879,86 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
2601
2879
  ] }, `${o.path}-${o.reason}-${i}`)) })
2602
2880
  ] }) : null
2603
2881
  ] }),
2604
- bufferError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { id: "alchemy-buffer-error", role: "alert", className: "matrx-alchemy-error", children: bufferError }) : null,
2605
- formatError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: formatError }) : null,
2606
- bufferError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: busy !== null, onClick: () => {
2607
- const fallback = (0, import_content_transfer2.editDraft)(state.draft, { kind: "text", text: buffer });
2882
+ bufferError ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { id: "alchemy-buffer-error", role: "alert", className: "matrx-alchemy-error", children: bufferError }) : null,
2883
+ formatError ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: formatError }) : null,
2884
+ bufferError ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: busy !== null, onClick: () => {
2885
+ const fallback = (0, import_content_transfer3.editDraft)(state.draft, { kind: "text", text: buffer });
2608
2886
  setBufferError(null);
2609
2887
  onChange({ ...state, draft: fallback, error: void 0 });
2610
2888
  setFormat("plain");
2611
2889
  }, children: "Use invalid JSON as plain text" }) : null
2612
2890
  ] }),
2613
- ai || busy === "capture" || state.error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("aside", { children: [
2614
- ai ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2615
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2891
+ ai || busy === "capture" || state.error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("aside", { children: [
2892
+ ai ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2893
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
2616
2894
  "Start with",
2617
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { "aria-label": "AI preparation recipe", defaultValue: "", onChange: (event) => {
2895
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("select", { "aria-label": "AI preparation recipe", defaultValue: "", onChange: (event) => {
2618
2896
  if (event.target.value) setInstruction(event.target.value);
2619
2897
  }, children: [
2620
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "Choose an instruction" }),
2621
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Summarize this content concisely. Preserve important facts, names, decisions, and source references.", children: "Summarize" }),
2622
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Extract decisions, action items, owners, and due dates. Mark missing details as unspecified.", children: "Extract action items" }),
2623
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Prepare a complete handoff for another assistant. Include the objective, relevant facts, constraints, decisions, and unresolved questions.", children: "Assistant handoff" }),
2624
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Condense this content by removing repetition and formatting noise. Preserve every unique fact and all identifiers.", children: "Condense without losing facts" }),
2625
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Turn this content into a clear structured outline. Keep the original meaning and explicitly flag uncertainty.", children: "Create an outline" }),
2626
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Analyze this data. Identify patterns, anomalies, and useful comparisons. Distinguish observations from inferences.", children: "Analyze the data" })
2898
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "", children: "Choose an instruction" }),
2899
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "Summarize this content concisely. Preserve important facts, names, decisions, and source references.", children: "Summarize" }),
2900
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "Extract decisions, action items, owners, and due dates. Mark missing details as unspecified.", children: "Extract action items" }),
2901
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "Prepare a complete handoff for another assistant. Include the objective, relevant facts, constraints, decisions, and unresolved questions.", children: "Assistant handoff" }),
2902
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "Condense this content by removing repetition and formatting noise. Preserve every unique fact and all identifiers.", children: "Condense without losing facts" }),
2903
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "Turn this content into a clear structured outline. Keep the original meaning and explicitly flag uncertainty.", children: "Create an outline" }),
2904
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "Analyze this data. Identify patterns, anomalies, and useful comparisons. Distinguish observations from inferences.", children: "Analyze the data" })
2627
2905
  ] })
2628
2906
  ] }),
2629
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2907
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
2630
2908
  "AI instruction",
2631
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value), placeholder: "Tell AI how to prepare this content" })
2909
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value), placeholder: "Tell AI how to prepare this content" })
2632
2910
  ] }),
2633
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: !aiSession.current || !instruction.trim() || busy !== null || !aiSession.current.supports(state.snapshot), onClick: () => void runAi(false), children: "Generate preview" }),
2634
- busy === "ai" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void cancelAi(), children: aiSession.current?.cancel ? "Cancel AI" : "Stop waiting" }) : null
2911
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: !aiSession.current || !instruction.trim() || busy !== null || !aiSession.current.supports(state.snapshot), onClick: () => void runAi(false), children: "Generate preview" }),
2912
+ busy === "ai" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void cancelAi(), children: aiSession.current?.cancel ? "Cancel AI" : "Stop waiting" }) : null
2635
2913
  ] }) : null,
2636
- busy === "capture" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => {
2914
+ busy === "capture" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => {
2637
2915
  activeCapture.current?.abort();
2638
2916
  activeCapture.current = null;
2639
2917
  setBusy(null);
2640
2918
  }, children: "Stop loading rows" }) : null,
2641
- ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
2642
- ai ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "matrx-alchemy-meta", children: "AI updates the preview; copy it when you are ready. Closing this window lets the AI run continue." }) : null,
2643
- state.error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
2919
+ ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
2920
+ ai ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "matrx-alchemy-meta", children: "AI updates the preview; copy it when you are ready. Closing this window lets the AI run continue." }) : null,
2921
+ state.error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
2644
2922
  ] }) : null
2645
2923
  ] }),
2646
- pendingControls ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
2647
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "This control would replace your manual edit." }),
2648
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
2649
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
2924
+ pendingControls ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
2925
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: "This control would replace your manual edit." }),
2926
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
2927
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
2650
2928
  ] }) : null,
2651
- state.sourceStale ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
2652
- state.pending ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
2653
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "A fresh source snapshot is ready." }),
2654
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
2655
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: () => resolveCapture("regenerate"), children: "Regenerate from fresh source" })
2929
+ state.sourceStale ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
2930
+ state.pending ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
2931
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: "A fresh source snapshot is ready." }),
2932
+ state.pending.scope !== state.scope ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { children: [
2933
+ "Switch from ",
2934
+ scopeLabels?.[state.scope] ?? SCOPE_LABEL[state.scope],
2935
+ " to ",
2936
+ scopeLabels?.[state.pending.scope] ?? SCOPE_LABEL[state.pending.scope],
2937
+ " by regenerating. Your current draft is retained until you choose."
2938
+ ] }) : null,
2939
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
2940
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: () => resolveCapture("regenerate"), children: "Regenerate from fresh source" })
2656
2941
  ] }) : null,
2657
- eligibleActions.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-destinations", children: [
2658
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
2942
+ eligibleActions.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-destinations", children: [
2943
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { children: [
2659
2944
  "Use prepared content \xB7 ",
2660
2945
  eligibleActions.length,
2661
2946
  " destinations"
2662
2947
  ] }),
2663
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "matrx-alchemy-destination-grid", children: eligibleActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliverAction(action), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DestinationPresentation, { action }) }, action.id)) })
2948
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "matrx-alchemy-destination-grid", children: eligibleActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliverAction(action), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DestinationPresentation, { action }) }, action.id)) })
2664
2949
  ] }) : null,
2665
- deliveryNotice ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "status", className: "matrx-alchemy-meta", children: deliveryNotice }) : null
2950
+ deliveryNotice ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "status", className: "matrx-alchemy-meta", children: deliveryNotice }) : null
2666
2951
  ] }),
2667
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogFooter, { children: [
2668
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "matrx-alchemy-meta", children: [
2952
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogFooter, { children: [
2953
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "matrx-alchemy-meta", children: [
2669
2954
  buffer.length.toLocaleString(),
2670
2955
  " characters \xB7 ~",
2671
2956
  estimateTokens(buffer).toLocaleString(),
2672
2957
  " tokens"
2673
2958
  ] }),
2674
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", onClick: close, children: "Close" }),
2675
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", "aria-label": "Download prepared output", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(true), children: "Download" }),
2676
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", className: "matrx-alchemy-workspace-primary", "aria-label": "Copy prepared output", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(false), children: "Copy" })
2959
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", onClick: close, children: "Close" }),
2960
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", "aria-label": "Download prepared output", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(true), children: "Download" }),
2961
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { type: "button", className: "matrx-alchemy-workspace-primary", "aria-label": "Copy prepared output", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(false), children: "Copy" })
2677
2962
  ] })
2678
2963
  ] }) });
2679
2964
  }
@@ -2681,59 +2966,59 @@ function RowControls({ rows, controls, change }) {
2681
2966
  const filterCount = Object.values(controls.filters).filter(Boolean).length;
2682
2967
  const selectionSummary = controls.selectedOnly ? `${controls.selectedIndices.length} selected row${controls.selectedIndices.length === 1 ? "" : "s"}` : "All rows";
2683
2968
  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 ");
2684
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2685
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
2686
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2969
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2970
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
2971
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
2687
2972
  "Search",
2688
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { value: controls.search, onChange: (e) => change({ ...controls, search: e.target.value }) })
2973
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { value: controls.search, onChange: (e) => change({ ...controls, search: e.target.value }) })
2689
2974
  ] }),
2690
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2975
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
2691
2976
  "Sort",
2692
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { value: controls.sort, onChange: (e) => change({ ...controls, sort: e.target.value }), children: [
2693
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "None" }),
2694
- rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: column.id, children: column.label }, column.id))
2977
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("select", { value: controls.sort, onChange: (e) => change({ ...controls, sort: e.target.value }), children: [
2978
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "", children: "None" }),
2979
+ rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: column.id, children: column.label }, column.id))
2695
2980
  ] })
2696
2981
  ] }),
2697
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2982
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
2698
2983
  "Direction",
2699
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { value: controls.direction, disabled: !controls.sort, onChange: (e) => change({ ...controls, direction: e.target.value }), children: [
2700
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "asc", children: "Ascending" }),
2701
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "desc", children: "Descending" })
2984
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("select", { value: controls.direction, disabled: !controls.sort, onChange: (e) => change({ ...controls, direction: e.target.value }), children: [
2985
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "asc", children: "Ascending" }),
2986
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "desc", children: "Descending" })
2702
2987
  ] })
2703
2988
  ] }),
2704
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2989
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
2705
2990
  "Top rows",
2706
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "number", min: "0", value: controls.top ?? "", onChange: (e) => change({ ...controls, top: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
2991
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "number", min: "0", value: controls.top ?? "", onChange: (e) => change({ ...controls, top: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
2707
2992
  ] })
2708
2993
  ] }),
2709
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options", children: [
2710
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
2994
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("details", { className: "matrx-alchemy-options", children: [
2995
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { children: [
2711
2996
  "Columns and filters",
2712
2997
  dataSummary ? ` \u2014 ${dataSummary}` : ""
2713
2998
  ] }),
2714
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("fieldset", { "aria-label": "Columns and filters", children: rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-column", children: [
2715
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2716
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: controls.visibleColumns.includes(column.id), onChange: (e) => change({ ...controls, visibleColumns: e.target.checked ? [...controls.visibleColumns, column.id] : controls.visibleColumns.filter((id) => id !== column.id) }) }),
2999
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("fieldset", { "aria-label": "Columns and filters", children: rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-column", children: [
3000
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
3001
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "checkbox", checked: controls.visibleColumns.includes(column.id), onChange: (e) => change({ ...controls, visibleColumns: e.target.checked ? [...controls.visibleColumns, column.id] : controls.visibleColumns.filter((id) => id !== column.id) }) }),
2717
3002
  " ",
2718
3003
  column.label
2719
3004
  ] }),
2720
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { "aria-label": `Filter ${column.label}`, placeholder: "Filter", value: controls.filters[column.id] ?? "", onChange: (e) => change({ ...controls, filters: { ...controls.filters, [column.id]: e.target.value } }) })
3005
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { "aria-label": `Filter ${column.label}`, placeholder: "Filter", value: controls.filters[column.id] ?? "", onChange: (e) => change({ ...controls, filters: { ...controls.filters, [column.id]: e.target.value } }) })
2721
3006
  ] }, column.id)) })
2722
3007
  ] }),
2723
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options", children: [
2724
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
3008
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("details", { className: "matrx-alchemy-options", children: [
3009
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { children: [
2725
3010
  "Rows \u2014 ",
2726
3011
  selectionSummary
2727
3012
  ] }),
2728
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("fieldset", { "aria-label": "Row selection", children: [
2729
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2730
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: controls.selectedOnly, onChange: (e) => change({ ...controls, selectedOnly: e.target.checked }) }),
3013
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("fieldset", { "aria-label": "Row selection", children: [
3014
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
3015
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "checkbox", checked: controls.selectedOnly, onChange: (e) => change({ ...controls, selectedOnly: e.target.checked }) }),
2731
3016
  " Only selected rows"
2732
3017
  ] }),
2733
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "matrx-alchemy-row-list", children: rows.rows.map((row, index) => {
2734
- const summary = rows.columns.filter((column) => column.visible).slice(0, 2).map((column) => String((0, import_content_transfer2.readTransferCell)(row, column) ?? "")).filter(Boolean).join(" \xB7 ");
2735
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
2736
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: controls.selectedIndices.includes(index), onChange: (e) => change({ ...controls, selectedIndices: e.target.checked ? [...controls.selectedIndices, index] : controls.selectedIndices.filter((value) => value !== index) }) }),
3018
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "matrx-alchemy-row-list", children: rows.rows.map((row, index) => {
3019
+ const summary = rows.columns.filter((column) => column.visible).slice(0, 2).map((column) => String((0, import_content_transfer3.readTransferCell)(row, column) ?? "")).filter(Boolean).join(" \xB7 ");
3020
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
3021
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "checkbox", checked: controls.selectedIndices.includes(index), onChange: (e) => change({ ...controls, selectedIndices: e.target.checked ? [...controls.selectedIndices, index] : controls.selectedIndices.filter((value) => value !== index) }) }),
2737
3022
  " Row ",
2738
3023
  index + 1,
2739
3024
  summary ? ` \u2014 ${summary}` : ""